import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__ from "react/jsx-runtime";
import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
import * as __WEBPACK_EXTERNAL_MODULE__tachybase_schema__ from "@tachybase/schema";
import * as __WEBPACK_EXTERNAL_MODULE__tachybase_utils_client__ from "@tachybase/utils/client";
import * as __WEBPACK_EXTERNAL_MODULE_lodash__ from "lodash";
import * as __WEBPACK_EXTERNAL_MODULE__api_client_index_mjs__ from "../api-client/index.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__collection_manager_index_mjs__ from "../collection-manager/index.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__schema_component_index_mjs__ from "../schema-component/index.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__hooks_useBuiltinVariables_mjs__ from "./hooks/useBuiltinVariables.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__utils_filterEmptyValues_mjs__ from "./utils/filterEmptyValues.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__utils_getAction_mjs__ from "./utils/getAction.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__utils_getPath_mjs__ from "./utils/getPath.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__ from "./utils/hasRequested.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__utils_isVariable_mjs__ from "./utils/isVariable.mjs";
import * as __WEBPACK_EXTERNAL_MODULE__utils_uniq_mjs__ from "./utils/uniq.mjs";
const VariablesContext = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react__.createContext)(null);
VariablesContext.displayName = 'VariablesContext';
const VariablesProvider_rslib_entry_variableToCollectionName = {};
const getFieldPath = (variablePath, variableToCollectionName)=>{
    const list = variablePath.split('.');
    const result = list.map((item)=>{
        if (variableToCollectionName[item]) return variableToCollectionName[item];
        return item;
    });
    return result.join('.');
};
const VariablesProvider = (param)=>{
    let { children } = param;
    const ctxRef = (0, __WEBPACK_EXTERNAL_MODULE_react__.useRef)({});
    const api = (0, __WEBPACK_EXTERNAL_MODULE__api_client_index_mjs__.useAPIClient)();
    const { getCollectionJoinField } = (0, __WEBPACK_EXTERNAL_MODULE__collection_manager_index_mjs__.useCollectionManager_deprecated)();
    const compile = (0, __WEBPACK_EXTERNAL_MODULE__schema_component_index_mjs__.useCompile)();
    const { builtinVariables } = (0, __WEBPACK_EXTERNAL_MODULE__hooks_useBuiltinVariables_mjs__["default"])();
    const setCtx = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((ctx)=>{
        if (__WEBPACK_EXTERNAL_MODULE_lodash__["default"].isFunction(ctx)) ctxRef.current = ctx(ctxRef.current);
        else ctxRef.current = ctx;
    }, []);
    const getValue = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)(async (variablePath, localVariables, options)=>{
        const list = variablePath.split('.');
        const variableName = list[0];
        const _variableToCollectionName = mergeVariableToCollectionNameWithLocalVariables(VariablesProvider_rslib_entry_variableToCollectionName, localVariables);
        let current = mergeCtxWithLocalVariables(ctxRef.current, localVariables);
        let collectionName = getFieldPath(variableName, _variableToCollectionName);
        if (!(variableName in current)) throw new Error("VariablesProvider: ".concat(variableName, " is not found"));
        for(let index = 0; index < list.length; index++){
            if (null == current) return current;
            if ('$nParentRecord' === list[index]) {
                if (!(list[index + 1] in current[list[index]]) && '__parent' in current[list[index]]) list.splice(1, 0, '__parent');
            }
            const key = list[index];
            const associationField = getCollectionJoinField(getFieldPath(list.slice(0, index + 1).join('.'), _variableToCollectionName));
            if (Array.isArray(current)) {
                const result = current.map((item)=>{
                    if (shouldToRequest(null == item ? void 0 : item[key]) && (null == item ? void 0 : item.id) != null) {
                        if (null == associationField ? void 0 : associationField.target) {
                            const url = "/".concat(collectionName, "/").concat(item.id, "/").concat(key, ":").concat((0, __WEBPACK_EXTERNAL_MODULE__utils_getAction_mjs__.getAction)(associationField.type));
                            if ((0, __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__.hasRequested)(url)) return (0, __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__.getRequested)(url);
                            const result = api.request({
                                url,
                                params: {
                                    appends: null == options ? void 0 : options.appends
                                }
                            }).then((data)=>{
                                (0, __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__.clearRequested)(url);
                                item[key] = data.data.data;
                                return item[key];
                            });
                            (0, __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__.stashRequested)(url, result);
                            return result;
                        }
                    }
                    return null == item ? void 0 : item[key];
                });
                current = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].flatten(await Promise.all(result));
            } else if (shouldToRequest(current[key]) && null != current.id && (null == associationField ? void 0 : associationField.target) && (null == associationField ? void 0 : associationField.type) != 'virtual') {
                const url = "/".concat(collectionName, "/").concat(current.id, "/").concat(key, ":").concat((0, __WEBPACK_EXTERNAL_MODULE__utils_getAction_mjs__.getAction)(associationField.type));
                let data = null;
                if ((0, __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__.hasRequested)(url)) data = await (0, __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__.getRequested)(url);
                else {
                    const waitForData = api.request({
                        url,
                        params: {
                            appends: null == options ? void 0 : options.appends
                        }
                    });
                    (0, __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__.stashRequested)(url, waitForData);
                    data = await waitForData;
                    (0, __WEBPACK_EXTERNAL_MODULE__utils_hasRequested_mjs__.clearRequested)(url);
                }
                if (!(0, __WEBPACK_EXTERNAL_MODULE__tachybase_schema__.raw)(current)[key]) (0, __WEBPACK_EXTERNAL_MODULE__tachybase_schema__.raw)(current)[key] = data.data.data;
                current = (0, __WEBPACK_EXTERNAL_MODULE__tachybase_utils_client__.getValuesByPath)(current, key);
            } else current = (0, __WEBPACK_EXTERNAL_MODULE__tachybase_utils_client__.getValuesByPath)(current, key);
            if (null == associationField ? void 0 : associationField.target) collectionName = associationField.target;
        }
        return compile(__WEBPACK_EXTERNAL_MODULE_lodash__["default"].isFunction(current) ? current() : current);
    }, [
        getCollectionJoinField
    ]);
    const registerVariable = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((variableOption)=>{
        if (!(0, __WEBPACK_EXTERNAL_MODULE__utils_isVariable_mjs__.isVariable)("{{".concat(variableOption.name, "}}"))) throw new Error("VariablesProvider: ".concat(variableOption.name, " is not a valid name"));
        setCtx((prev)=>({
                ...prev,
                [variableOption.name]: variableOption.ctx
            }));
        if (variableOption.collectionName) VariablesProvider_rslib_entry_variableToCollectionName[variableOption.name] = variableOption.collectionName;
    }, [
        setCtx
    ]);
    const getVariable = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((variableName)=>{
        if (!ctxRef.current[variableName]) return null;
        return {
            name: variableName,
            ctx: ctxRef.current[variableName],
            collectionName: VariablesProvider_rslib_entry_variableToCollectionName[variableName]
        };
    }, []);
    const removeVariable = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)((variableName)=>{
        setCtx((prev)=>{
            const next = {
                ...prev
            };
            delete next[variableName];
            return next;
        });
        delete VariablesProvider_rslib_entry_variableToCollectionName[variableName];
    }, [
        setCtx
    ]);
    const parseVariable = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)(async (str, localVariables, options)=>{
        if (!(0, __WEBPACK_EXTERNAL_MODULE__utils_isVariable_mjs__.isVariable)(str)) return str;
        if (localVariables) localVariables = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].isArray(localVariables) ? localVariables : [
            localVariables
        ];
        const path = (0, __WEBPACK_EXTERNAL_MODULE__utils_getPath_mjs__.getPath)(str);
        const value = await getValue(path, localVariables, options);
        return (0, __WEBPACK_EXTERNAL_MODULE__utils_uniq_mjs__.uniq)((0, __WEBPACK_EXTERNAL_MODULE__utils_filterEmptyValues_mjs__.filterEmptyValues)(value));
    }, [
        getValue
    ]);
    const getCollectionField = (0, __WEBPACK_EXTERNAL_MODULE_react__.useCallback)(async (variableString, localVariables)=>{
        if (!(0, __WEBPACK_EXTERNAL_MODULE__utils_isVariable_mjs__.isVariable)(variableString)) throw new Error("VariablesProvider: ".concat(variableString, " is not a variable string"));
        if (localVariables) localVariables = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].isArray(localVariables) ? localVariables : [
            localVariables
        ];
        const path = (0, __WEBPACK_EXTERNAL_MODULE__utils_getPath_mjs__.getPath)(variableString);
        let result = getCollectionJoinField(getFieldPath(path, mergeVariableToCollectionNameWithLocalVariables(VariablesProvider_rslib_entry_variableToCollectionName, localVariables)));
        if (!result && !path.includes('.')) result = {
            target: VariablesProvider_rslib_entry_variableToCollectionName[path]
        };
        return result;
    }, [
        getCollectionJoinField
    ]);
    (0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
        builtinVariables.forEach((variableOption)=>{
            registerVariable(variableOption);
        });
    }, [
        builtinVariables,
        registerVariable
    ]);
    const value = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>({
            ctxRef,
            setCtx,
            parseVariable,
            registerVariable,
            getVariable,
            getCollectionField,
            removeVariable
        }), [
        getCollectionField,
        getVariable,
        parseVariable,
        registerVariable,
        removeVariable,
        setCtx
    ]);
    return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime__.jsx)(VariablesContext.Provider, {
        value: value,
        children: children
    });
};
VariablesProvider.displayName = 'VariablesProvider';
const VariablesProvider_rslib_entry_ = VariablesProvider;
function shouldToRequest(value) {
    let result = false;
    (0, __WEBPACK_EXTERNAL_MODULE__tachybase_schema__.untracked)(()=>{
        if ('[{}]' === JSON.stringify(value) || '{}' === JSON.stringify(value)) {
            result = true;
            return;
        }
        result = __WEBPACK_EXTERNAL_MODULE_lodash__["default"].isEmpty(value);
    });
    return result;
}
function mergeCtxWithLocalVariables(ctx, localVariables) {
    ctx = {
        ...ctx
    };
    null == localVariables || localVariables.forEach((item)=>{
        ctx[item.name] = item.ctx;
    });
    return ctx;
}
function mergeVariableToCollectionNameWithLocalVariables(variableToCollectionName, localVariables) {
    variableToCollectionName = {
        ...variableToCollectionName
    };
    null == localVariables || localVariables.forEach((item)=>{
        if (item.collectionName) variableToCollectionName[item.name] = item.collectionName;
    });
    return variableToCollectionName;
}
export { VariablesContext, VariablesProvider_rslib_entry_ as default };
