import { mergeWith } from "../../../../utils/mergeWith.js";
import useEngineContext from "../../../../hooks/useEngineContext.js";
import VariablesContext from "./VariablesContext.js";
import { getNestedValue } from "../../dataSourceForm/utils.js";
import { genComponentFunctionVariable, genComponentValueVariable, getVariableKey } from "./utils.js";
import React, { useEffect, useMemo, useRef } from "react";
import { isArr, isString, isUndefined } from "@pisell/utils";
import { useMemoizedFn } from "ahooks";
//#region src/components/dataSourceComponents/provider/variables/VariablesProvider.tsx
const defaultCustomizer = (objValue, srcValue) => {
	if (isArr(srcValue)) return srcValue;
};
const VARIABLE_PATTERN = /{{([^}]+)}}/g;
const VariablesProvider = (props) => {
	var _context$engine, _context$appHelper;
	const { children, variables, config } = props;
	const context = useEngineContext();
	const disabledHistoryListener = config !== null && config !== void 0 ? config : context === null || context === void 0 || (_context$engine = context.engine) === null || _context$engine === void 0 || (_context$engine = _context$engine.props) === null || _context$engine === void 0 || (_context$engine = _context$engine.variablesConfig) === null || _context$engine === void 0 ? void 0 : _context$engine.disabledHistoryListener;
	const { getApp } = (context === null || context === void 0 || (_context$appHelper = context.appHelper) === null || _context$appHelper === void 0 ? void 0 : _context$appHelper.utils) || {};
	const initialQuery = useMemo(() => {
		var _getApp;
		if (disabledHistoryListener) return {};
		const currentLocation = getApp === null || getApp === void 0 || (_getApp = getApp()) === null || _getApp === void 0 || (_getApp = _getApp.history) === null || _getApp === void 0 || (_getApp = _getApp.instance) === null || _getApp === void 0 ? void 0 : _getApp.location;
		if (currentLocation === null || currentLocation === void 0 ? void 0 : currentLocation.search) {
			const searchParams = new URLSearchParams(currentLocation.search);
			const query = {};
			searchParams.forEach((value, key) => {
				query[key] = value;
			});
			return query;
		}
		return {};
	}, [disabledHistoryListener]);
	const variablesRef = useRef(disabledHistoryListener ? variables || {} : mergeWith(variables, { global: {
		value: { query: initialQuery },
		query: initialQuery
	} }, defaultCustomizer));
	const listenersRef = useRef(/* @__PURE__ */ new Set());
	const setQueryVariable = useMemoizedFn((search) => {
		if (disabledHistoryListener) return;
		const searchParams = new URLSearchParams(search);
		const query = {};
		searchParams.forEach((value, key) => {
			query[key] = value;
		});
		registerVariable({ global: query });
	});
	useEffect(() => {
		var _getApp2;
		if (disabledHistoryListener) return;
		const unlisten = getApp === null || getApp === void 0 || (_getApp2 = getApp()) === null || _getApp2 === void 0 || (_getApp2 = _getApp2.history) === null || _getApp2 === void 0 || (_getApp2 = _getApp2.instance) === null || _getApp2 === void 0 ? void 0 : _getApp2.listen((location) => {
			setQueryVariable(location.search);
		});
		return () => {
			unlisten === null || unlisten === void 0 || unlisten();
		};
	}, [disabledHistoryListener]);
	const registerVariable = useMemoizedFn((value) => {
		variablesRef.current = mergeWith(variablesRef.current, value, defaultCustomizer);
		listenersRef.current.forEach((listener) => listener(variablesRef.current, value));
		console.log("注册变量", value, "全部变量", variablesRef.current);
	});
	const subscribeVariables = useMemoizedFn((listener) => {
		listenersRef.current.add(listener);
		return () => {
			listenersRef.current.delete(listener);
		};
	});
	const registerValueVariable = useMemoizedFn((componentId, value) => {
		const variable = genComponentValueVariable(componentId, value);
		registerVariable === null || registerVariable === void 0 || registerVariable(variable);
	});
	const registerFunctionVariable = useMemoizedFn((componentId, value) => {
		const variable = genComponentFunctionVariable(componentId, value);
		registerVariable === null || registerVariable === void 0 || registerVariable(variable);
	});
	const parseVariable = useMemoizedFn((str, localVariables = {}) => {
		var _str$match;
		if (!isString(str)) return str;
		if (((_str$match = str.match(VARIABLE_PATTERN)) === null || _str$match === void 0 ? void 0 : _str$match[0]) === str) {
			const key = getVariableKey(str);
			if (!key) return str;
			const localValue = getNestedValue(localVariables, key);
			if (!isUndefined(localValue)) return localValue;
			const globalValue = getNestedValue(variablesRef.current, key);
			return isUndefined(globalValue) ? str : globalValue;
		}
		return str.replace(VARIABLE_PATTERN, (match, key) => {
			const localValue = getNestedValue(localVariables, key);
			if (!isUndefined(localValue)) return localValue;
			const globalValue = getNestedValue(variablesRef.current, key);
			return isUndefined(globalValue) ? match : globalValue;
		});
	});
	const value = useMemo(() => ({
		variables: variablesRef.current,
		registerVariable,
		parseVariable,
		registerValueVariable,
		registerFunctionVariable,
		subscribeVariables
	}), [
		registerVariable,
		parseVariable,
		registerValueVariable,
		registerFunctionVariable,
		subscribeVariables
	]);
	return /* @__PURE__ */ React.createElement(VariablesContext.Provider, { value }, children);
};
//#endregion
export { VariablesProvider as default };
