/**
 * field-system 核心类型定义
 *
 * 本模块定义了字段系统（field-system）的全部公共契约：
 *
 * 1. **FieldDriver<TConfig>** —— 每种字段类型必须实现的驱动接口，
 *    由 orchestrator 统一编排创建 → 校验 → 持久化 → 构建列定义 → 挂载视图 → 物化数据 的完整生命周期。
 *
 * 2. **FieldMeta / SelectorItem / FieldUiContribution** —— 驱动对外暴露的元数据与 UI 贡献，
 *    供 FieldSelector 渲染"添加字段"面板。
 *
 * 3. **FieldRecord** —— 统一的运行时字段记录，屏蔽了旧 aiConfig / formulaConfig 分桶差异。
 *
 * 4. **FieldContext** —— 贯穿整个字段生命周期的上下文，携带 dataModel、eventBus、services 等依赖。
 *
 * 设计约束：
 * - 所有类型均为纯数据接口，不依赖 React 运行时（仅 FieldPanelProps 引用 React.ComponentType）。
 * - FieldDriver 的泛型 TConfig 允许各驱动定义自己的配置结构，同时保持 orchestrator 的类型安全。
 */
import type React from 'react';
import type { CnAiListEventNamesMap } from '../../../../cn-ai-agent/constants/event-constants';
import type { LookupFieldCallbacks } from '../../../../cn-ai-table/types/lookup-field-table-config';
import type { LookupFieldCapability } from '../../../../cn-ai-table/view/utils/resolve-config';
/**
 * 字段运行时物化模式，决定字段数据的填充策略：
 * - 'sync-compute' : 同步计算（如公式字段，在前端立即求值）
 * - 'async-task'   : 异步任务（如 AI 字段，需提交远程 AI 任务后回填）
 * - 'passive'      : 无操作（如普通文本字段，用户手动输入）
 */
export type MaterializeMode = 'sync-compute' | 'async-task' | 'passive';
/**
 * 字段分类，用于"添加字段"选择器的分组展示。
 * 'custom' 保留给宿主/插件层扩展的自定义字段。
 */
export type FieldCategory = 'ai' | 'agent' | 'regular' | 'business' | 'custom';
/** 字段元信息 —— 由 driver.getMeta() 返回，描述字段的静态特征 */
export interface FieldMeta {
    /** 唯一字段类型标识，如 'ai-generate' / 'formula' / 'text' */
    type: string;
    /** 国际化后的显示名称 */
    label: string;
    /** 分类 */
    category: FieldCategory;
    /** 排序权重（越小越靠前） */
    order: number;
    /** 图标名称 */
    icon: string;
    /** 图标类型 */
    iconType?: 'ai' | 'agent' | 'regular' | 'business' | 'custom-iconfont' | 'reference-field';
    /** 图标颜色 */
    iconColor?: string;
    /** 物化模式，决定 FieldRuntime 的调度策略 */
    materializeMode: MaterializeMode;
}
/** 字段选择器展示项 */
export interface SelectorItem {
    type: string;
    label: string;
    icon: string;
    iconType?: FieldMeta['iconType'];
    color?: string;
    category: FieldCategory;
    order: number;
}
/**
 * 字段记录 —— 统一元数据。
 * 所有字段类型创建后都转为此结构，屏蔽旧 aiConfig / formulaConfig 分桶差异。
 * config 内部结构由各 FieldDriver<TConfig> 自行定义。
 */
export interface FieldRecord {
    id: string;
    type: string;
    name: string;
    config: Record<string, any>;
    runtime: {
        mode: MaterializeMode;
    };
}
/** UI 贡献 —— 配置面板 */
export interface FieldUiContribution {
    selectorItem: SelectorItem;
    createPanel?: React.ComponentType<FieldPanelProps>;
    editPanel?: React.ComponentType<FieldPanelProps>;
    /** 'none' 表示无配置面板（直接创建），'inline' 表示有内联配置面板 */
    panelKind?: 'none' | 'inline';
}
/** 配置面板 Props 通用定义 */
export interface FieldPanelProps {
    fieldType: string;
    fieldLabel: string;
    /** 编辑模式下传入已有列 ID */
    columnId?: string;
    /** 编辑模式下传入已有列 code */
    columnCode?: string;
    /** 编辑模式下传入已有表达式（公式） / prompt（AI） */
    initialValue?: string;
    /** 是否为编辑状态 */
    isEditStatus?: boolean;
    context: FieldContext;
    onSave: (config: Record<string, any>, extra?: Record<string, any>) => void;
    onCancel: () => void;
}
/**
 * AI 列服务 —— 桥接 useAiColumns hook 返回的方法。
 * 通过 FieldContext.services.aiColumn 注入，使 driver 不直接依赖 React hook。
 */
