import React, { useMemo, useRef, useEffect } from 'react';
import { isArr, isString, isUndefined } from '@pisell/utils';
import { useMemoizedFn } from 'ahooks';
import useEngineContext from "../../../../hooks/useEngineContext";
import VariablesContext from "./VariablesContext";
import { getNestedValue } from "../../dataSourceForm/utils";
import { mergeWith } from "../../../../utils";
import { genComponentValueVariable, genComponentFunctionVariable, getVariableKey } from "./utils";

// 默认合并逻辑 数组直接覆盖
var defaultCustomizer = function defaultCustomizer(objValue, srcValue) {
  if (isArr(srcValue)) {
    return srcValue;
  }
};
var VARIABLE_PATTERN = /{{([^}]+)}}/g;
var VariablesProvider = function VariablesProvider(props) {
  var _context$appHelper;
  var children = props.children,
    variables = props.variables;
  var context = useEngineContext();
  var _ref = (context === null || context === void 0 || (_context$appHelper = context.appHelper) === null || _context$appHelper === void 0 ? void 0 : _context$appHelper.utils) || {},
    getApp = _ref.getApp;

  // 在组件创建时就初始化 URL 参数
  var initialQuery = useMemo(function () {
    var _getApp;
    var 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 && currentLocation.search) {
      var searchParams = new URLSearchParams(currentLocation.search);
      var query = {};
      searchParams.forEach(function (value, key) {
        query[key] = value;
      });
      return query;
    }
    return {};
  }, []);

  // 初始变量中包含 URL 参数
  var variablesRef = useRef(mergeWith(variables, {
    global: {
      value: {
        query: initialQuery
      },
      query: initialQuery
    }
  }, defaultCustomizer));

  // 添加变量变化监听器存储
  var listenersRef = useRef(new Set());

  // 解析并设置 query 参数
  var setQueryVariable = useMemoizedFn(function (search) {
    var searchParams = new URLSearchParams(search);
    var query = {};
    searchParams.forEach(function (value, key) {
      query[key] = value;
    });
    registerVariable({
      global: query
    });
  });
  useEffect(function () {
    var _getApp2;
    var 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(function (location) {
      setQueryVariable(location.search);
    });
    return function () {
      unlisten === null || unlisten === void 0 || unlisten();
    };
  }, []);

  // useEffect(() => {
  //   if (variables) {
  //     variablesRef.current = variables;
  //   }
  // }, [variables]);

  // 注册变量
  var registerVariable = useMemoizedFn(function (value) {
    variablesRef.current = mergeWith(variablesRef.current, value, defaultCustomizer);
    // 变量更新时通知所有监听器
    listenersRef.current.forEach(function (listener) {
      return listener(variablesRef.current, value);
    });
    console.log('注册变量', value, '全部变量', variablesRef.current);
  });

  // 添加变量监听器
  var subscribeVariables = useMemoizedFn(function (listener) {
    listenersRef.current.add(listener);
    return function () {
      listenersRef.current.delete(listener);
    };
  });

  // 注册组件value
  var registerValueVariable = useMemoizedFn(function (componentId, value) {
    var variable = genComponentValueVariable(componentId, value);
    registerVariable === null || registerVariable === void 0 || registerVariable(variable);
  });

  // 注册组件函数
  var registerFunctionVariable = useMemoizedFn(function (componentId, value) {
    var variable = genComponentFunctionVariable(componentId, value);
    registerVariable === null || registerVariable === void 0 || registerVariable(variable);
  });

  // 解析变量
  var parseVariable = useMemoizedFn(function (str) {
    var _str$match;
    var localVariables = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
    if (!isString(str)) {
      return str;
    }
    // 如果整个字符串就是一个变量模式，直接返回变量值
    if (((_str$match = str.match(VARIABLE_PATTERN)) === null || _str$match === void 0 ? void 0 : _str$match[0]) === str) {
      var key = getVariableKey(str);
      if (!key) return str;
      var localValue = getNestedValue(localVariables, key);
      if (!isUndefined(localValue)) {
        return localValue;
      }
      var globalValue = getNestedValue(variablesRef.current, key);
      return isUndefined(globalValue) ? str : globalValue;
    }

    // 否则替换字符串中的所有变量
    return str.replace(VARIABLE_PATTERN, function (match, key) {
      var localValue = getNestedValue(localVariables, key);
      if (!isUndefined(localValue)) {
        return localValue;
      }
      var globalValue = getNestedValue(variablesRef.current, key);
      return isUndefined(globalValue) ? match : globalValue;
    });
  });
  var value = useMemo(function () {
    return {
      variables: variablesRef.current,
      registerVariable: registerVariable,
      parseVariable: parseVariable,
      registerValueVariable: registerValueVariable,
      registerFunctionVariable: registerFunctionVariable,
      subscribeVariables: subscribeVariables
    };
  }, [registerVariable, parseVariable, registerValueVariable, registerFunctionVariable, subscribeVariables]);
  return /*#__PURE__*/React.createElement(VariablesContext.Provider, {
    value: value
  }, children);
};
export default VariablesProvider;