import { jsx, jsxs } from "react/jsx-runtime";
import react, { useCallback, useEffect, useMemo } from "react";
import { useForm } from "@tachybase/schema";
import { CloseCircleFilled } from "@ant-design/icons";
import { error } from "@tego/client";
import { Cascader, DatePicker, Input, InputNumber, Select, Space, Tag } from "antd";
import { createStyles } from "antd-style";
import classnames from "classnames";
import dayjs from "dayjs";
import { cloneDeep } from "lodash";
import { useTranslation } from "react-i18next";
import { useCompile } from "../../hooks/index.mjs";
import { useStyles } from "./style.mjs";
import { XButton } from "./XButton.mjs";
const JT_VALUE_RE = /^\s*{{\s*([^{}]+)\s*}}\s*$/;
function parseValue(value) {
    if (null == value) return 'null';
    const type = typeof value;
    if ('string' === type) {
        const matched = value.match(JT_VALUE_RE);
        if (matched) return matched[1].split('.');
    }
    return 'object' === type && value instanceof Date ? 'date' : type;
}
const ConstantTypes = {
    string: {
        label: '{{t("String")}}',
        value: 'string',
        component: function(param) {
            let { onChange, value, ...otherProps } = param;
            return /*#__PURE__*/ jsx(Input, {
                value: value,
                onChange: (ev)=>onChange(ev.target.value),
                ...otherProps
            });
        },
        default: ''
    },
    number: {
        label: '{{t("Number")}}',
        value: 'number',
        component: function(param) {
            let { onChange, value, ...otherProps } = param;
            return /*#__PURE__*/ jsx(InputNumber, {
                value: value,
                onChange: onChange,
                ...otherProps
            });
        },
        default: 0
    },
    boolean: {
        label: '{{t("Boolean")}}',
        value: 'boolean',
        component: function(param) {
            let { onChange, value, ...otherProps } = param;
            const { t } = useTranslation();
            return /*#__PURE__*/ jsx(Select, {
                value: value,
                onChange: onChange,
                placeholder: t('Select'),
                options: [
                    {
                        value: true,
                        label: t('True')
                    },
                    {
                        value: false,
                        label: t('False')
                    }
                ],
                ...otherProps
            });
        },
        default: false
    },
    date: {
        label: '{{t("Date")}}',
        value: 'date',
        component: function(param) {
            let { onChange, value, ...otherProps } = param;
            return /*#__PURE__*/ jsx(DatePicker, {
                value: dayjs(value),
                onChange: (d)=>d ? onChange(d.toDate()) : null,
                allowClear: false,
                showTime: true,
                ...otherProps
            });
        },
        default: (()=>{
            const now = new Date();
            return new Date(now.getFullYear(), now.getMonth(), now.getDate(), 0, 0, 0);
        })()
    },
    null: {
        label: '{{t("Null")}}',
        value: 'null',
        component: function() {
            const { t } = useTranslation();
            return /*#__PURE__*/ jsx(Input, {
                style: {
                    width: '100%'
                },
                readOnly: true,
                placeholder: t('Null'),
                className: "null-value"
            });
        },
        default: null
    }
};
function getTypedConstantOption(type, types, fieldNames) {
    var _ConstantTypes_type;
    const allTypes = Object.values(ConstantTypes);
    const children = (types ? allTypes.filter((item)=>Array.isArray(types) && types.includes(item.value) || true === types) : allTypes).map((item)=>Object.keys(item).reduce((result, key)=>fieldNames[key] in item ? result : Object.assign(result, {
                [fieldNames[key]]: item[key]
            }), item));
    return {
        value: '',
        label: '{{t("Constant")}}',
        children,
        [fieldNames.value]: '',
        [fieldNames.label]: '{{t("Constant")}}',
        [fieldNames.children]: children,
        component: null == (_ConstantTypes_type = ConstantTypes[type]) ? void 0 : _ConstantTypes_type.component
    };
}
createStyles((param, param1)=>{
    let { css } = param, { disabled } = param1;
    return {};
});
function Input_Input(props) {
    var _constantOption_children;
    const { value = '', onChange, children, button, useTypedConstant, style, className, changeOnSelect, fieldNames } = props;
    const scope = 'function' == typeof props.scope ? props.scope() : props.scope;
    const compile = useCompile();
    const { t } = useTranslation();
    const form = useForm();
    const [options, setOptions] = react.useState([]);
    const [variableText, setVariableText] = react.useState('');
    const parsed = useMemo(()=>parseValue(value), [
        value
    ]);
    const isConstant = 'string' == typeof parsed;
    const type = isConstant ? parsed : '';
    const variable = isConstant ? null : parsed;
    const names = Object.assign({
        label: 'label',
        value: 'value',
        children: 'children'
    }, null != fieldNames ? fieldNames : {});
    const { component: ConstantComponent, ...constantOption } = useMemo(()=>{
        if (children) return {
            value: '',
            label: t('Constant'),
            [names.value]: '',
            [names.label]: t('Constant')
        };
        if (useTypedConstant) return getTypedConstantOption(type, useTypedConstant, names);
        return {
            value: '',
            label: t('Null'),
            [names.value]: '',
            [names.label]: t('Null'),
            component: ConstantTypes.null.component
        };
    }, [
        type,
        useTypedConstant
    ]);
    useEffect(()=>{
        setOptions([
            compile(constantOption),
            ...scope ? cloneDeep(scope) : []
        ]);
    }, [
        scope
    ]);
    const loadData = async (selectedOptions)=>{
        var _option_children;
        const option = selectedOptions[selectedOptions.length - 1];
        if (!(null == (_option_children = option.children) ? void 0 : _option_children.length) && !option.isLeaf && option.loadChildren) {
            await option.loadChildren(option);
            setOptions((prev)=>[
                    ...prev
                ]);
        }
    };
    const onSwitch = useCallback((next, optionPath)=>{
        if ('' === next[0]) {
            if (next[1]) {
                if (next[1] !== type) {
                    var _ConstantTypes_next_;
                    var _ConstantTypes_next__default;
                    onChange(null != (_ConstantTypes_next__default = null == (_ConstantTypes_next_ = ConstantTypes[next[1]]) ? void 0 : _ConstantTypes_next_.default) ? _ConstantTypes_next__default : null, optionPath);
                }
            } else if (variable) onChange(null, optionPath);
            return;
        }
        onChange("{{".concat(next.join('.'), "}}"), optionPath);
    }, [
        type,
        variable,
        onChange
    ]);
    useEffect(()=>{
        const run = async ()=>{
            if (!variable || options.length <= 1) return;
            let prevOption = null;
            const labels = [];
            for(let i = 0; i < variable.length; i++){
                const key = variable[i];
                try {
                    if (0 === i) prevOption = options.find((item)=>item[names.value] === key);
                    else {
                        var _prevOption_children;
                        if (prevOption.loadChildren && !(null == (_prevOption_children = prevOption.children) ? void 0 : _prevOption_children.length)) await prevOption.loadChildren(prevOption);
                        prevOption = prevOption.children.find((item)=>item[names.value] === key);
                    }
                    if (!prevOption) return;
                    labels.push(prevOption[names.label]);
                } catch (err) {
                    error(err);
                }
            }
            setOptions([
                ...options
            ]);
            setVariableText(labels.join(' / '));
        };
        run();
    }, [
        variable,
        options.length
    ]);
    const disabled = props.disabled || form.disabled;
    const { styles } = useStyles({
        disabled
    });
    return /*#__PURE__*/ jsxs(Space.Compact, {
        style: style,
        className: classnames(styles.outerContainer, styles.fixInput, className),
        children: [
            variable ? /*#__PURE__*/ jsxs("div", {
                className: classnames('variable', styles.container2),
                children: [
                    /*#__PURE__*/ jsx("div", {
                        role: "button",
                        "aria-label": "variable-tag",
                        onInput: (e)=>e.preventDefault(),
                        onKeyDown: (e)=>{
                            if ('Backspace' !== e.key) return void e.preventDefault();
                            onChange(null);
                        },
                        className: classnames('ant-input', {
                            'ant-input-disabled': disabled
                        }),
                        contentEditable: !disabled,
                        suppressContentEditableWarning: true,
                        children: /*#__PURE__*/ jsx(Tag, {
                            contentEditable: false,
                            color: "blue",
                            children: variableText
                        })
                    }),
                    disabled ? null : /*#__PURE__*/ jsx("span", {
                        role: "button",
                        "aria-label": "icon-close",
                        className: classnames('clear-button'),
                        unselectable: "on",
                        onClick: ()=>onChange(null),
                        children: /*#__PURE__*/ jsx(CloseCircleFilled, {})
                    })
                ]
            }) : /*#__PURE__*/ jsx("div", {
                style: {
                    flex: 1
                },
                children: null != children ? children : /*#__PURE__*/ jsx(ConstantComponent, {
                    role: "button",
                    "aria-label": "variable-constant",
                    value: value,
                    onChange: onChange
                })
            }),
            /*#__PURE__*/ jsx(Cascader, {
                options: options,
                value: null != variable ? variable : [
                    '',
                    ...!children && (null == (_constantOption_children = constantOption.children) ? void 0 : _constantOption_children.length) ? [
                        type
                    ] : []
                ],
                onChange: onSwitch,
                loadData: loadData,
                changeOnSelect: changeOnSelect,
                fieldNames: fieldNames,
                disabled: disabled,
                children: null != button ? button : /*#__PURE__*/ jsx(XButton, {
                    className: styles.button2,
                    type: variable ? 'primary' : 'default'
                })
            })
        ]
    });
}
export { Input_Input as Input };
