import { Component, reactive } from "vue";
import { DrawItem } from "../components";
import { installGlobalVar } from "../hook/use-global-vars";
import { useStoreRaw } from "./store";
import { useHistory } from "../hook/use-history";
import { round } from "@/utils/shared";

// 放置重复放入历史，我们把小数保留5位小数
const b = 3
const normalStore = (store: any) => {
  const norStore = Array.isArray(store) ? [...store] : {...store}
  for (const key in norStore) {
    const val = norStore[key]
    if (typeof val === 'number') {
      norStore[key] = round(val, b)
    } else if (typeof val === 'object') {
      norStore[key] = normalStore(val)
    } else {
      norStore[key] = val
    }
  }
  return norStore
}

export const useStore = installGlobalVar(() => {
  const history = useHistory();
  const store = useStoreRaw();

  const trackActions = [
    "setStore",
    "repStore",
    "addItem",
    "delItem",
    "setItem",
  ];
  store.$onAction(({ args, name, after, store }) => {
    if (!trackActions.includes(name)) return;
    const isInit = name === "setStore";
    after(() => {
      if (isInit) {
        history.setInit(JSON.stringify(store.data));
      } else {
        history.push(JSON.stringify(store.data));
      }
    });
  });
  return store;
}, Symbol("store"));

export const useStoreRenderProcessors = installGlobalVar(() => {
  type Processor<T extends DrawItem = DrawItem> = (data: T) => Component;
  const processors = reactive(new Map<Processor, DrawItem["id"][]>());
  const store = useStore();

  const result = {
    register<T extends DrawItem>(
      processor: Processor<T>,
      ids: DrawItem["id"][] = []
    ) {
      processors.set(processor as any, ids);
      return reactive(ids);
    },
    itemHasRegistor(id: DrawItem["id"]) {
      for (const ids of processors.values()) {
        if (ids.includes(id)) return true;
      }
      return false;
    },
    getProcessor(id: DrawItem["id"]) {
      for (const [p, ids] of processors.entries()) {
        if (ids.includes(id)) {
          return p;
        }
      }
    },
    renderer(id: DrawItem["id"]) {
      const processor = result.getProcessor(id);
      const item = store.items.find((item) => item.id === id);
      return processor && item && processor(item);
    },
  };
  return result;
}, Symbol("storeRenderProcessors"));
