#pragma once

#include <types/base/types.h>
#include <core/service.h>
#include <string>
#include <vector>
#include <functional>

namespace extra2d {

/**
 * @brief 文件信息
 */
struct FileInfo {
    std::string path;
    std::string name;
    bool isDir = false;
    int64 size = 0;
};

/**
 * @brief 文件读取结果
 */
struct FileData {
    bool ok = false;
    std::vector<uint8> data;
    std::string error;
    
    operator bool() const { return ok; }
    const uint8* ptr() const { return data.data(); }
    size_t size() const { return data.size(); }
};

/**
 * @brief 文件服务
 * 
 * 提供跨平台文件系统操作
 */
class FileSvc : public IService {
public:
    /**
     * @brief 获取单例实例
     */
    static FileSvc& inst();
    
    const char* name() const override { return "FileSvc"; }
    int pri() const override { return Pri::System; }
    
    bool init() override;
    void shutdown() override;
    
    /**
     * @brief 检查文件是否存在
     */
    bool exists(const std::string& path) const;
    
    /**
     * @brief 检查是否为目录
     */
    bool isDir(const std::string& path) const;
    
    /**
     * @brief 读取整个文件到内存
     */
    FileData read(const std::string& path) const;
    
    /**
     * @brief 读取文件为字符串
     */
    std::string readString(const std::string& path) const;
    
    /**
     * @brief 写入数据到文件
     */
    bool write(const std::string& path, const void* data, size_t size) const;
    
    /**
     * @brief 写入字符串到文件
     */
    bool writeString(const std::string& path, const std::string& content) const;
    
    /**
     * @brief 追加数据到文件
     */
    bool append(const std::string& path, const void* data, size_t size) const;
    
    /**
     * @brief 删除文件
     */
    bool remove(const std::string& path) const;
    
    /**
     * @brief 创建目录
     */
    bool mkdir(const std::string& path) const;
    
    /**
     * @brief 列出目录内容
     */
    std::vector<FileInfo> listDir(const std::string& path) const;
    
    /**
     * @brief 获取文件大小
     */
    int64 fileSize(const std::string& path) const;
    
    /**
     * @brief 获取文件扩展名
     */
    std::string ext(const std::string& path) const;
    
    /**
     * @brief 获取文件名（不含路径）
     */
    std::string fileName(const std::string& path) const;
    
    /**
     * @brief 获取文件所在目录
     */
    std::string dirName(const std::string& path) const;
    
    /**
     * @brief 连接路径
     */
    std::string join(const std::string& a, const std::string& b) const;
    
    /**
     * @brief 获取可写目录（用于存档等）
     */
    std::string writableDir() const;
    
    /**
     * @brief 设置资源根目录
     */
    void setAssetRoot(const std::string& root) { assetRoot_ = root; }
    
    /**
     * @brief 获取资源根目录
     */
    const std::string& assetRoot() const { return assetRoot_; }
    
    /**
     * @brief 获取资源完整路径
     */
    std::string assetPath(const std::string& relPath) const;
    
private:
    FileSvc() = default;
    
    std::string assetRoot_;
    std::string writableDir_;
};

#define FILE_SVC extra2d::FileSvc::inst()

} // namespace extra2d
