/**
 * upload 模块类型定义
 *
 * @description
 * 将所有类型定义集中到一个文件，便于维护和理解
 * 遵循 KISS 原则：简单、直接、零废话
 */
import { useToast } from '../ui';
/**
 * upload 模块的 toast 函数类型
 *
 * @description
 * 允许业务侧注入自定义 toast，实现“业务统一 UI 风格”。
 */
export type UploadToast = typeof useToast;
/**
 * 上传/选择文件类型
 */
export type UploadFileType = 'image' | 'file' | 'any';
/**
 * 单个文件的统一描述结构
 *
 * @description
 * 将各平台返回值规整成统一的 UniFile，方便业务使用
 */
export interface UniFile {
    /** 文件唯一标识（由本工具生成） */
    id: string;
    /** 文件名 */
    name: string;
    /** 文件大小（字节） */
    size: number;
    /** 本地临时路径 / H5 对象 URL */
    path: string;
    /** MIME 类型（如果可用） */
    mimeType?: string;
    /** 文件扩展名（不带点，例如：jpg、png） */
    ext?: string;
    /** 文件来源（相册、相机、本地文件等） */
    source?: 'camera' | 'album' | 'file' | 'chat' | 'unknown';
    /** 运行平台（仅作标记使用） */
    platform?: 'weixin' | 'alipay' | 'h5' | 'app' | 'unknown';
    /** 平台原始返回对象，保留以备高级用法 */
    raw?: unknown;
}
/**
 * 上传选项（v5 扁平结构）
 *
 * @description
 * v5 目标：只保留一套配置结构，移除 compat 层与多层嵌套，让用户只关心“要什么能力”。
 *
 * 设计原则：
 * 1) 一层参数：避免 `config.file.xxx` 这类无意义的分组
 * 2) 大多数用户只需要：选择 → 校验 → 上传 → 返回结果
 * 3) 真正特殊逻辑放到 `beforeUpload`/`onProgress`/`toast` 注入里解决
 */
export interface UploadOptions {
    /** 上传地址（必填） */
    url: string;
    /**
     * 直接上传已有文件（跳过选择阶段）
     *
     * @description
     * 用于业务侧已拿到文件对象/路径的场景（例如二次上传、批量重试）。
     */
    files?: UniFile[];
    /** 文件类型，默认 image */
    type?: UploadFileType;
    /** 最大选择数量，默认 1 */
    count?: number;
    /**
     * 文件体积限制（MB）
     *
     * @description
     * v5 统一为一个限制：
     * - 选择后立即校验（避免选完才发现不合规）
     * - 传入 `files` 时同样会校验
     *
     * 语义：
     * - `undefined/null`：不限制
     * - `0`：不允许选择/上传任何文件
     */
    maxSizeMB?: number;
    /**
     * 允许的扩展名白名单（严格模式）
     *
     * @example ['jpg', 'png']
     */
    extensions?: string[];
    /** 表单字段名，默认 file */
    fieldName?: string;
    /** 额外的表单数据 */
    formData?: Record<string, unknown>;
    /** 请求头 */
    headers?: Record<string, string>;
    /** 上传超时时间 (ms) */
    timeoutMs?: number;
    /** [H5] 是否自动释放对象 URL */
    autoRevokeObjectURL?: boolean;
    /** 并发上传数量；不传则默认全并发（等于文件数） */
    concurrency?: number;
    /** 取消信号 */
    signal?: AbortSignal;
    /** 上传前拦截钩子：返回 false 则跳过该文件 */
    beforeUpload?: (file: UniFile) => boolean | Promise<boolean>;
    /** 进度回调（单文件进度百分比 0~100） */
    onProgress?: (file: UniFile, progress: number) => void;
    /** 是否显示 Toast，默认 true */
    showToast?: boolean;
    /** 成功提示文本（仅单文件且全成功时） */
    successMessage?: string;
    /** 失败提示文本（保留字段：目前主要用于自定义失败提示策略） */
    failMessage?: string;
    /** 是否显示进度 Toast（内部使用 `uni.showLoading`） */
    showProgressToast?: boolean;
    /** 自定义进度 Toast 格式化函数 */
    progressToastFormatter?: (file: UniFile, progress: number, currentIndex?: number, totalCount?: number) => string;
    /** 注入自定义 toast 函数 */
    toast?: UploadToast;
}
/**
 * 单个文件的上传结果
 */
export interface UploadResult {
    /** 对应的文件，选择阶段失败时为 null */
    file: UniFile | null;
    /** 是否上传成功 */
    success: boolean;
    /** HTTP 状态码（如果有） */
    statusCode?: number;
    /** 服务器返回的数据（成功或失败时的响应体） */
    data?: unknown;
    /** 提示信息 */
    message?: string;
}
/**
 * 文件选择结果（内部）
 */
export interface FileSelection {
    success: boolean;
    files: UniFile[];
    message?: string;
}