export interface AiColumnService {
    saveAiColumn: (params: {
        tableId: string;
        columnCode: string;
        columnName: string;
        scenarioId: string;
        promptTemplate: string;
        gatewayType: string;
        modelName: string;
    }) => Promise<boolean>;
    savingAiColumn: boolean;
    executingColumnTask: boolean;
}
/**
 * 字段上下文 —— 贯穿字段创建/编辑/删除的整个生命周期。
 *
 * 由调用方（如 NormalTableView）在触发字段操作前构建，
 * 将 dataModel、eventBus、外部服务等注入到 driver 和 orchestrator 中，
 * 使其不依赖全局状态。
 *
 * dataModel 类型暂为 any，后续应替换为 DataModel 接口。
 */
export interface FieldContext {
    dataModel: any;
    viewId: string;
    bizRequestConfig?: any;
    /** 引用字段能力配置（含 hiddenSubTable / callbacks；子表 URL 在 bizRequestConfig.subTableConfig） */
    lookupFieldConfig?: LookupFieldCapability;
    eventBus: {
        emit: (event: string, payload?: any) => void;
    };
    cnAiListEventNames: CnAiListEventNamesMap;
    services: {
        aiColumn?: AiColumnService;
        /** 引用字段创建/删除时的业务回调（来自 `fieldTypeOptions.lookup`）；编辑列元信息时不调用新增回调 */
        lookup?: LookupFieldCallbacks;
    };
}
/** 生命周期回调 */
export interface FieldLifecycleCallbacks {
    onSuccess?: () => void;
    onError?: (error: Error) => void;
}
/** 字段操作的统一返回类型 */
export type FieldActionResult = {
    success: true;
    record?: FieldRecord;
} | {
    success: false;
    error: Error;
};
/**
 * FieldDriver<TConfig> —— 字段驱动接口
 *
 * 每种字段类型实现此接口以接入 field-system。
 * orchestrator 通过此接口统一编排创建、编辑、删除流程。
 *
 * 典型生命周期（createField）：
 *   validateConfig → persistMeta → buildColumnDef → attachToView → materializeData
 *
 * 可选方法：
 * - updateMeta : 编辑场景下的持久化（缺省退化到 persistMeta）
 * - hydrate    : 从旧数据结构恢复 FieldRecord，支持向前兼容
 */
export interface FieldDriver<TConfig = any> {
    /** 返回字段的静态元信息，registry 据此完成注册和去重 */
    getMeta(): FieldMeta;
    /** 返回 UI 贡献（选择器条目 + 配置面板组件） */
    getUiContribution(): FieldUiContribution;
    /** 生成该字段类型的默认配置（用于新建场景预填） */
    createDefaultConfig(): TConfig;
    /** 校验配置合法性，返回 { valid, error } */
    validateConfig(config: TConfig): {
        valid: boolean;
        error?: string;
    };
    /**
     * 持久化元数据（AI 字段为异步远端写入，公式为同步本地写入，统一返回 Promise）。
     * 返回创建后的 FieldRecord。
     */
    persistMeta(config: TConfig, ctx: FieldContext): Promise<FieldRecord>;
    /** 构建列定义并 addColumn */
    buildColumnDef(record: FieldRecord, ctx: FieldContext): any;
    /** 挂载到视图（更新 columnOrder、写 rawData 空值等） */
    attachToView(record: FieldRecord, ctx: FieldContext): void;
    /** 物化数据（公式批量计算 / AI 批量提交任务 / 普通字段 noop） */
    materializeData(record: FieldRecord, config: TConfig, ctx: FieldContext): Promise<void>;
    /** 编辑字段时的持久化（可选，默认走 persistMeta） */
    updateMeta?(columnId: string, config: TConfig, ctx: FieldContext): Promise<FieldRecord>;
    /** 删除字段 */
    remove(columnId: string, ctx: FieldContext): Promise<void>;
    /** 从现有数据恢复 FieldRecord（用于兼容旧数据） */
    hydrate?(columnId: string, ctx: FieldContext): FieldRecord | undefined;
}
