import { EditorModule } from "..";
import { CompObject } from "../../controllers/SelectCtrl/compObj";
import { DesignComp } from "../../objects/DesignTemp/DesignComp";
import { createCompStyle } from "../../objects/DesignTemp/creates/createCompStyle";
import { Layout } from "../../typings";

export const helpers = EditorModule.helper({
  designToNaturalSize(value: number) {
    // return parseFloat((value / 100).toFixed(2)) + "rem";
    return value / 2 + "px";
  },
  pxToDesignSize(value: number) {
    return value * 2;
  },
  designSizeToPx(value: number) {
    return value / 2.0;
  },
  
  findComp(compId: string) {
    const { compMap } = this.store.designData;
    const comp = compMap[compId];
    if (comp) return comp;
  },
  isStreamCard(compId: string) {
    return this.store.streamCardIds.indexOf(compId) > -1;
  },
  isGroupComp(compId: string) {
    return this.store.groupIds.indexOf(compId) > -1;
  },
  isGroupCompChild(compId: string) {
    const comps = this.helper.getCompTrees(compId);
    comps.pop();
    while (comps.length) {
      const comp = comps.pop() as DesignComp;
      if (comp.compKey === "Group") {
        return true;
      }
    }
    return false;
  },
  isStreamCardChild(compId:string) {
    if (compId == "root" || this.helper.isStreamCard(compId) ) {
      return false;
    }
    const cards = this.store.streamCardIds
    let n = cards.length;
    const compMap = this.store.designData.compMap;
    while(n--) {
       const childs = compMap[cards[n]].children.default || [];
       if (childs.indexOf(compId) > -1 ) return true;
    }
    return false;
  },

  findParentComp(compId: string): DesignComp | undefined {
    const comp = this.helper.findComp(compId);
    if (comp) return this.helper.findComp(this.store.compPids[compId]);
  },
  findRootComp(): DesignComp | undefined {
    return this.store.designData.compMap["root"];
  },
  getCompTrees(compId: string) {
    const comps: DesignComp[] = [];
    const getParentComp = (compId: string) => {
      const comp = this.helper.findComp(compId);
      if (comp) {
        comps.unshift(comp);
        getParentComp(this.store.compPids[comp.id]);
      }
    };
    getParentComp(compId);
    return comps;
  },
  createStyle(layout: Partial<Layout> & {size:any[]}) {
    return createCompStyle(this, layout);
  },
  isCurrComp(compId: string) {
    return this.store.currCompId === compId;
  },
  isCustomChildComp(comp: DesignComp): boolean {
    const parentComp = this.helper.findParentComp(comp.id);
    if (!parentComp) return false;
    const i =
      parentComp.children.default?.findIndex((d) => d === comp.id) ?? -1;
    return i >= 0;
  },
  isCompCanDelete(compId: string): boolean {
    const comp = this.helper.findComp(compId);
    if (!comp || !this.helper.isCustomChildComp(comp)) return false;
    if (comp.compKey == "Container" && this.store.streamCardIds.length == 1)
      return false;
    return true;
    // if (this.store.isEditComp) return true;
    // return this.store.pageCompIds.includes(compId);
  },
  isShowSaveComp(comp: DesignComp): boolean {
    // if (!comp.children?.default || comp.children?.default?.length == 0)
    //   return false;
    if (!this.helper.isCustomChildComp(comp)) return false;
    return true;
  },

  clearUnusedComps(compMap: Record<string, DesignComp>, rootId = "root") {
    const used = new Set<string>();
    const getUsedIds = (ids: string[]) => {
      ids.forEach((id) => {
        const comp = compMap[id];
        if (!comp) return;
        used.add(id);
        getUsedIds(comp.getChildIds());
      });
      return used;
    };
    getUsedIds([rootId]);
    Object.keys(compMap).forEach((compId) => {
      if (!used.has(compId)) {
        delete compMap[compId];
      }
    });
  },
  getPointOffsetWith(e: MouseEvent, dom: HTMLElement) {
    const domRect = dom.getBoundingClientRect();
    return {
      x: e.clientX - domRect.left,
      y: e.clientY - domRect.top,
    };
  },

  getCardCompBound(compId :string) {
    const compMap = this.store.designData.compMap
    const c = compMap[compId];
    const obj = new CompObject(c);
    const bound = obj.getBox();

    return bound;
  },

  extendStreamCard(streamCardId: string) {
    if (!streamCardId) return;

    const compMap = this.store.designData.compMap;
    const card = compMap[streamCardId];
    const childs = card.children.default || [];
    let maxH = 0,
      n = childs.length;
    while (n--) {
      const c = childs[n];
      const aabb = this.helper.getCardCompBound(c);
      maxH = Math.max(maxH, aabb.y + aabb.h);
    }
    maxH = this.helper.pxToDesignSize(maxH);

    if (childs.length < 1 ) {
      maxH = 200
    }
    card.setH(maxH);
  },
});
