// ============================================================
// 任务模块 — 任务记录 CRUD API
// GET    /api/v1/tasks              → 任务列表（分页/游标）
// POST   /api/v1/tasks              → 提交任务
// GET    /api/v1/tasks/:id          → 任务详情
// GET    /api/v1/tasks/:id/status   → 轻量轮询状态
// GET    /api/v1/tasks/export       → 导出 CSV
//
// TaskAPI 的静态方法直接返回 get/post 的 Promise<T>，
// 不做额外的 async/await 包装，由调用方决定是否 await。
// ============================================================

import {get, post} from '@/shared/services/http';
import {getDeviceId} from '@/shared/utils/env';
import {Nullable} from "@/shared/utils/display";

// ============================================================
// 基础枚举 / 字面量类型
// ============================================================

/** 输出类型映射 */
export enum OutputTypeMap {
    image = '图片',
    video = '视频',
    audio = '音频',
}

export type OutputTypeString = keyof typeof OutputTypeMap;

/** 任务状态 */
export enum TaskStatusMap {
    pending = '待处理',
    submitted = '已提交',
    processing = '处理中',
    success = '成功',
    failed = '失败',
}

export type TaskStatusString = keyof typeof TaskStatusMap;

/** 需要持续轮询的非终态状态 */
export const POLLING_STATUSES: TaskStatusString[] = ['pending', 'submitted', 'processing'];

// ============================================================
// 请求体 / 参数类型
// ============================================================

/** 任务列表请求参数 */
export interface TaskListRequestParams {
    status?: TaskStatusString;
    user_ids?: string[];
    model_ids?: string[];
    /** 游标分页：上次最后一条的 created_at（ISO 8601） */
    cursor?: string;
    /** 页码（OFFSET 分页模式），default: 1 */
    page?: number;
    /** 每页条数，default: 20 */
    page_size?: number;
}

/** 创建任务请求体 */
export interface CreatTaskRequestBody {
    model_id: string;
    params: Record<string, string>;
    device_id: string;
    tags?: string[];
}

/**
 * 批量任务轮询查询参数
 */
export interface BatchTaskStatusRequestParam {
    task_ids: string[];
}

/**
 * 批量任务状态轮询响应头
 */
export interface BatchTaskStatusResponseBody {
    items: Nullable<TaskStatusResponseBody>[],
    balance_cent: number,
    next_poll_ms: number;
}


/** 导出 CSV 参数 */
export interface ExportTaskCSVParams {
    start_date: Date;
    end_date: Date;
    status?: TaskStatusString;
    user_ids?: string[];
    model_ids?: string[];
}

// ============================================================
// 内容项 — 带判别标签的联合类型
// ============================================================

interface BaseContentItem {
    type: string;
}

interface TextContent extends BaseContentItem {
    type: 'text';
    text: string;
}

interface ImageUrlContent extends BaseContentItem {
    type: 'image_url';
    role: 'reference_image';
    image_url: { url: string };
}

interface VideoUrlContent extends BaseContentItem {
    type: 'video_url';
    role: 'reference_video';
    video_url: { url: string };
}

interface AudioContent extends BaseContentItem {
    type: 'audio_url';
    role: 'reference_audio';
    audio_url: { url: string };
}

export type ContentItem =
    | TextContent
    | ImageUrlContent
    | VideoUrlContent
    | AudioContent;

// ============================================================
// 各输出类型的 UI 参数
// ============================================================

export interface ImageUiParams {
    imageUrls?: string[];
    prompt: string;
    aspectRatio: string;
    resolution?: string;
}

export interface VideoUiParams {
    resolution?: string;
    ratio?: string;
    model?: string;
    generate_audio: boolean;
    duration: number;
    content: ContentItem[];
}

export interface AudioUiParams {
    format?: string;
    sampleRate?: number;
    bitrate?: number;
}

// ============================================================
// 响应体 — 用判别联合按 output_type 分发
// ============================================================

