import { useChartEditStore } from '@/store/modules/chart/chartEditStore';
import { useChartHistoryStore } from '@/store/modules/chart/chartHistoryStore';
import { useChartLayoutStore } from '@/store/modules/chart/chartLayoutStore';
import { merge } from 'lodash-es';
import { getUUID, createComponent, fetchChartComponent, fetchConfigComponent } from '../utils/chart-util';

/**
 * * 画布-版本升级对旧数据无法兼容的补丁
 * @param object
 */
const canvasVersionUpdatePolyfill = object => {
  return object;
};

/**
 * * 组件-版本升级对旧数据无法兼容的补丁
 * @param newObject
 * @param sources
 */
const componentVersionUpdatePolyfill = (newObject, sources) => {
  try {
    // 判断是否是组件
    if (sources.id) {
      // 处理事件补丁
      const hasVnodeBeforeMount = 'vnodeBeforeMount' in sources.events;
      const hasVnodeMounted = 'vnodeMounted' in sources.events;

      if (hasVnodeBeforeMount) {
        newObject.events.advancedEvents.vnodeBeforeMount = sources?.events.vnodeBeforeMount;
      }
      if (hasVnodeMounted) {
        newObject.events.advancedEvents.vnodeMounted = sources?.events.vnodeMounted;
      }
      if (hasVnodeBeforeMount || hasVnodeMounted) {
        sources.events = {
          baseEvent: {
            click: undefined,
            dblclick: undefined,
            mouseenter: undefined,
            mouseleave: undefined
          },
          advancedEvents: {
            vnodeMounted: undefined,
            vnodeBeforeMount: undefined
          },
          interactEvents: []
        };
      }
      return newObject;
    }
  } catch (error) {
    return newObject;
  }
};

/**
 * * 合并处理
 * @param newObject 新的模板数据
 * @param sources 新拿到的数据
 * @returns object
 */
const componentMerge = (newObject, sources, notComponent = false) => {
  // 处理组件补丁
  componentVersionUpdatePolyfill(newObject, sources);

  // 非组件不处理
  if (notComponent) return merge(newObject, sources);
  // 组件排除 newObject
  const option = sources.option;
  if (!option) return merge(newObject, sources);

  // 为 undefined 的 sources 来源对象属性将被跳过详见 https://www.lodashjs.com/docs/lodash.merge
  sources.option = undefined;
  if (option) {
    return {
      ...merge(newObject, sources),
      option: option
    };
  }
};

// 请求处理
export const useSync = () => {
  const chartEditStore = useChartEditStore();
  const chartHistoryStore = useChartHistoryStore();
  const chartLayoutStore = useChartLayoutStore();
  
  /**
   * * 组件动态注册
   * @param projectData 项目数据
   * @param isReplace 是否替换数据
   * @returns
   */
  const updateComponent = async (projectData, isReplace = false, changeId = false) => {
    if (isReplace) {
      // 清除列表
      chartEditStore.componentList = [];
      // 清除历史记录
      chartHistoryStore.clearBackStack();
      chartHistoryStore.clearForwardStack();
    }
    // 画布补丁处理
    projectData.editCanvasConfig = canvasVersionUpdatePolyfill(projectData.editCanvasConfig);

    // 列表组件注册
    projectData.componentList.forEach(async e => {
      const intComponent = target => {
        if (!window['$vue'].component(target.chartConfig.chartKey)) {
          window['$vue'].component(target.chartConfig.chartKey, fetchChartComponent(target.chartConfig));
          if (!window['$vue'].component(target.chartConfig.conKey)) {
            window['$vue'].component(target.chartConfig.conKey, fetchConfigComponent(target.chartConfig));
          }
        }
      };

      if (e.isGroup) {
        e.groupList.forEach(groupItem => {
          intComponent(groupItem);
        });
      } else {
        intComponent(e);
      }
    });

    // 创建函数-重新创建是为了处理类种方法消失的问题
    const create = async (_componentInstance, callBack) => {
      // 补充 class 上的方法
      let newComponent = await createComponent(_componentInstance.chartConfig);
      if (_componentInstance.chartConfig.redirectComponent) {
        _componentInstance.chartConfig.dataset && (newComponent.option.dataset = _componentInstance.chartConfig.dataset);
        newComponent.chartConfig.title = _componentInstance.chartConfig.title;
        newComponent.chartConfig.chartFrame = _componentInstance.chartConfig.chartFrame;
      }
      if (callBack) {
        if (changeId) {
          callBack(componentMerge(newComponent, { ..._componentInstance, id: getUUID() }));
        } else {
          callBack(componentMerge(newComponent, _componentInstance));
        }
      } else {
        if (changeId) {
          chartEditStore.addComponentList(componentMerge(newComponent, { ..._componentInstance, id: getUUID() }), false, true);
        } else {
          chartEditStore.addComponentList(componentMerge(newComponent, _componentInstance), false, true);
        }
      }
    };

    // 数据赋值
    for (const key in projectData) {
      // 组件
      if (key === 'componentList') {
        let loadIndex = 0;
        const listLength = projectData[key].length;
        for (const comItem of projectData[key]) {
          // 设置加载数量
          let percentage = parseInt((parseFloat(`${++loadIndex / listLength}`) * 100).toString());
          chartLayoutStore.setItemUnHandle('percentage', percentage);
          // 判断类型
          if (comItem.isGroup) {
            // 创建分组
            let groupClass = new PublicGroupConfigClass();
            if (changeId) {
              groupClass = componentMerge(groupClass, { ...comItem, id: getUUID() });
            } else {
              groupClass = componentMerge(groupClass, comItem);
            }

            // 异步注册子应用
            const targetList = [];
            for (const groupItem of comItem.groupList) {
              await create(groupItem, e => {
                targetList.push(e);
              });
            }
            groupClass.groupList = targetList;

            // 分组插入到列表
            chartEditStore.addComponentList(groupClass, false, true);
          } else {
            await create(comItem);
          }
          if (percentage === 100) {
            // 清除历史记录
            chartHistoryStore.clearBackStack();
            chartHistoryStore.clearForwardStack();
          }
        }
      } else if (key === 'editCanvasConfig' || key === 'requestGlobalConfig') {
        componentMerge(chartEditStore[key], projectData[key], true);
      }
    }

    // 清除数量
    chartLayoutStore.setItemUnHandle('percentage', 0);
  };

  return {
    updateComponent
  };
};
