// ============================================================
// API 响应通用类型
// ============================================================

/** 后端统一响应结构 */
export interface ApiResponse<T = unknown> {
    /** 业务状态码：0 表示成功 */
    code: number;
    /** 响应数据 */
    data: T;
    /** 提示信息 */
    message: string;
    /** 请求追踪 ID（可选，用于排查问题） */
    traceId?: string;
}

/** 分页请求参数 */
export interface PaginationParams {
    page: number;
    pageSize: number;
}

/** 分页响应数据 */
export interface PaginatedData<T> {
    /** 数据列表 */
    list: T[];
    /** 总条数 */
    total: number;
    /** 当前页码 */
    page: number;
    /** 每页条数 */
    pageSize: number;
}

/** 分页响应包装 */
export type PaginatedResponse<T> = ApiResponse<PaginatedData<T>>;

/** 请求错误类型 */
export enum RequestErrorType {
    /** 网络错误（断网等） */
    NETWORK = 'NETWORK',
    /** 请求超时 */
    TIMEOUT = 'TIMEOUT',
    /** HTTP 状态码异常（4xx / 5xx） */
    HTTP = 'HTTP',
    /** 业务错误（code ≠ 0） */
    BUSINESS = 'BUSINESS',
    /** 请求被取消 */
    CANCELLED = 'CANCELLED',
    /** 认证过期（refresh_token 失效，需重新登录） */
    AUTH_EXPIRED = 'AUTH_EXPIRED',
}

/** 请求错误 */
export class RequestError extends Error {
    type: RequestErrorType;
    code?: number;
    httpStatus?: number;
    traceId?: string;
    /**
     * 标记该错误是否已通过事件总线 → Modal 展示给用户。
     * 调用方（如 useAsyncMutation / 表单提交）读取此标记，
     * 若为 true 则跳过 message.error 等重复提示。
     */
    displayed = false;

    constructor(
        type: RequestErrorType,
        message: string,
        options?: { code?: number; httpStatus?: number; traceId?: string },
    ) {
        super(message);
        this.name = 'RequestError';
        this.type = type;
        this.code = options?.code;
        this.httpStatus = options?.httpStatus;
        this.traceId = options?.traceId;
    }
}

// ---------- 自定义错误子类（全局统一捕获 → 事件总线触发）----------

/**
 * RefreshError — refresh_token 过期/无效，需重新登录。
 * 全局响应拦截器自动捕获此错误并 emit AUTH_REQUIRED，调用方无需手动处理。
 *
 * 用法：throw new RefreshError('登录已过期，请重新登录');
 */
export class RefreshError extends RequestError {
    constructor(message = '登录已过期，请重新登录') {
        super(RequestErrorType.AUTH_EXPIRED, message);
        this.name = 'RefreshError';
    }
}

/** 判断一个错误是否为 RefreshError（支持 instanceof 或 type 判断） */
export function isRefreshError(err: unknown): err is RefreshError {
    return err instanceof RefreshError || (err as RequestError)?.type === RequestErrorType.AUTH_EXPIRED;
}
