// ============================================================
// ICanvasDataSource — 数据源抽象接口
//
// 定义离线（本地文件系统）和在线（远程 API）模式的统一契约。
// 未来切换到在线协作时只需替换实现，上层代码无需修改。
//
// 设计原则：
//   1. Store 和 UI 组件不直接依赖 IPC 或 HTTP
//   2. 所有文件操作通过此接口调用
//   3. 测试时可用 Mock 实现替换
// ============================================================

// ---------- 扫描相关 ----------

/** 目录扫描请求参数 */
export interface ScanRequest {
    /** 扫描根目录列表（绝对路径，离线模式）或项目 ID 列表（在线模式） */
    roots: string[];
    /** 允许的文件扩展名（小写，不含点） */
    extensions: string[];
    /** 是否递归扫描子目录 */
    recursive: boolean;
}

/** 扫描进度回调 */
export type ScanProgressCallback = (progress: { found: number; currentPath: string }) => void;

/** 扫描结果条目（文件元信息） */
export interface ScanEntry {
    /** 文件绝对路径（离线模式）/ 文件 URI（在线模式） */
    path: string;
    /** 文件名（不含路径） */
    fileName: string;
    /** 扩展名（小写，不含点） */
    ext: string;
    /** 文件大小（字节） */
    fileSize: number;
    /** 修改时间 ISO 字符串 */
    modifiedAt: string;
}

// ---------- 侧加载元数据 ----------

/** 旁加载元数据 JSON（sidecar 文件） */
export interface SidecarMetadata {
    schema_version: number;
    favorite: boolean;
    remark: string;
    description: string;
    tags: string[];
    create_time: string;
    original_name: string;
    /** 审核状态（仅 Storyboard / Keyframe / Video 阶段有效） */
    audit_status?: 'pending' | 'approved' | 'rework' | 'deprecated';
}

/** 默认 sidecar 元数据 */
export function getDefaultSidecarMetadata(fileName: string): SidecarMetadata {
    return {
        schema_version: 1,
        favorite: false,
        remark: '',
        description: '',
        tags: [],
        create_time: new Date().toISOString().replace('T', ' ').slice(0, 19),
        original_name: fileName,
        audit_status: 'pending',
    };
}

// ---------- 缩略图 ----------

/** 缩略图请求参数 */
export interface ThumbnailRequest {
    /** 源文件绝对路径 */
    filePath: string;
    /** 目标尺寸（像素，按长边等比缩放） */
    size: 512 | 1024 | 2048 | 4096;
}

/** 缩略图生成结果 */
export interface ThumbnailResult {
    /** Base64 编码的图片数据 */
    data: string;
    /** MIME 类型（如 "image/jpeg"） */
    mimeType: string;
    /** 原始宽度 */
    width: number;
    /** 原始高度 */
    height: number;
}

// ---------- 数据源能力标志 ----------

/** 数据源能力标志 */
export interface DataSourceCapabilities {
    /** 是否支持离线操作 */
    offline: boolean;
    /** 是否支持实时协作（WebSocket 同步） */
    realtime: boolean;
    /** 是否支持服务器端缩略图生成 */
    thumbnails: boolean;
}

// ---------- 主接口 ----------

/**
 * 画布数据源接口
 *
 * 所有文件系统和 API 操作都通过此接口，确保：
 *   1. 上层 Store 和组件不直接依赖 IPC 或 HTTP
 *   2. 离线 / 在线模式可平滑切换
 *   3. 测试时可用 Mock 实现替换
 */
export interface ICanvasDataSource {
    /** 数据源能力标志（只读） */
    readonly capabilities: DataSourceCapabilities;

    /** 扫描目录，返回匹配文件列表 */
    scanDirectory(
        request: ScanRequest,
        onProgress?: ScanProgressCallback,
    ): Promise<ScanEntry[]>;

    /**
     * 扫描项目（推荐方式）。
     * 接收 projectPath + 筛选条件，主进程内部完成目录探索 + 文件遍历。
     * 渲染进程无需直接访问 fs 模块。
     */
    scanProject(params: {
        projectPath: string;
        stage: string;
        assetTypeFilter: string;
        shotQuery: string;
    }): Promise<ScanEntry[]>;

    /** 读取文件的旁加载元数据（sidecar JSON） */
    readSidecar(filePath: string): Promise<SidecarMetadata | null>;

    /** 写入文件的旁加载元数据 */
    writeSidecar(filePath: string, metadata: SidecarMetadata): Promise<void>;

    /** 生成缩略图（返回 base64 data URL） */
    generateThumbnail(request: ThumbnailRequest): Promise<ThumbnailResult>;

    /** 获取文件二进制数据（base64 编码） */
    readFileData(filePath: string): Promise<string | null>;

    /** 获取文件访问 URL（用于 <img> / <video> 的 src 属性） */
    getFileUrl(filePath: string): Promise<string>;

    /** 检查文件/目录是否存在 */
    fileExists(filePath: string): Promise<boolean>;

    /** 复制文件到目录（导入操作），返回目标路径 */
    copyFile(src: string, destDir: string, fileName: string): Promise<string>;

    /** 删除文件及其 sidecar */
    deleteFile(filePath: string): Promise<void>;

    /** 打开目录选择对话框，返回选中的路径 */
    openDirectoryDialog(): Promise<string | null>;

    /** 列出目录下的子文件夹名称（非递归，排除隐藏目录） */
    listSubdirs(parentPath: string): Promise<string[]>;

    /** 扫描指定镜头的阶段文件 */
    scanStageFiles(params: {
        projectPath: string;
        episode: string;
        shot: string;
        stage: string;
    }): Promise<ScanEntry[]>;

    /** 扫描资产文件（深度递归扫描 assets/ 目录） */
    scanAssetFiles(params: {
        projectPath: string;
        assetTypeFilter: string;
    }): Promise<ScanEntry[]>;

    /** 创建新目录，返回创建的完整路径 */
    createDirectory(parentPath: string, dirName: string): Promise<string>;
}