/** 任务条目基类（不含 output_type 特有字段） */
interface BaseTaskItemResponseBody {
    id: string;
    user_id: string;
    model_id: string;
    model_name: string;
    provider_name: string;
    status: TaskStatusString;
    external_task_id: string;
    cost_cent: number;
    estimated_cost_cent: number;
    error_code: string;
    poll_attempts: number;
    is_favorite: boolean;
    submitted_at: Date;
    finished_at: Date;
    created_at: Date;
    updated_at: Date;
    prompt?: string;
    output_assets?: Array<{ url: string }>;
    tags: Array<string | null>;
    error_message: string;
    user_display_name: string | null;
}

/** 判别联合：根据 output_type 收窄 ui_params */
export type TaskInfoItemResponseBody =
    | (BaseTaskItemResponseBody & { output_type: 'image'; ui_params: ImageUiParams })
    | (BaseTaskItemResponseBody & { output_type: 'video'; ui_params: VideoUiParams })
    | (BaseTaskItemResponseBody & { output_type: 'audio'; ui_params: AudioUiParams });

/** 任务列表分页响应 */
export interface TaskInfoDataResponseBody {
    has_more: boolean;
    next_cursor: string;
    page: number;
    page_size: number;
    total: number;
    items: TaskInfoItemResponseBody[];
}

/** 轻量轮询状态响应 */
export interface TaskStatusResponseBody {
    task_id: string;
    status: TaskStatusString;
    progress?: number;
    output_assets?: string[];
    error_code?: string;
    error_message?: string;
    cost_cent?: number;
    queue_position: number,
    submitted_at: Date,
    finished_at: Date,
    external_task_id: string,
    refund_cent: number,
    refunded_at: Date,
    refund_reason: string,
    next_poll_ms: number
}

// ============================================================
// 路由常量
// ============================================================

const TaskUrlObj = {
    task: '/api/v1/tasks',
    taskInfo: (task_id: string) => `/api/v1/tasks/${task_id}`,
    taskStatus: (task_id: string) => `/api/v1/tasks/${task_id}/status`,
    tasksCSV: '/api/v1/tasks/export',
    batchTaskStatus: "/api/v1/tasks/status/batch"
} as const;

// ============================================================
// TaskAPI — 静态方法直接返回 Promise<T>，不做二次 async 包装
// ============================================================

export class TaskAPI {
    /** 获取任务列表（分页/游标） */
    static getTaskList(params: TaskListRequestParams, signal?: AbortSignal): Promise<TaskInfoDataResponseBody> {
        return get<TaskInfoDataResponseBody>(TaskUrlObj.task, params as Record<string, unknown>, {signal});
    }

    /** 提交新任务（device_id 由 API 层自动注入 getDeviceId()，调用方无需传入） */
    static submitTask(body: Omit<CreatTaskRequestBody, 'device_id'>): Promise<TaskInfoItemResponseBody> {
        return post<TaskInfoItemResponseBody>(TaskUrlObj.task, {
            ...body,
            device_id: getDeviceId(),
        });
    }

    /** 获取任务详情 */
    static getTaskInfo(task_id: string, signal?: AbortSignal): Promise<TaskInfoItemResponseBody> {
        return get<TaskInfoItemResponseBody>(TaskUrlObj.taskInfo(task_id), undefined, {signal});
    }

    /** 轻量轮询任务状态 */
    static getTaskStatus(task_id: string): Promise<TaskStatusResponseBody> {
        return get<TaskStatusResponseBody>(TaskUrlObj.taskStatus(task_id));
    }

    /** 批量查询任务状态 — GET + 逗号拼接 task_ids（避免 axios 默认 bracket 序列化 task_ids[]=...） */
    static batchTaskStatus(body: BatchTaskStatusRequestParam): Promise<BatchTaskStatusResponseBody> {
        return post<BatchTaskStatusResponseBody>(TaskUrlObj.batchTaskStatus, body);
    }

    /** 导出任务 CSV */
    static exportTaskCSV(params: ExportTaskCSVParams): Promise<File> {
        return get<File>(TaskUrlObj.tasksCSV, params as unknown as Record<string, unknown>);
    }
}
