import { nanoid } from "nanoid";
import { EditorModule } from "..";
import { DesignTemp } from "../../objects/DesignTemp";
import { DesignComp } from "../../objects/DesignTemp/DesignComp";
import { EditorMode, ICompKeys } from "../../typings";
import { eachValuesAndPathsDeep } from "@/utils";
import { set } from "lodash";

export const store = EditorModule.store({
  state: () => ({
    textEditingState: false,
    mode: "editPage" as EditorMode,
    isWk: false, //作品集内作品
    currCompId: "root",
    currStreamCardId: "",
    designData: new DesignTemp(),

    groupModeStatus: false,
    groupIds: [] as string[],
    compPids: {} as Record<string, string>,

    selected: [] as string[], //选中的组件
    selectId: "", //选中的id唯一标识一次选中
    croppImage: "", //裁剪图片
    compEditMode: false, //组件编辑模式
    compEditReslut: 0, // -1 取消, 1 确定
    lastSelected: "", //最后上传

    shortPage: {
      index: 0,
      offset: 0,
      isMoving: false,
    },
  }),
  getters: {
    rootPage(state) {
      return state.designData.compMap["root"] as DesignComp;
    },
    isEditMode(): boolean {
      return !this.store.isPreview && !this.store.isDisplay;
    },
    isEditPage(state) {
      return state.mode === "editPage";
    },
    isEditComp(state) {
      return state.mode === "editComp";
    },
    isPreview(state) {
      return state.mode === "preview";
    },
    isDisplay(state) {
      return state.mode === "display";
    },
    compMap(state) {
      return state.designData.compMap;
    },
    currComp(state) {
      return state.designData.compMap[state.currCompId];
    },
    currStreamCard(state) {
      return state.designData.compMap[state.currStreamCardId];
    },
    pageCompIds(state): string[] {
      return state.designData.compMap.root?.children.default || [];
    },
    streamCardIds(state): string[] {
      return state.designData.compMap.root?.children.default || [];
    },
    previewImageList(state) {
      const res: string[] = [];

      function deepChild(item: any) {
        if (typeof item == "string") {
          const comp = state.designData.compMap[item];
          if (comp.compKey === "Image") {
            res.push(comp.value.url);
          } else if (comp.children) {
            deepChild(comp.children);
          }
        } else if (item instanceof Object) {
          if (item instanceof Array) {
            item.forEach((d) => {
              deepChild(d);
            });
          } else {
            Object.values(item).forEach((d) => {
              deepChild(d);
            });
          }
        }
      }
      deepChild(state.designData.compMap["root"].children);

      return res;
    },
  },
  actions: {
    setCompData(id: string, data: any) {
      this.store.designData.compMap[id] = data;
    },
    setMode(v: EditorMode) {
      this.store.mode = v;
    },
    setWk(v: boolean) {
      this.store.isWk = v;
    },
    setGroupMode(status: boolean) {
      this.store.groupModeStatus = status;
    },
    setGroupIds(ids: string[]) {
      this.store.groupIds = ids;
    },
    setDesignData(data: Partial<DesignTemp>) {
      this.store.designData = new DesignTemp(data);
    },
    setCompPid(compId: string, pid: string) {
      this.store.compPids[compId] = pid;
    },
    async insertDesignContent(compKey: ICompKeys, index?: number) {
      const compId = await this.controls.compUICtrl.createCompId(compKey);
      const childIds = [...this.store.pageCompIds];

      index === undefined && (index = childIds.length);
      childIds.splice(index, 0, compId);
      this.store.designData.compMap.root.children.default = childIds;
      return compId;
    },

    async insertCompContainer(compKey: ICompKeys, container: DesignComp) {
      const compId = this.controls.compUICtrl.createCompId(compKey);
      const childIds = [...(container.children.default || [])];
      childIds.push(compId);
      container.children.default = childIds;
      return compId;
    },

    addUserCard(detail: any) {
      const { compMap } = this.store.designData;
      const idMap = new Map<string, string>();
      const nextCompMap: Record<string, DesignComp> = {};
      Object.entries(detail.compMap as Record<string, DesignComp>).forEach(
        ([key, comp]) => {
          if (key === "root") {
            idMap.set(key, nanoid());
            comp.title = detail.title;
            comp.thumbnail = detail.thumbnail;
          }
          const id = idMap.get(key) || nanoid();
          idMap.set(key, id);
          comp.id = id;
          eachValuesAndPathsDeep(
            comp.children,
            (v) => typeof v === "string",
            (v, paths) => {
              const id = idMap.get(v) || nanoid();
              idMap.set(v, id);
              set(comp.children, paths, id);
            }
          );
          nextCompMap[id] = new DesignComp(comp);
        }
      );
      Object.assign(compMap, nextCompMap);
      return nextCompMap[idMap.get("root") as string];
    },

    setCurrComp(compId: string) {
      this.store.currCompId = compId;
      const comps = this.helper.getCompTrees(compId);

      if (compId == "root") {
        return;
      }
      let cardId = comps[1]?.id || "";
      if (this.helper.isStreamCard(compId)) {
        cardId = compId;
      }
      this.store.currStreamCardId = cardId;
    },

    deleteComp(compId: string) {
      const parentComp = this.helper.findParentComp(compId);
      let deleteOK = false;
      if (parentComp) {
        const ids = [...(parentComp.children.default || [])];
        // 只能删除children.default中的组件
        if (ids?.includes(compId)) {
          const index = ids.findIndex((id) => id === compId);
          if (index >= 0) {
            ids.splice(index, 1);
            parentComp.children.default = ids;
            deleteOK = true;
          }
        }
      }

      if (deleteOK) {
        delete this.store.compPids[compId];
      }
    },
    moveComp(selIndex: number, targetIndex: number) {
      const pageCompIds = [...this.store.pageCompIds];
      const [selComp] = pageCompIds.splice(selIndex, 1);
      pageCompIds.splice(targetIndex, 0, selComp);
      this.store.designData.compMap.root.children.default = pageCompIds;
    },
    setTextEditingState(state: boolean) {
      this.store.textEditingState = state;
    },
    setDesignThumbnail(url: string) {
      this.store.designData.thumbnail = url;
    },
  },
});