import type { ClassToken } from '../ioc/metadata';
/** 快速 CRUD 接口名（含回收站） */
export type CrudApi = 'add' | 'delete' | 'update' | 'info' | 'list' | 'page' | 'restore'
/** 声明业务数据多语言（非 HTTP 接口；与 restore 一样写在 api 里） */
 | 'dataI18n';
/**
 * 字段引用（fieldEq / fieldLike / fieldArray / keyWordLikeFields）。
 * - 裸名 `status` → `a.status`，请求参数名 = `status`
 * - `b.providerId` → 参数名 = `providerId`
 * - `e.id as roleId` → 筛 `e.id`，参数名 = `roleId`（短名冲突用 as，不用 requestParam）
 */
export type QueryFieldRef = string | {
    /** 如 `status` / `b.providerId` / `e.id as roleId` */
    column: string;
    /** 筛选项展示名；缺省用实体 columnComments / EPS comment */
    label?: string;
    /** 业务字典 type.key；筛选项用其拉 options */
    dict?: string;
    /** 有 dict 时默认 true（下拉多选）；false 为单选 */
    multiple?: boolean;
    /** true：后端仍按本字段筛选，admin 不自动构建筛控件 */
    none?: boolean;
};
/** 区间筛选精度 / 数字类型（告诉 admin 用什么控件） */
export type FieldRangeType = 'int' | 'float' | 'year' | 'month' | 'day' | 'datetime';
/** 价格 / 时间等区间；min/max 为请求体参数名 */
export type QueryFieldRange = {
    column: string;
    min: string;
    max: string;
    type: FieldRangeType;
    /** 覆盖实体注释，用于搜索 label / placeholder 前缀 */
    label?: string;
    /** true：后端支持区间，admin 不自动出控件 */
    none?: boolean;
};
/** join 类型 */
export type QueryJoinType = 'join' | 'leftJoin' | 'innerJoin';
/**
 * Join 配置（Drizzle pgTable）。
 * - 主表固定别名 `a`
 * - 联表必须显式：`entity` + `alias` + `type` + `condition`
 */
export type QueryJoin = {
    /** Drizzle pgTable */
    entity: unknown;
    /** 联表别名，如 b / c / f；不可为 a */
    alias: string;
    type: QueryJoinType;
    /** 等值条件，如 `a.skinId = b.id` */
    condition: string;
};
/** where / extend 上下文 */
export type QueryOpCtx = {
    body: Record<string, unknown>;
    request: Request;
};
/** where 返回：单条 SQL，或列表（undefined/false/null 自动丢弃） */
export type QueryWhereResult = unknown | Array<unknown | undefined | false | null>;
export type QueryWhereFn = (ctx: QueryOpCtx) => QueryWhereResult | Promise<QueryWhereResult>;
/** extend 可改的查询句柄 */
export type QueryExtendQb = {
    andWhere: (condition: unknown) => void;
    orderBy: (...orders: unknown[]) => void;
};
export type QueryExtendFn = (qb: QueryExtendQb, ctx: QueryOpCtx) => void | Promise<void>;
/** page / list 查询配置 */
export type QueryOp = {
    keyWordLikeFields?: string[];
    fieldEq?: QueryFieldRef[];
    fieldLike?: QueryFieldRef[];
    /** PG 数组列包含查询（body 单值或数组）；admin 筛选用输入框 */
    fieldArray?: QueryFieldRef[];
    /** 数字 / 时间区间（与 fieldEq 等并存，勿再在 where 里拆参） */
    fieldRange?: QueryFieldRange[];
    addOrderBy?: Record<string, 'asc' | 'desc'>;
    /**
     * 声明式投影（有 join 时建议显式配置）。
     * - `a.*`：主表全部列，结果键 = 驼峰字段名
     * - `b.userName`：结果键 = `userName`（无需 as）
     * - `e.name as roleName`：结果键 = `roleName`
     */
    select?: string[];
    join?: QueryJoin[];
    where?: QueryWhereFn;
    extend?: QueryExtendFn;
};
export type InsertParamFn = (ctx: {
    body?: unknown;
    request?: Request;
}) => Record<string, unknown> | Promise<Record<string, unknown>>;
/** 写操作前钩子（add / update / delete / restore） */
export type CrudBeforeFn = (ctx: {
    body: Record<string, unknown>;
    request: Request;
    api: string;
}) => void | Promise<void>;
/** 控制器 / 路由中间件（Elysia onBeforeHandle） */
export type RouteMiddleware = (ctx: Record<string, unknown>) => unknown | Promise<unknown>;
export type DataI18nRefDecl = {
    sourceTable: string;
    joinField: string;
    sourceJoinField?: string;
    sourceField?: string;
    sourcePkField?: string;
};
/**
 * 参考字段种子（翻译时直接用同行另一列，不调 AI）
 * @example { skinName: 'marketHashName', language: 'en' }  // en / en-US 均命中
 */
export type DataI18nSeedItem = {
    /** 适用语种：`en` 匹配 `en`、`en-US`、`en-GB` */
    language: string;
    /** 目标字段 → 参考列，如 skinName: 'marketHashName' */
    [fieldName: string]: string;
};
/**
 * @Controller 快速 CRUD 选项（Drizzle 适配）
 */
export type ControllerCrudOptions = {
    api?: CrudApi[];
    /** Drizzle pgTable，宿主挂载 Repository */
    entity?: unknown;
    /** 业务 Service 类（须 @Provide，建议 extends BaseService） */
    service?: ClassToken;
    /** 把 Service 方法挂成 POST /methodName */
    serviceApis?: string[];
    /** 写操作前改 body（add/update/delete/restore） */
    before?: CrudBeforeFn;
    pageQueryOp?: QueryOp;
    listQueryOp?: QueryOp;
    insertParam?: InsertParamFn;
    infoIgnoreProperty?: string[];
    /**
     * api 含 dataI18n 时：本表 direct 翻译字段；缺省推断 varchar/text 列
     */
    dataI18nFields?: string[];
    /**
     * api 含 dataI18n 时：冗余列走源表 pack（源表也须声明 dataI18n）
     * @example skinName: { sourceTable: 'game_skin', joinField: 'steamId' }
     */
    dataI18nRef?: Record<string, DataI18nRefDecl>;
    /**
     * 翻译种子：单条或数组。`language: 'en'` 时可用同行 `marketHashName` 作为 `skinName` 译文。
     * @example [{ skinName: 'marketHashName', language: 'en' }]
     */
    dataI18nSeed?: DataI18nSeedItem | DataI18nSeedItem[];
    /**
     * 导入 upsert 唯一键（字段名数组）。
     * 未配置时自动取实体 uniqueIndex / unique 约束。
     */
    importUniqueKeys?: string[];
};
