"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FormulaFieldConfigPanel = FormulaFieldConfigPanel;
const i18n_1 = __importDefault(require("../../../../../../../locales/i18n.js"));
const arms_hot_tag_log_1 = require("../../../../../../../utils/arms/arms-hot-tag-log.js");
/**
 * 公式字段配置面板
 * 交互流程：内联面板（字段名 + 编辑公式按钮）→ 点击"编辑公式"弹出 CnDialog
 */
const react_1 = __importStar(require("react"));
const cn_ui_1 = require("@cainiaofe/cn-ui");
const mobx_react_simpler_1 = require("../../../../../../../utils/mobx-react-simpler/index.js");
const formula_editor_1 = require("./formula-editor");
const formula_engine_1 = require("./formula-engine");
const field_types_1 = require("../constants/field-types");
const formula_constants_1 = require("./formula-constants");
const formula_panel_components_1 = require("./formula-panel-components");
require("./formula-field-config-panel.scss");
function FormulaFieldConfigPanel({ fieldLabel, columnCode: existingColumnCode, initialExpression, onSave, onCancel, }) {
    const dataModel = (0, mobx_react_simpler_1.useModel)('dataModel');
    const [fieldName, setFieldName] = (0, react_1.useState)(fieldLabel);
    const [expression, setExpression] = (0, react_1.useState)(initialExpression || '');
    const [validationError, setValidationError] = (0, react_1.useState)('');
    const [editorDialogVisible, setEditorDialogVisible] = (0, react_1.useState)(false);
    const [pendingExpression, setPendingExpression] = (0, react_1.useState)('');
    const [hoveredItem, setHoveredItem] = (0, react_1.useState)(null);
    const editorRef = (0, react_1.useRef)(null);
    const fieldNameInputRef = (0, react_1.useRef)(null);
    const hoverLeaveTimerRef = (0, react_1.useRef)(null);
    const getAvailableFields = (0, react_1.useCallback)(() => {
        const columnDefinitions = (dataModel === null || dataModel === void 0 ? void 0 : dataModel.columnDefinitions) || [];
        const fieldMap = (dataModel === null || dataModel === void 0 ? void 0 : dataModel.fieldMap) || {};
        return columnDefinitions
            .filter((col) => {
            if (col.isAiColumn)
                return false;
            if (col.format === 'formula')
                return false;
            const fieldInfo = fieldMap[col.dataIndex];
            const componentType = (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo.component) || (fieldInfo === null || fieldInfo === void 0 ? void 0 : fieldInfo['x-component']);
            if (!componentType)
                return true;
            return field_types_1.FORMULA_FIELD_WHITELIST_COMPONENTS.includes(componentType);
        })
            .map((col) => {
            var _a;
            return ({
                dataIndex: col.dataIndex,
                title: col.title || col.dataIndex,
                component: (_a = fieldMap[col.dataIndex]) === null || _a === void 0 ? void 0 : _a.component,
            });
        });
    }, [dataModel]);
    const availableFields = (0, react_1.useMemo)(() => getAvailableFields(), [getAvailableFields]);
    const groupedFunctions = (0, react_1.useMemo)(() => {
        return formula_constants_1.FORMULA_FUNCTION_CATEGORIES.map((cat) => {
            var _a, _b, _c, _d;
            return ({
                category: cat,
                label: (_b = (_a = formula_constants_1.FUNCTION_GROUP_LABELS[cat]) === null || _a === void 0 ? void 0 : _a.label) !== null && _b !== void 0 ? _b : cat,
                i18nId: (_d = (_c = formula_constants_1.FUNCTION_GROUP_LABELS[cat]) === null || _c === void 0 ? void 0 : _c.i18nId) !== null && _d !== void 0 ? _d : cat,
                functions: formula_constants_1.FORMULA_FUNCTIONS.filter((fn) => fn.category === cat),
            });
        }).filter((g) => g.functions.length > 0);
    }, []);
    const previewResult = (0, react_1.useMemo)(() => {
        if (!pendingExpression.trim())
            return null;
        const rows = (dataModel === null || dataModel === void 0 ? void 0 : dataModel.rawData) || [];
        if (rows.length === 0)
            return null;
        try {
            const columnDefinitions = (dataModel === null || dataModel === void 0 ? void 0 : dataModel.columnDefinitions) || [];
            const processedColumnMap = (dataModel === null || dataModel === void 0 ? void 0 : dataModel.processedColumnMap) || new Map();
            const result = (0, formula_engine_1.evaluateFormula)(pendingExpression, {
                row: rows[0],
                fields: availableFields,
                allowedFunctions: new Set(formula_constants_1.FORMULA_FUNCTIONS.map((f) => f.name)),
                columnDefinitions,
                processedColumnMap,
                rowIndex: 0,
            });
            return result !== undefined && result !== null ? String(result) : null;
        }
        catch {
            return null;
        }
    }, [
        pendingExpression,
        dataModel === null || dataModel === void 0 ? void 0 : dataModel.rawData,
        dataModel === null || dataModel === void 0 ? void 0 : dataModel.columnDefinitions,
        dataModel === null || dataModel === void 0 ? void 0 : dataModel.processedColumnMap,
        availableFields,
    ]);
    (0, react_1.useEffect)(() => {
        const timer = setTimeout(() => {
            var _a, _b;
            if (fieldNameInputRef.current) {
                const inputNode = ((_b = (_a = fieldNameInputRef.current).getInputNode) === null || _b === void 0 ? void 0 : _b.call(_a)) || fieldNameInputRef.current;
                if (inputNode && typeof inputNode.focus === 'function') {
                    inputNode.focus();
                    if (typeof inputNode.select === 'function') {
                        inputNode.select();
                    }
                }
            }
        }, 100);
        return () => clearTimeout(timer);
    }, []);
    (0, react_1.useEffect)(() => {
        return () => {
            if (hoverLeaveTimerRef.current) {
                clearTimeout(hoverLeaveTimerRef.current);
            }
        };
    }, []);
    const handleExpressionChange = (0, react_1.useCallback)((newValue) => {
        setPendingExpression(newValue);
        if (validationError) {
            setValidationError('');
        }
    }, [validationError]);
    const handleHoverEnter = (0, react_1.useCallback)((item) => {
        if (hoverLeaveTimerRef.current) {
            clearTimeout(hoverLeaveTimerRef.current);
            hoverLeaveTimerRef.current = null;
        }
        setHoveredItem(item);
    }, []);
    const handleHoverLeave = (0, react_1.useCallback)(() => {
        hoverLeaveTimerRef.current = setTimeout(() => {
            setHoveredItem(null);
            hoverLeaveTimerRef.current = null;
        }, 150);
    }, []);
    const handleInfoPanelMouseEnter = (0, react_1.useCallback)(() => {
        if (hoverLeaveTimerRef.current) {
            clearTimeout(hoverLeaveTimerRef.current);
            hoverLeaveTimerRef.current = null;
        }
    }, []);
    const handleInfoPanelMouseLeave = (0, react_1.useCallback)(() => {
        setHoveredItem(null);
    }, []);
    const handleOpenEditorDialog = () => {
        var _a;
        (0, arms_hot_tag_log_1.armsHottagLog)({
            hottag: 'cn-ai-table.formulaField.openEditor',
            name: i18n_1.default.get({ id: 'OpenTheFormulaEditor', dm: '打开公式编辑器' }),
            c6: existingColumnCode || '',
            c7: String((_a = dataModel === null || dataModel === void 0 ? void 0 : dataModel.tableId) !== null && _a !== void 0 ? _a : ''),
        });
        setPendingExpression(expression);
        setHoveredItem(null);
        setEditorDialogVisible(true);
    };
    const handleEditorDialogConfirm = () => {
        var _a, _b;
        (0, arms_hot_tag_log_1.armsHottagLog)({
            hottag: 'cn-ai-table.formulaField.editorConfirm',
            name: i18n_1.default.get({ id: 'ConfirmFormulaEditing', dm: '确认公式编辑' }),
            c6: existingColumnCode || '',
            c7: String((_a = dataModel === null || dataModel === void 0 ? void 0 : dataModel.tableId) !== null && _a !== void 0 ? _a : ''),
            c8: String((_b = pendingExpression === null || pendingExpression === void 0 ? void 0 : pendingExpression.length) !== null && _b !== void 0 ? _b : 0),
        });
        setExpression(pendingExpression);
        setEditorDialogVisible(false);
    };
    const handleEditorDialogClose = () => {
        var _a;
        (0, arms_hot_tag_log_1.armsHottagLog)({
            hottag: 'cn-ai-table.formulaField.editorCancel',
            name: i18n_1.default.get({ id: 'CancelFormulaEditing', dm: '取消公式编辑' }),
            c6: existingColumnCode || '',
            c7: String((_a = dataModel === null || dataModel === void 0 ? void 0 : dataModel.tableId) !== null && _a !== void 0 ? _a : ''),
        });
        setPendingExpression('');
        setEditorDialogVisible(false);
    };
    const handleInsertFunction = (fn) => {
        const editor = editorRef.current;
        if (!editor)
            return;
        editor.insertText(`${fn.name}(`);
    };
    const validateForm = () => {
        if (!fieldName.trim()) {
            setValidationError(i18n_1.default.get({ id: 'PleaseEnterAFieldName', dm: '请输入字段名称' }));
            return false;
        }
        if (!expression.trim()) {
            setValidationError(i18n_1.default.get({ id: 'EnterFormula', dm: '请输入公式' }));
            return false;
        }
        const validation = (0, formula_engine_1.validateFormula)(expression);
        if (!validation.valid) {
            setValidationError(validation.error || '');
            return false;
        }
        setValidationError('');
        return true;
    };
    const handleSave = () => {
        if (!validateForm())
            return;
        const referencedFields = (0, formula_engine_1.extractReferencedFields)(expression);
        const columnCode = existingColumnCode || `formula_column_${Date.now()}`;
        const config = {
            fieldName,
            expression,
            referencedFields,
            columnCode,
        };
        onSave(config);
    };
    const handleCancel = () => {
        setFieldName(fieldLabel);
        setExpression(initialExpression || '');
        setValidationError('');
        onCancel();
    };
    const displayExpression = (0, react_1.useMemo)(() => {
        if (!expression.trim())
            return '';
        const fieldMap = new Map(availableFields.map((f) => [f.dataIndex, f.title]));
        return expression.replace(/\{([^}]+)\}/g, (_match, inner) => {
            const title = fieldMap.get(inner.trim());
            return title ? `{${title}}` : _match;
        });
    }, [expression, availableFields]);
    const hasExpression = expression.trim().length > 0;
    return (react_1.default.createElement(react_1.default.Fragment, null,
        react_1.default.createElement("div", { className: "formula-field-config-panel" },
            react_1.default.createElement("div", { className: "formula-field-config-header" },
                react_1.default.createElement("div", { className: "formula-field-config-header-left" },
                    react_1.default.createElement(cn_ui_1.CnIcon, { type: "function", style: { color: '#1677ff', fontSize: '16px' } }),
                    react_1.default.createElement("span", { className: "formula-field-config-title" }, i18n_1.default.get({ id: 'FormulaField', dm: '公式字段' }))),
                react_1.default.createElement(cn_ui_1.CnIcon, { type: "close", size: "small", onClick: handleCancel, style: { cursor: 'pointer' } })),
            react_1.default.createElement("div", { className: "formula-field-config-content" },
                react_1.default.createElement("div", { className: "formula-field-config-section" },
                    react_1.default.createElement(cn_ui_1.CnInput, { ref: fieldNameInputRef, value: fieldName, onChange: setFieldName, placeholder: i18n_1.default.get({ id: 'EnterFieldTitle', dm: '请输入字段标题' }), style: { width: '100%' } })),
                react_1.default.createElement("div", { className: "formula-field-config-section" },
                    react_1.default.createElement("div", { className: "formula-field-config-label" }, i18n_1.default.get({ id: 'Formula', dm: '公式' })),
                    react_1.default.createElement("div", { className: "formula-field-edit-button", onClick: handleOpenEditorDialog },
                        react_1.default.createElement(cn_ui_1.CnIcon, { type: "edit", size: "small" }),
                        react_1.default.createElement("span", null, i18n_1.default.get({ id: 'EditFormula', dm: '编辑公式' }))),
                    hasExpression && (react_1.default.createElement("div", { className: "formula-field-expression-preview" }, displayExpression)),
                    validationError && (react_1.default.createElement("div", { className: "formula-field-config-validation-error" }, validationError)))),
            react_1.default.createElement("div", { className: "formula-field-config-footer" },
                react_1.default.createElement("div", { style: { display: 'flex', gap: '8px' } },
                    react_1.default.createElement(cn_ui_1.CnButton, { onClick: handleCancel }, i18n_1.default.get({ id: 'Cancel', dm: '取消' })),
                    react_1.default.createElement(cn_ui_1.CnButton, { type: "primary", onClick: handleSave }, i18n_1.default.get({ id: 'OK', dm: '确定' }))))),
        react_1.default.createElement(cn_ui_1.CnDialog, { visible: editorDialogVisible, onClose: handleEditorDialogClose, title: react_1.default.createElement("div", { className: "formula-editor-dialog-title" },
                react_1.default.createElement("span", null, i18n_1.default.get({ id: 'FormulaEditor', dm: '公式编辑器' })),
                react_1.default.createElement(cn_ui_1.CnIcon, { type: "help-color", size: 16, style: { marginLeft: '4px', cursor: 'pointer' } })), size: "medium", className: "formula-editor-dialog", footer: false },
            react_1.default.createElement("div", { className: "formula-editor-dialog-content" },
                react_1.default.createElement("div", { className: "formula-editor-dialog-editor-section" },
                    react_1.default.createElement("div", { className: "formula-editor-dialog-editor-wrapper" },
                        react_1.default.createElement(formula_editor_1.FormulaEditor, { ref: editorRef, value: pendingExpression, onChange: handleExpressionChange, fields: availableFields, placeholder: i18n_1.default.get({
                                id: 'EnterAFormulaExpressionSuchAsSUM_1722066728',
                                dm: '输入公式表达式，如 =SUM({字段1}, {字段2})',
                            }), minHeight: 140 }),
                        react_1.default.createElement("div", { className: "formula-editor-dialog-editor-footer" },
                            previewResult !== null && (react_1.default.createElement("div", { className: "formula-editor-preview-result" },
                                react_1.default.createElement("span", { className: "formula-editor-preview-label" }, i18n_1.default.get({ id: 'PreviewFirstRowResult', dm: '预览首行结果' })),
                                react_1.default.createElement("span", { className: "formula-editor-preview-tag" }, fieldName || i18n_1.default.get({ id: 'FormulaField', dm: '公式字段' })),
                                react_1.default.createElement("span", { className: "formula-editor-preview-separator" }, ":"),
                                react_1.default.createElement("span", { className: "formula-editor-preview-value" }, previewResult))),
                            react_1.default.createElement(cn_ui_1.CnButton, { type: "primary", size: "small", onClick: handleEditorDialogConfirm }, i18n_1.default.get({ id: 'OK', dm: '确定' }))))),
                react_1.default.createElement("div", { className: "formula-editor-dialog-bottom-panel" },
                    react_1.default.createElement("div", { className: "formula-editor-dialog-bottom-panel-content" },
                        react_1.default.createElement("div", { className: "formula-editor-dialog-tabs" },
                            react_1.default.createElement("span", { className: "formula-editor-dialog-tab active" }, i18n_1.default.get({ id: 'FormulaEditor', dm: '公式编辑器' }))),
                        react_1.default.createElement("div", { className: "formula-editor-dialog-panel-body" },
                            react_1.default.createElement("div", { className: "formula-editor-dialog-fields" },
                                react_1.default.createElement("div", { className: "formula-editor-dialog-fields-list" },
                                    react_1.default.createElement("div", { className: "formula-editor-dialog-group-title" }, i18n_1.default.get({ id: 'FieldReference', dm: '字段引用' })),
                                    availableFields.map((field) => (react_1.default.createElement(formula_panel_components_1.FieldReferenceItem, { key: field.dataIndex, field: field, editorRef: editorRef, onHover: (f) => handleHoverEnter({ type: 'field', data: f }), onLeave: handleHoverLeave, isActive: (hoveredItem === null || hoveredItem === void 0 ? void 0 : hoveredItem.type) === 'field' &&
                                            hoveredItem.data.dataIndex === field.dataIndex }))),
                                    availableFields.length === 0 && (react_1.default.createElement("span", { className: "formula-editor-dialog-no-fields" }, i18n_1.default.get({ id: 'NoReferenceFieldsAvailable', dm: '暂无可引用字段' }))),
                                    groupedFunctions.map((group) => (react_1.default.createElement(react_1.default.Fragment, { key: group.category },
                                        react_1.default.createElement("div", { className: "formula-editor-dialog-group-title" }, group.label),
                                        group.functions.map((fn) => (react_1.default.createElement(formula_panel_components_1.FunctionReferenceItem, { key: fn.name, fn: fn, onInsert: () => handleInsertFunction(fn), onHover: (f) => handleHoverEnter({ type: 'function', data: f }), onLeave: handleHoverLeave, isActive: (hoveredItem === null || hoveredItem === void 0 ? void 0 : hoveredItem.type) === 'function' && hoveredItem.data.name === fn.name })))))))),
                            react_1.default.createElement("div", { className: "formula-editor-dialog-field-info", onMouseEnter: handleInfoPanelMouseEnter, onMouseLeave: handleInfoPanelMouseLeave },
                                react_1.default.createElement(formula_panel_components_1.InfoDetailPanel, { hoveredItem: hoveredItem })))))))));
}
