/**
 * amis-ui v6.12.0-beta.0
 * Copyright 2018-2025 fex
 */

'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var tslib = require('tslib');
var amisCore = require('amis-core');
var React = require('react');
var Editor = require('./Editor.js');
var Button = require('../Button.js');
var icons = require('../icons.js');
var Modal = require('../Modal.js');
var PopUp = require('../PopUp.js');
var Input = require('./Input.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

var __react_jsx__ = require('react');
var _J$X_ = (__react_jsx__["default"] || __react_jsx__).createElement;
(__react_jsx__["default"] || __react_jsx__).Fragment;
var InputSchemaType = [
    'text',
    'number',
    'boolean',
    'date',
    'time',
    'datetime',
    'select',
    'custom'
];
var FormulaPicker = /** @class */ (function (_super) {
    tslib.__extends(FormulaPicker, _super);
    function FormulaPicker(props) {
        var _this = _super.call(this, props) || this;
        _this.unmounted = false;
        _this.props.onRef && _this.props.onRef(_this);
        _this.state = {
            isOpened: false,
            value: _this.props.value,
            editorValue: _this.value2EditorValue(_this.props),
            isError: false,
            variables: Array.isArray(props.variables) ? props.variables : []
        };
        return _this;
    }
    FormulaPicker.prototype.componentDidMount = function () {
        return tslib.__awaiter(this, void 0, void 0, function () {
            var _a, variables, data, list, result;
            return tslib.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        _a = this.props, variables = _a.variables, data = _a.data;
                        if (!(typeof variables === 'function')) return [3 /*break*/, 2];
                        return [4 /*yield*/, variables(this.props)];
                    case 1:
                        list = _b.sent();
                        this.setState({ variables: list });
                        return [3 /*break*/, 4];
                    case 2:
                        if (!(typeof variables === 'string' && amisCore.isExpression(variables))) return [3 /*break*/, 4];
                        return [4 /*yield*/, amisCore.resolveVariableAndFilterForAsync(variables, data, '|raw')];
                    case 3:
                        result = _b.sent();
                        this.setState({ variables: result });
                        _b.label = 4;
                    case 4:
                        this.buildFunctions();
                        return [2 /*return*/];
                }
            });
        });
    };
    FormulaPicker.prototype.componentDidUpdate = function (prevProps) {
        return tslib.__awaiter(this, void 0, void 0, function () {
            var value, _a, variables, data, list, result;
            return tslib.__generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        value = this.props.value;
                        if (value !== prevProps.value && !this.state.isOpened) {
                            this.setState({
                                value: typeof value === 'string' || !this.isTextInput() ? value : '',
                                editorValue: this.value2EditorValue(this.props)
                            });
                        }
                        if (!amisCore.anyChanged(['variables', 'data'], this.props, prevProps)) return [3 /*break*/, 4];
                        _a = this.props, variables = _a.variables, data = _a.data;
                        if (!(typeof variables === 'function')) return [3 /*break*/, 2];
                        return [4 /*yield*/, variables(this.props)];
                    case 1:
                        list = _b.sent();
                        this.setState({ variables: list });
                        return [3 /*break*/, 4];
                    case 2:
                        if (!(typeof variables === 'string' && amisCore.isExpression(variables))) return [3 /*break*/, 4];
                        return [4 /*yield*/, amisCore.resolveVariableAndFilterForAsync(variables, data, '|raw')];
                    case 3:
                        result = _b.sent();
                        this.setState({ variables: result });
                        _b.label = 4;
                    case 4:
                        if (prevProps.functions !== this.props.functions) {
                            this.buildFunctions();
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    FormulaPicker.prototype.componentWillUnmount = function () {
        this.unmounted = true;
    };
    FormulaPicker.prototype.buildFunctions = function (functions, setState) {
        if (functions === void 0) { functions = this.props.functions; }
        if (setState === void 0) { setState = true; }
        return tslib.__awaiter(this, void 0, void 0, function () {
            var functionList;
            return tslib.__generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, Editor.FormulaEditor.buildFunctions(functions, this.props.functionsFilter)];
                    case 1:
                        functionList = _a.sent();
                        if (this.unmounted) {
                            return [2 /*return*/];
                        }
                        if (!setState) {
                            return [2 /*return*/, functionList];
                        }
                        this.setState({
                            functions: functionList
                        });
                        return [2 /*return*/];
                }
            });
        });
    };
    FormulaPicker.prototype.value2EditorValue = function (props) {
        var value = props.value, mixedMode = props.mixedMode; props.inputSettings;
        if (mixedMode &&
            typeof value === 'string' &&
            /^\s*\$\{([\s\S]+)\}\s*$/.test(value)) {
            return RegExp.$1;
        }
        else if (typeof value !== 'string') {
            var editorValue = '';
            try {
                editorValue = JSON.stringify(value);
            }
            catch (error) { }
            return editorValue;
        }
        else {
            return value
                ? mixedMode
                    ? amisCore.isExpression(value)
                        ? "`".concat(value.replace(/`/g, '\\`'), "`")
                        : JSON.stringify(value)
                    : value
                : '';
        }
    };
    FormulaPicker.prototype.isTextInput = function () {
        var inputSettings = this.props.inputSettings;
        return (!inputSettings ||
            (inputSettings === null || inputSettings === void 0 ? void 0 : inputSettings.type) === 'text' ||
            !InputSchemaType.includes(inputSettings === null || inputSettings === void 0 ? void 0 : inputSettings.type));
    };
    FormulaPicker.prototype.handleConfirm = function () {
        var _a, _b;
        var value = this.state.value;
        if (this.props.onConfirm) {
            this.props.onConfirm(value);
        }
        else {
            (_b = (_a = this.props).onChange) === null || _b === void 0 ? void 0 : _b.call(_a, value);
        }
    };
    FormulaPicker.prototype.handleInputChange = function (value) {
        var _this = this;
        this.setState({ value: value }, function () { return _this.handleConfirm(); });
    };
    FormulaPicker.prototype.handleInputGroupChange = function (e) {
        var onChange = this.props.onChange;
        onChange && onChange(e.currentTarget.value);
    };
    FormulaPicker.prototype.handleEditorChange = function (value) {
        this.setState({
            editorValue: value,
            isError: false
        });
    };
    FormulaPicker.prototype.handleEditorConfirm = function () {
        var _a, _b;
        var _c = this.props; _c.translate; var inputSettings = _c.inputSettings;
        var editorValue = this.state.editorValue;
        var ast;
        try {
            ast = amisCore.parse(editorValue, {
                // mixedMode 弹窗中的一定是表达式
                evalMode: this.props.mixedMode ? true : this.props.evalMode,
                allowFilter: false
            });
        }
        catch (error) {
            this.setState({ isError: (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : true });
            return;
        }
        if ((inputSettings === null || inputSettings === void 0 ? void 0 : inputSettings.type) &&
            ['boolean', 'number'].includes(inputSettings === null || inputSettings === void 0 ? void 0 : inputSettings.type)) {
            var result = editorValue;
            // const schemaType = inputSettings?.type;
            if (ast.type === 'literal' || ast.type === 'string') {
                result = (_b = ast.value) !== null && _b !== void 0 ? _b : '';
            }
            this.setState({ isError: false });
            return this.confirm(result);
        }
        return this.confirm(editorValue, ast);
    };
    FormulaPicker.prototype.confirm = function (value, ast) {
        var _this = this;
        var mixedMode = this.props.mixedMode;
        var stateOnConfirm = this.state.onConfirm;
        var validate = this.validate(value);
        if (validate === true) {
            var result = value;
            if (mixedMode && typeof value === 'string') {
                result =
                    (ast === null || ast === void 0 ? void 0 : ast.type) === 'string'
                        ? ast.value
                        : (ast === null || ast === void 0 ? void 0 : ast.type) === 'template' &&
                            ast.body.length === 1 &&
                            ast.body[0].type === 'template_raw'
                            ? ast.body[0].value
                            : "${".concat(value, "}");
            }
            this.setState({ value: result, onConfirm: undefined }, function () {
                _this.close(undefined, function () {
                    stateOnConfirm
                        ? stateOnConfirm(_this.state.value)
                        : _this.handleConfirm();
                });
            });
        }
        else {
            this.setState({ isError: validate });
        }
    };
    FormulaPicker.prototype.handleClick = function () {
        return tslib.__awaiter(this, void 0, void 0, function () {
            return tslib.__generator(this, function (_a) {
                return [2 /*return*/, this.openEditor(this.value2EditorValue(this.props))];
            });
        });
    };
    FormulaPicker.prototype.openEditor = function (editorValue, onConfirm) {
        var _a, _b;
        return tslib.__awaiter(this, void 0, void 0, function () {
            var state, _c, _d;
            return tslib.__generator(this, function (_e) {
                switch (_e.label) {
                    case 0:
                        _c = [{}];
                        return [4 /*yield*/, ((_b = (_a = this.props).onPickerOpen) === null || _b === void 0 ? void 0 : _b.call(_a, this.props))];
                    case 1:
                        state = tslib.__assign.apply(void 0, [tslib.__assign.apply(void 0, _c.concat([(_e.sent())])), { editorValue: editorValue, isOpened: true, onConfirm: onConfirm }]);
                        if (!state.functions) return [3 /*break*/, 3];
                        _d = state;
                        return [4 /*yield*/, this.buildFunctions(state.functions, false)];
                    case 2:
                        _d.functions = _e.sent();
                        _e.label = 3;
                    case 3:
                        this.setState(state);
                        return [2 /*return*/];
                }
            });
        });
    };
    FormulaPicker.prototype.close = function (e, callback) {
        this.setState({
            isOpened: false,
            isError: false
        }, function () {
            if (callback) {
                callback();
                return;
            }
        });
    };
    FormulaPicker.prototype.updateState = function (state) {
        if (state === void 0) { state = {}; }
        state.isOpened; var rest = tslib.__rest(state, ["isOpened"]);
        this.setState(tslib.__assign(tslib.__assign({}, this.state), rest));
    };
    FormulaPicker.prototype.validate = function (value) {
        var _a = this.props, __ = _a.translate, inputSettings = _a.inputSettings;
        /** 处理非文本输入场景 */
        if (inputSettings && !this.isTextInput()) {
            var schemaType = inputSettings === null || inputSettings === void 0 ? void 0 : inputSettings.type;
            var errorMsg = __('FormulaEditor.invalidValue');
            /** 变量类型 */
            if (typeof value === 'string') {
                return true;
            }
            if (['number', 'boolean'].includes(schemaType)) {
                return typeof value === schemaType ? true : errorMsg;
            }
            else if (['text', 'date', 'time', 'datetime'].includes(schemaType)) {
                return typeof value === 'string' ? true : errorMsg;
            }
            else if (schemaType === 'select' && inputSettings.multiple) {
                return Array.isArray(value) ? true : errorMsg;
            }
            else {
                return true;
            }
        }
        try {
            value &&
                amisCore.parse(value, {
                    // mixedMode 值是模版， 要 ${} 包裹表达式
                    evalMode: this.props.mixedMode ? false : this.props.evalMode,
                    allowFilter: false
                });
            return true;
        }
        catch (e) {
            if (/\s(\d+:\d+)$/.test(e.message)) {
                var _b = tslib.__read(/\s(\d+:\d+)$/.exec(e.message) || [], 2), position = _b[1];
                return position;
            }
            return e.message;
        }
    };
    FormulaPicker.prototype.render = function () {
        var _a, _b, _c;
        var _d, _e, _f, _g, _h, _j, _k, _l;
        var _m = this.props, cx = _m.classnames, __ = _m.translate, disabled = _m.disabled, className = _m.className, style = _m.style; _m.onChange; _m.size; var borderMode = _m.borderMode, placeholder = _m.placeholder, _o = _m.mode, mode = _o === void 0 ? 'input-button' : _o, btnLabel = _m.btnLabel, level = _m.level, btnSize = _m.btnSize, icon = _m.icon, title = _m.title, clearable = _m.clearable, functions = _m.functions, children = _m.children, variableMode = _m.variableMode, mixedMode = _m.mixedMode, evalMode = _m.evalMode, popOverContainer = _m.popOverContainer, mobileUI = _m.mobileUI, inputSettings = _m.inputSettings, customInputRender = _m.customInputRender, rest = tslib.__rest(_m, ["classnames", "translate", "disabled", "className", "style", "onChange", "size", "borderMode", "placeholder", "mode", "btnLabel", "level", "btnSize", "icon", "title", "clearable", "functions", "children", "variableMode", "mixedMode", "evalMode", "popOverContainer", "mobileUI", "inputSettings", "customInputRender"]);
        var _p = this.state, isOpened = _p.isOpened, value = _p.value, editorValue = _p.editorValue, isError = _p.isError;
        var iconElement = _J$X_(icons.Icon, { cx: cx, icon: icon, className: "Icon" });
        return (_J$X_(React__default["default"].Fragment, null,
            children ? (children({
                isOpened: this.state.isOpened,
                onClick: this.handleClick,
                setState: this.updateState,
                value: value,
                onChange: this.handleInputChange,
                disabled: disabled
            })) : (_J$X_("div", { className: cx('FormulaPicker', mode === 'input-group' ? 'is-input-group' : '', {
                    'FormulaPicker--text': this.isTextInput()
                }, className), style: style },
                mode === 'button' && (_J$X_(Button["default"], { className: cx('FormulaPicker-action', 'w-full'), level: level, size: btnSize, active: !!value, onClick: this.handleClick },
                    iconElement ? (React__default["default"].cloneElement(iconElement, {
                        className: cx((_e = (_d = iconElement === null || iconElement === void 0 ? void 0 : iconElement.props) === null || _d === void 0 ? void 0 : _d.className) !== null && _e !== void 0 ? _e : '', 'FormulaPicker-icon', (_a = {},
                            _a['is-filled'] = !!value,
                            _a))
                    })) : (_J$X_(icons.Icon, { icon: "function", className: cx('FormulaPicker-icon', 'icon', (_b = {},
                            _b['is-filled'] = !!value,
                            _b)) })),
                    _J$X_("span", { className: cx('FormulaPicker-label') }, __(btnLabel || 'FormulaEditor.btnLabel')))),
                mode === 'input-button' && (_J$X_(React__default["default"].Fragment, null,
                    _J$X_(Input["default"], { className: cx('FormulaPicker-input', isOpened ? 'is-active' : '', !!isError ? 'is-error' : ''), inputSettings: inputSettings, customInputRender: customInputRender, clearable: clearable, evalMode: mixedMode ? false : evalMode, variables: this.state.variables, functions: (_f = this.state.functions) !== null && _f !== void 0 ? _f : functions, value: value, onChange: this.handleInputChange, disabled: disabled, borderMode: borderMode, placeholder: placeholder }),
                    _J$X_(Button["default"], { className: cx('FormulaPicker-action'), onClick: this.handleClick },
                        _J$X_(icons.Icon, { icon: "function", className: cx('FormulaPicker-icon', 'icon', (_c = {},
                                _c['is-filled'] = !!value,
                                _c)) })))),
                mode === 'input-group' && (_J$X_(React__default["default"].Fragment, null,
                    _J$X_(Input["default"], { className: cx('FormulaPicker-input', isOpened ? 'is-active' : '', !!isError ? 'is-error' : ''), inputSettings: inputSettings, customInputRender: customInputRender, clearable: clearable, evalMode: mixedMode ? false : evalMode, variables: this.state.variables, functions: (_g = this.state.functions) !== null && _g !== void 0 ? _g : functions, value: value, onChange: this.handleInputChange, disabled: disabled, borderMode: borderMode, placeholder: placeholder }),
                    _J$X_("a", { className: cx("FormulaPicker-toggler"), onClick: this.handleClick },
                        _J$X_(icons.Icon, { icon: "function", className: "icon" })))))),
            mobileUI ? (_J$X_(PopUp["default"], { className: cx("FormulaPicker-popup"), isShow: this.state.isOpened, showConfirm: true, onHide: this.close, onConfirm: this.handleEditorConfirm, container: popOverContainer },
                _J$X_("div", { className: cx('FormulaPicker-popup-inner') },
                    _J$X_(Editor["default"], tslib.__assign({}, rest, { evalMode: mixedMode ? true : evalMode, variables: this.state.variables, functions: (_h = this.state.functions) !== null && _h !== void 0 ? _h : functions, variableMode: (_j = this.state.variableMode) !== null && _j !== void 0 ? _j : variableMode, value: editorValue, onChange: this.handleEditorChange, selfVariableName: this.props.selfVariableName })),
                    !!isError ? (_J$X_("div", { className: cx('Dialog-info'), key: "info" },
                        _J$X_("span", { className: cx('Dialog-error') }, __('FormulaEditor.invalidData', { err: isError })))) : null))) : (_J$X_(Modal["default"], { size: "lg", closeOnEsc: true, show: this.state.isOpened, onHide: this.close, container: popOverContainer },
                _J$X_(Modal["default"].Header, { onClose: this.close, className: "font-bold" }, __(title || 'FormulaEditor.title')),
                _J$X_(Modal["default"].Body, null,
                    _J$X_(Editor["default"], tslib.__assign({}, rest, { evalMode: mixedMode ? true : evalMode, variables: this.state.variables, functions: (_k = this.state.functions) !== null && _k !== void 0 ? _k : functions, variableMode: (_l = this.state.variableMode) !== null && _l !== void 0 ? _l : variableMode, value: editorValue, onChange: this.handleEditorChange, selfVariableName: this.props.selfVariableName }))),
                _J$X_(Modal["default"].Footer, null,
                    !!isError ? (_J$X_("div", { className: cx('Dialog-info'), key: "info" },
                        _J$X_("span", { className: cx('Dialog-error') }, __('FormulaEditor.invalidData', { err: isError })))) : null,
                    _J$X_(Button["default"], { onClick: this.close }, __('cancel')),
                    _J$X_(Button["default"], { onClick: this.handleEditorConfirm, level: "primary" }, __('confirm')))))));
    };
    FormulaPicker.defaultProps = {
        evalMode: true
    };
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", []),
        tslib.__metadata("design:returntype", void 0)
    ], FormulaPicker.prototype, "handleConfirm", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", [String]),
        tslib.__metadata("design:returntype", void 0)
    ], FormulaPicker.prototype, "handleInputChange", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", [Object]),
        tslib.__metadata("design:returntype", void 0)
    ], FormulaPicker.prototype, "handleInputGroupChange", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", [String]),
        tslib.__metadata("design:returntype", void 0)
    ], FormulaPicker.prototype, "handleEditorChange", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", []),
        tslib.__metadata("design:returntype", void 0)
    ], FormulaPicker.prototype, "handleEditorConfirm", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", []),
        tslib.__metadata("design:returntype", Promise)
    ], FormulaPicker.prototype, "handleClick", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", [String, Function]),
        tslib.__metadata("design:returntype", Promise)
    ], FormulaPicker.prototype, "openEditor", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", [Object, Function]),
        tslib.__metadata("design:returntype", void 0)
    ], FormulaPicker.prototype, "close", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", [Object]),
        tslib.__metadata("design:returntype", void 0)
    ], FormulaPicker.prototype, "updateState", null);
    tslib.__decorate([
        amisCore.autobind,
        tslib.__metadata("design:type", Function),
        tslib.__metadata("design:paramtypes", [String]),
        tslib.__metadata("design:returntype", void 0)
    ], FormulaPicker.prototype, "validate", null);
    return FormulaPicker;
}(React__default["default"].Component));
var FormulaPicker$1 = amisCore.themeable(amisCore.localeable(amisCore.uncontrollable(FormulaPicker, {
    value: 'onChange'
})));

exports.FormulaPicker = FormulaPicker;
exports.InputSchemaType = InputSchemaType;
exports["default"] = FormulaPicker$1;
