/**
 * AiFieldDriver —— AI 字段驱动
 *
 * 迁移自：
 * - add-field-button.tsx 中 handleAiConfigSave
 * - use-field-creation.tsx 中 AI 分支
 * - columnHeaderMenuUtils.ts 中 handleEditAiColumn / AI 删除分支
 *
 * 设计要点：
 * 1. 每种 AI 子类型（ai-generate / format-convert / ...）及 Agent 子类型
 *    共用此 driver 类，通过构造函数 options 区分元信息和图标。
 * 2. persistMeta 调用 AiColumnService 远程保存，属于异步持久化。
 * 3. materializeData 根据 saveMode 决定是否立即提交批量 AI 任务。
 * 4. remove 需先远程删除 AI 列，再清理本地 dataModel（columnDefinitions、viewConfigs 等）。
 * 5. updateMeta 在编辑场景下同时更新远程、columnDefinitions 和旧分桶 aiConfig。
 */
import $i18n from '../../../../locales/i18n.js';
import React from 'react';
import { CnMessage } from '@cainiaofe/cn-ui';
import { removeAiColumn } from '../../../../cn-ai-table/view/services';
import { AI_GENERATING_MARKER } from '../../../../cn-ai-table/view/constants/ai-cell-constants';
import { AGENT_ID } from '../../../../cn-ai-table/view/hooks/constants';
import { AI_FIELD_ICON_URL, AGENT_FIELD_ICON_URL, } from '../../components/toolbar/components/add-field/constants';
import { parsePromptVariables, buildPromptParamsWithExtractor, } from '../../components/toolbar/components/add-field/utils/prompt-utils';
import { isAgentField } from '../../components/toolbar/components/add-field/utils/field-utils';
import { getTargetRows, shouldExecuteAiTask, } from '../../components/toolbar/components/add-field/utils/ai-task-utils';
import { AiFieldPanelAdapter } from './panels/ai-field-panel-adapter';
export class AiFieldDriver {
    constructor(options) {
        this.options = options;
    }
    getMeta() {
        return {
            type: this.options.type,
            label: this.options.label,
            category: this.options.category,
            order: this.options.order,
            icon: this.options.icon,
            iconType: this.options.iconType,
            iconColor: this.options.iconColor,
            materializeMode: 'async-task',
        };
    }
    getUiContribution() {
        const meta = this.getMeta();
        return {
            selectorItem: {
                type: meta.type,
                label: meta.label,
                icon: meta.icon,
                iconType: meta.iconType,
                color: meta.iconColor,
                category: meta.category,
                order: meta.order,
            },
            createPanel: AiFieldPanelAdapter,
            editPanel: AiFieldPanelAdapter,
            panelKind: 'inline',
        };
    }
    createDefaultConfig() {
        return {
            fieldName: '',
            aiTaskType: this.options.type,
            targetInfo: '',
            content: '',
            model: 'qwen-max',
            autoUpdate: false,
            allowEmptyField: false,
            saveMode: 'config-only',
        };
    }
    validateConfig(config) {
        var _a, _b;
        if (!((_a = config.fieldName) === null || _a === void 0 ? void 0 : _a.trim())) {
            return {
                valid: false,
                error: $i18n.get({ id: 'PleaseEnterAFieldName', dm: '请输入字段名称' }),
            };
        }
        if (!((_b = config.targetInfo) === null || _b === void 0 ? void 0 : _b.trim())) {
            return {
                valid: false,
                error: $i18n.get({ id: 'PleaseEnterThePromptContent', dm: '请输入提示词内容' }),
            };
        }
        return { valid: true };
    }
    /**
     * 远程持久化 AI 字段元数据。
     * 调用 AiColumnService.saveAiColumn 写入服务端，再通过 addAiColumnToView 关联到视图。
     */
    async persistMeta(config, ctx) {
        const columnCode = config.columnCode || `ai_column_${Date.now()}`;
        const aiColumnService = ctx.services.aiColumn;
        if (!aiColumnService) {
            throw new Error('[AiFieldDriver] aiColumn service not available in context');
        }
        const saved = await aiColumnService.saveAiColumn({
            tableId: ctx.dataModel.tableId,
            columnCode,
            columnName: config.fieldName,
            scenarioId: AGENT_ID,
            promptTemplate: config.targetInfo,
            gatewayType: 'caibao',
            modelName: config.model || 'qwen-max',
        });
        console.log('saved', saved);
        if (!saved) {
            throw new Error($i18n.get({ id: 'FailedToSaveAIField', dm: '保存AI字段失败' }));
        }
        ctx.dataModel.addAiColumnToView(ctx.viewId, columnCode, true);
        return {
            id: columnCode,
            type: this.options.type,
            name: config.fieldName,
            config: { ...config, columnCode },
            runtime: { mode: 'async-task' },
        };
    }
    /**
     * 构建列定义并通过 dataModel.addColumn 注册。
     * 同时将 aiConfig 双写到旧分桶，保持向后兼容。
     */
    buildColumnDef(record, ctx) {
        const isAgent = isAgentField(record.type);
        const iconUrl = isAgent ? AGENT_FIELD_ICON_URL : AI_FIELD_ICON_URL;
        const altText = isAgent
            ? $i18n.get({ id: 'AgentField', dm: 'Agent字段' })
            : $i18n.get({ id: 'AIField', dm: 'AI字段' });
        const headerContent = React.createElement('span', { style: { display: 'flex', alignItems: 'center', gap: '6px' } }, React.createElement('img', {
            src: iconUrl,
            alt: altText,
            style: { width: '16px', height: '16px' },
        }), record.name);
        const colDef = {
            dataIndex: record.id,
            title: record.name,
            header: headerContent,
            accessorKey: record.id,
            isAiColumn: true,
            format: 'ai-generate',
            aiConfig: record.config,
        };
        ctx.dataModel.addColumn(colDef);
        ctx.dataModel.setCustomFieldAiConfig(record.id, {
            fieldName: record.config.fieldName,
            aiTaskType: record.config.aiTaskType,
            targetInfo: record.config.targetInfo,
            content: record.config.content,
            model: record.config.model,
            autoUpdate: record.config.autoUpdate,
            allowEmptyField: record.config.allowEmptyField,
            fieldDescription: record.config.fieldDescription,
            columnCode: record.id,
            fieldType: record.type,
        });
        return colDef;
    }
    /** 将新列挂载到当前视图：追加到 columnOrder，并为每行 rawData 填充空值 */
    attachToView(record, ctx) {
        const viewConfig = ctx.dataModel.getViewConfig(ctx.viewId);
        const currentColumnOrder = viewConfig.columnOrder || [];
        const nextColumnOrder = currentColumnOrder.includes(record.id)
            ? currentColumnOrder
            : [...currentColumnOrder, record.id];
        ctx.dataModel.setViewConfig(ctx.viewId, { columnOrder: nextColumnOrder }, true);
        const newData = ctx.dataModel.rawData.map((row) => ({
            ...row,
            [record.id]: '',
        }));
        ctx.dataModel.setRawData(newData);
    }
    /**
     * 物化 AI 字段数据：根据 saveMode 决定是否立即为目标行提交批量 AI 任务。
     * 'config-only' 模式下不执行任务（仅保存配置），其余模式提取 prompt 变量后批量提交。
     * 提交前会在每行对应单元格写入 AI_GENERATING_MARKER 以显示 loading 状态。
     */
    async materializeData(record, config, ctx) {
        const mode = config.saveMode || 'config-only';
        if (!shouldExecuteAiTask(mode))
            return;
        const targetRows = getTargetRows({
            mode,
            dataModel: ctx.dataModel,
            viewId: ctx.viewId,
        });
        if (targetRows.length === 0) {
            CnMessage.warning($i18n.get({ id: 'NoDataRowsToGenerate', dm: '没有可生成的数据行' }));
            return;
        }
        const columnCode = record.id;
        const variables = parsePromptVariables(config.targetInfo);
        const allColumns = ctx.dataModel.columnDefinitions || [];
        const processedColumnMap = ctx.dataModel.processedColumnMap || new Map();
        const taskRequests = [];
        let skippedCount = 0;
        targetRows.forEach((row, rowIndex) => {
            const rowKey = ctx.dataModel.getRowKeyStrict(row);
            if (rowKey == null) {
                skippedCount += 1;
                return;
            }
            const rowId = String(rowKey);
            taskRequests.push({
                columnCode,
                rowId,
                promptParams: buildPromptParamsWithExtractor(row, variables, allColumns, processedColumnMap, rowIndex),
            });
            ctx.dataModel.setAiCellData(rowKey, columnCode, AI_GENERATING_MARKER);
        });
        // if (process.env.NODE_ENV !== 'production' && skippedCount > 0) {
        //   // eslint-disable-next-line no-console
        //   console.warn(
        //     `[cn-ai-table] AiFieldDriver.materializeData: ${skippedCount} row(s) skipped because primaryKey value is missing.`,
        //   );
        // }
        ctx.eventBus.emit(ctx.cnAiListEventNames.SUBMIT_BATCH_AI_TASKS, {
            columnCode,
            taskRequests,
        });
    }
    /**
     * 删除 AI 列：先调用远程接口 removeAiColumn，再清理本地 dataModel。
     * 本地清理包括：columnDefinitions、customField 分桶、各视图的 columnOrder / hiddenColumns / filter / sort / group / colorFill。
     */
    async remove(columnId, ctx) {
        var _a, _b, _c, _d, _e;
        const { tableId } = ctx.dataModel;
        if (!tableId) {
            throw new Error($i18n.get({
                id: 'TableIdDoesNotExistCannotDeleteA_1884224232',
                dm: 'tableId 不存在，无法删除 AI 列',
            }));
        }
        const result = await removeAiColumn({ tableId, columnCode: columnId }, (_a = ctx.dataModel) === null || _a === void 0 ? void 0 : _a.bizRequestConfig, {
            userCubeConfigRowIdHint: ctx.dataModel.cubePlatformUserConfigRowId,
            onUserCubeConfigRowId: (id) => ctx.dataModel.setCubePlatformUserConfigRowId(id),
        });
        if (!(result === null || result === void 0 ? void 0 : result.success)) {
            throw new Error((result === null || result === void 0 ? void 0 : result.errorMsg) ||
                (result === null || result === void 0 ? void 0 : result.msg) ||
                $i18n.get({ id: 'FailedToDeleteAIColumn', dm: '删除 AI 列失败' }));
        }
        const currentAiColumns = ((_c = (_b = ctx.dataModel).getAiColumns) === null || _c === void 0 ? void 0 : _c.call(_b)) || ctx.dataModel.aiColumns || [];
        const newAiColumns = currentAiColumns.filter((col) => col.columnCode !== columnId);
        (_e = (_d = ctx.dataModel).setAiColumns) === null || _e === void 0 ? void 0 : _e.call(_d, newAiColumns);
        this.removeFieldFromDataModel(columnId, ctx);
    }
    /**
     * 编辑场景下更新 AI 字段元数据。
     * 同步更新三处：远程服务端 → columnDefinitions（列标题 + aiConfig）→ 旧分桶 customFieldAiConfig。
     * 最后调用 updateRemoteViews 同步视图配置到服务端。
     */
    async updateMeta(columnId, config, ctx) {
        const aiColumnService = ctx.services.aiColumn;
        if (!aiColumnService) {
            throw new Error('[AiFieldDriver] aiColumn service not available in context');
        }
        const saved = await aiColumnService.saveAiColumn({
            tableId: ctx.dataModel.tableId,
            columnCode: columnId,
            columnName: config.fieldName,
            scenarioId: AGENT_ID,
            promptTemplate: config.targetInfo,
            gatewayType: 'caibao',
            modelName: config.model || 'qwen-max',
        });
        if (!saved) {
            throw new Error($i18n.get({ id: 'FailedToSaveAIField', dm: '保存AI字段失败' }));
        }
        const isAgent = isAgentField(this.options.type);
        const iconUrl = isAgent ? AGENT_FIELD_ICON_URL : AI_FIELD_ICON_URL;
        const altText = isAgent
            ? $i18n.get({ id: 'AgentField', dm: 'Agent字段' })
            : $i18n.get({ id: 'AIField', dm: 'AI字段' });
        const headerContent = React.createElement('span', { style: { display: 'flex', alignItems: 'center', gap: '6px' } }, React.createElement('img', {
            src: iconUrl,
            alt: altText,
            style: { width: '16px', height: '16px' },
        }), config.fieldName);
        const colDefs = ctx.dataModel.columnDefinitions || [];
        const colIdx = colDefs.findIndex((c) => c.dataIndex === columnId);
        if (colIdx >= 0) {
            colDefs[colIdx] = {
                ...colDefs[colIdx],
                title: config.fieldName,
                header: headerContent,
                aiConfig: {
                    fieldName: config.fieldName,
                    aiTaskType: config.aiTaskType,
                    targetInfo: config.targetInfo,
                    content: config.content,
                    model: config.model,
                    autoUpdate: config.autoUpdate,
                    allowEmptyField: config.allowEmptyField,
                    fieldDescription: config.fieldDescription,
                    columnCode: columnId,
                    fieldType: config.aiTaskType || this.options.type,
                },
            };
            ctx.dataModel.setColumnDefinitions([...colDefs]);
        }
        ctx.dataModel.setCustomFieldAiConfig(columnId, {
            fieldName: config.fieldName,
            aiTaskType: config.aiTaskType,
            targetInfo: config.targetInfo,
            content: config.content,
            model: config.model,
            autoUpdate: config.autoUpdate,
            allowEmptyField: config.allowEmptyField,
            fieldDescription: config.fieldDescription,
            columnCode: columnId,
            fieldType: config.aiTaskType || this.options.type,
        });
        ctx.dataModel.updateRemoteViews();
        return {
            id: columnId,
            type: this.options.type,
            name: config.fieldName,
            config: { ...config, columnCode: columnId },
            runtime: { mode: 'async-task' },
        };
    }
    /** 从旧 aiConfig 分桶恢复 FieldRecord，用于编辑面板回填已有配置 */
    hydrate(columnId, ctx) {
        var _a, _b;
        const aiConfig = (_b = (_a = ctx.dataModel).getCustomFieldAiConfig) === null || _b === void 0 ? void 0 : _b.call(_a, columnId);
        if (!aiConfig)
            return undefined;
        return {
            id: columnId,
            type: aiConfig.fieldType || this.options.type,
            name: aiConfig.fieldName,
            config: aiConfig,
            runtime: { mode: 'async-task' },
        };
    }
    /** 从 dataModel 中彻底清理该字段的所有痕迹（列定义、分桶、各视图配置） */
    removeFieldFromDataModel(columnId, ctx) {
        const { dataModel } = ctx;
        const newColumnDefinitions = dataModel.columnDefinitions.filter((col) => col.dataIndex !== columnId);
        dataModel.setColumnDefinitions(newColumnDefinitions);
        dataModel.removeCustomField(columnId);
        dataModel.viewConfigs.forEach((config, viewId) => {
            const currentColumnOrder = config.columnOrder || [];
            const currentHiddenColumns = config.hiddenColumns || [];
            dataModel.setViewConfig(viewId, {
                columnOrder: currentColumnOrder.filter((col) => col !== columnId),
                hiddenColumns: currentHiddenColumns.filter((col) => col !== columnId),
                filter: (config.filter || []).filter((rule) => rule.field !== columnId),
                sort: (config.sort || []).filter((rule) => rule.field !== columnId),
                group: (config.group || []).filter((rule) => rule.field !== columnId),
                colorFill: (config.colorFill || []).filter((rule) => rule.field !== columnId),
            });
        });
        dataModel.updateRemoteViews();
    }
}
