import { evaluators } from "@tachybase/evaluators/client";
import { uid } from "@tachybase/utils/client";
import lodash from "lodash";
import { ActionType } from "../../../schema-settings/LinkageRules/type.mjs";
import { REGEX_OF_VARIABLE } from "../../../variables/utils/isVariable.mjs";
import { conditionAnalyses } from "../../common/utils/uitls.mjs";
async function getTempFieldState(condition, value) {
    [condition, value] = await Promise.all([
        condition,
        value
    ]);
    return {
        condition,
        value
    };
}
const collectFieldStateOfLinkageRules = (param)=>{
    let { operator, value, field, condition, variables, localVariables } = param;
    var _field_stateOfLinkageRules, _field_initStateOfLinkageRules, _field_stateOfLinkageRules1, _field_initStateOfLinkageRules1, _field_stateOfLinkageRules2, _field_initStateOfLinkageRules2, _field_stateOfLinkageRules3, _field_initStateOfLinkageRules3;
    const requiredResult = (null == field ? void 0 : null == (_field_stateOfLinkageRules = field.stateOfLinkageRules) ? void 0 : _field_stateOfLinkageRules.required) || [
        null == field ? void 0 : null == (_field_initStateOfLinkageRules = field.initStateOfLinkageRules) ? void 0 : _field_initStateOfLinkageRules.required
    ];
    const displayResult = (null == field ? void 0 : null == (_field_stateOfLinkageRules1 = field.stateOfLinkageRules) ? void 0 : _field_stateOfLinkageRules1.display) || [
        null == field ? void 0 : null == (_field_initStateOfLinkageRules1 = field.initStateOfLinkageRules) ? void 0 : _field_initStateOfLinkageRules1.display
    ];
    const patternResult = (null == field ? void 0 : null == (_field_stateOfLinkageRules2 = field.stateOfLinkageRules) ? void 0 : _field_stateOfLinkageRules2.pattern) || [
        null == field ? void 0 : null == (_field_initStateOfLinkageRules2 = field.initStateOfLinkageRules) ? void 0 : _field_initStateOfLinkageRules2.pattern
    ];
    const valueResult = (null == field ? void 0 : null == (_field_stateOfLinkageRules3 = field.stateOfLinkageRules) ? void 0 : _field_stateOfLinkageRules3.value) || [
        null == field ? void 0 : null == (_field_initStateOfLinkageRules3 = field.initStateOfLinkageRules) ? void 0 : _field_initStateOfLinkageRules3.value
    ];
    const { evaluate } = evaluators.get('formula.js');
    switch(operator){
        case ActionType.Required:
            requiredResult.push(getTempFieldState(conditionAnalyses({
                ruleGroup: condition,
                variables,
                localVariables
            }), true));
            field.stateOfLinkageRules = {
                ...field.stateOfLinkageRules,
                required: requiredResult
            };
            break;
        case ActionType.InRequired:
            requiredResult.push(getTempFieldState(conditionAnalyses({
                ruleGroup: condition,
                variables,
                localVariables
            }), false));
            field.stateOfLinkageRules = {
                ...field.stateOfLinkageRules,
                required: requiredResult
            };
            break;
        case ActionType.Visible:
        case ActionType.None:
        case ActionType.Hidden:
            displayResult.push(getTempFieldState(conditionAnalyses({
                ruleGroup: condition,
                variables,
                localVariables
            }), operator));
            field.stateOfLinkageRules = {
                ...field.stateOfLinkageRules,
                display: displayResult
            };
            break;
        case ActionType.Editable:
        case ActionType.ReadOnly:
        case ActionType.ReadPretty:
            patternResult.push(getTempFieldState(conditionAnalyses({
                ruleGroup: condition,
                variables,
                localVariables
            }), operator));
            field.stateOfLinkageRules = {
                ...field.stateOfLinkageRules,
                pattern: patternResult
            };
            break;
        case ActionType.Value:
            {
                const getValue = async ()=>{
                    if ((null == value ? void 0 : value.mode) === 'express') {
                        if (null == (value.value || value.result)) return;
                        const { exp, scope: expScope } = await replaceVariables(value.value || value.result, {
                            variables,
                            localVariables
                        });
                        try {
                            const result = evaluate(exp, {
                                now: ()=>new Date().toString(),
                                ...expScope
                            });
                            return result;
                        } catch (error) {
                            console.error(error);
                        }
                    } else if ((null == value ? void 0 : value.mode) === 'constant') return (null == value ? void 0 : value.value) || value;
                    else return null;
                };
                if (isConditionEmpty(condition)) valueResult.push(getTempFieldState(true, getValue()));
                else valueResult.push(getTempFieldState(conditionAnalyses({
                    ruleGroup: condition,
                    variables,
                    localVariables
                }), getValue()));
                field.stateOfLinkageRules = {
                    ...field.stateOfLinkageRules,
                    value: valueResult
                };
            }
            break;
        default:
            return null;
    }
};
async function replaceVariables(value, param) {
    let { variables, localVariables } = param;
    var _value_match;
    const store = {};
    const scope = {};
    if (null == value) return;
    const waitForParsing = null == (_value_match = value.match(REGEX_OF_VARIABLE)) ? void 0 : _value_match.map(async (item)=>{
        const result = await variables.parseVariable(item, localVariables);
        const id = "_".concat(uid());
        scope[id] = result;
        store[item] = id;
        return result;
    });
    if (waitForParsing) await Promise.all(waitForParsing);
    return {
        exp: value.replace(REGEX_OF_VARIABLE, (match)=>"{{".concat(store[match] || match, "}}")),
        scope
    };
}
function isConditionEmpty(rules) {
    const type = Object.keys(rules)[0] || '$and';
    const conditions = rules[type];
    return lodash.isEmpty(conditions);
}
export { collectFieldStateOfLinkageRules, getTempFieldState };
