import { cloneDeep, pick } from "lodash";
import { Exception, queenApi } from "queenjs";
import { EditorModule } from "..";
import { ScreenshotCtrl } from "../../controllers/ScreenshotCtrl";
import { CompObject } from "../../controllers/SelectCtrl/compObj";
import { DesignComp } from "../../objects/DesignTemp/DesignComp";
import { ICompKeys, Layout } from "../../typings";

export const editActions = EditorModule.action({

  pickComp(compId: string, selected = true) {
    if (compId == "") {//空的时候,就选择根页面
      compId = "root";
    }
    const selectCardChild = (id:string)=>{
      const paths = this.helper.getCompTrees(id)
        const cardChilds = paths[2];
        if (cardChilds) {
            this.actions.selectObjs([cardChilds.id])
        } else  {
          this.actions.selectObjs([])
          if (id != "root") {
             this.store.setCurrComp(this.store.currStreamCardId);
          }
        }
    }

    if (this.store.currCompId == compId) {
      return;
    }
    this.store.setCurrComp(compId);
    if (selected) {
      selectCardChild(compId);
    }
  },

  
  // 通过点击添加组件到画布
  async clickCompToDesign(compKey: ICompKeys, cb?: (comp: DesignComp) => void) {
    if (!this.store.currStreamCardId) {
      queenApi.messageError("请先选中一个卡片")
      return;
    }
    
    //点击默认都创建一个容器
    //创建容器
    const isCreatCard =
      compKey != "Text" &&
      compKey != "Image" &&
      compKey != "Video" &&
      compKey != "Web3D";

    let yOffset = 0;
    if (
      this.store.currCompId != this.store.currStreamCardId &&
      !isCreatCard &&
      this.store.currCompId != "root"
    ) {
      const bound = this.helper.getCardCompBound(this.store.currCompId);
      yOffset = bound.y + bound.h;
    }

    let currCard = this.store.currStreamCard;
 
    if (isCreatCard) {
      //先创建卡片
      const currCardIndex = this.store.streamCardIds.indexOf(this.store.currStreamCardId) + 1;
      const compId = await this.store.insertDesignContent("Container", currCardIndex);
      currCard = this.helper.findComp(compId) as DesignComp;
    } 

    const compId = await this.store.insertCompContainer(compKey, currCard);
    const addedComp = this.store.compMap[compId];
    addedComp.layout.position = "absolute";

    const currComp  = this.helper.findComp(compId) as DesignComp;
    cb?.(currComp);

    //添加组件到当前选中的组件下面
    let xOffset = this.helper.designSizeToPx(
      375 - (currComp.layout.size?.[0] || 750) / 2
    );
    const obj = new CompObject(currComp)
    obj.worldTransform.translate(xOffset, yOffset);
    currComp.layout.transformMatrix = obj.worldTransform.getMatrixStr();
  
    this.actions.pickComp(compId)
    this.helper.extendStreamCard(currCard.id);

    if (compKey == "Text") {
      this.actions.textFocus(compId, true);
    }
  },

  // 通过拖拽添加组件到画布
  async dragCompToDesign(event: MouseEvent, compKey: ICompKeys) {
    await this.actions.addCompToDesign(compKey);

    const cardPoints = this.helper.getPointOffsetWith(
      event,
      this.store.currStreamCard.$el
    );
    const { currComp } = this.store;
    let selCtrl = this.controls.selectCtrl;
    selCtrl.translate(
      this.helper.designSizeToPx(375 - (currComp.layout.size?.[0] || 750) / 2),
      cardPoints.y
    );

    this.helper.extendStreamCard(this.store.currStreamCardId);

    if (compKey == "Text") {
      this.actions.selectObjs([]);
      this.actions.textFocus(currComp.id, true);
    }
  },
  
   async selectObjs(ids: string[]) {
     this.store.selected = ids;
     this.store.selectId = ids.length > 1 ? (Date.now() + "") : ""
   },

  // 添加组件到画布
  async addCompToDesign(compKey: ICompKeys, index?: number) {
    if (!this.store.currStreamCardId) {
      //必须选中一个streamCard
      return;
    }
    if (compKey == "Container") {
      // index = this.store.streamCardIds.indexOf(this.store.currStreamCardId) + 1;
      const compId = await this.store.insertDesignContent(compKey, index);
      this.actions.pickComp(compId);
      return;
    }

    const compId = await this.store.insertCompContainer(
      compKey,
      this.store.currStreamCard
    );
    const addedComp = this.store.compMap[compId];
    this.actions.setCompPositionFloat(addedComp);

    this.actions.pickComp(compId);
  },

  // 切换当前组件
  // pickComp(compId: string) {
  //   const { store, helper } = this;
  //   // 组合模式下，切换组件
  //   // if (store.currCompId && store.groupModeStatus) {
  //   //   const enableGroupIds = helper
  //   //     .findParentComp(compId)
  //   //     ?.getChildIds() as string[];
  //   //   const comps = helper.getCompTrees(compId);
  //   //   while (comps.length) {
  //   //     const comp = comps.pop() as DesignComp;
  //   //     const index = store.groupIds.indexOf(comp.id);
  //   //     if (index >= 0) {
  //   //       const groupIds = [...store.groupIds];
  //   //       groupIds.splice(index, 1);
  //   //       store.setGroupIds(groupIds);
  //   //     } else if (enableGroupIds.includes(comp.id)) {
  //   //       store.groupIds.push(comp.id);
  //   //       return;
  //   //     }
  //   //   }
  //   //   return;
  //   // }
  //   // let nextCompId = compId;
  //   // if (this.store.isEditPage) {
  //   //   const comps = this.helper.getCompTrees(compId);
  //   //   nextCompId = comps[1].id;
  //   // }
  //   if (this.store.currCompId == compId) {
  //     return;
  //   }
  //   if (this.store.currComp.compKey == "Text") {
  //     this.store.setTextEditingState(false);
  //   }
  //   this.store.setCurrComp(compId);
  //   if (this.store.currCompId == this.store.currStreamCardId) {
  //     this.controls.transferCtrl.destroy();
  //   }
  // },
  // 切换到父组件
  pickParentComp(compId: string) {
    const parentComp = this.helper.findParentComp(compId);
    parentComp && this.store.setCurrComp(parentComp.id);
  },

  // 删除组件
  removeSelectComps() {
    const selected = this.store.selected.slice(0);
    this.actions.selectObjs([]);
    let n = selected.length;
    while( n--) {
      this.actions.removeComp(selected[n]);
    }
  },

  // 删除组件
  removeComp(compId: string) {
    if (this.helper.isCompCanDelete(compId)) {
      if (this.helper.isStreamCard(compId)) {
        this.actions.removeStreamCard(compId);
        return;
      }

      const cardid = this.store.currStreamCardId;
      if (compId === this.store.currCompId) {
        this.store.setCurrComp(this.store.currStreamCardId);
      }
      this.store.deleteComp(compId);

      this.helper.extendStreamCard(cardid);

      this.actions.selectObjs([]);
    }
  },

  async removeStreamCard(compId: string) {
    await queenApi.showConfirm({ title: "删除", content: "确认删除当前内容?" });

    // if (this.store.streamCardIds.length < 2) {
    //   queenApi.messageError("")
    //   return;
    // }
    let nextCard = this.store.currStreamCardId;
    if (compId == this.store.currStreamCardId) {
      const i = this.store.streamCardIds.indexOf(compId);
      nextCard = this.store.streamCardIds[i + 1];
      if (!nextCard) {
        nextCard = this.store.streamCardIds[i - 1];
      }
    }
    this.controls.selectCtrl.selecteObjs([]);

    this.store.deleteComp(compId);

    this.store.setCurrComp(nextCard);
  },
  // 移动组件顺序
  moveComp(selIndex: number, targetIndex: number) {
    if (selIndex === targetIndex) return;
    this.store.moveComp(selIndex, targetIndex);
  },

  // 保存容器为组件
  async saveAsComp(comp: DesignComp) {
    try {
      // 组件封面
      const blob = await new ScreenshotCtrl().snap({
        element: comp.$el,
      });
      const thumbnail = URL.createObjectURL(blob);
      const title = await queenApi.showInput({
        title: "保存到我的组件",
        defaultValue: this.controls.compUICtrl.state.components.get(
          comp.compKey
        )?.name,
      });

      const data = {
        title,
        thumbnail,
        compMap: cloneDeep(this.store.designData.compMap),
      };
      this.helper.clearUnusedComps(data.compMap, comp.id);
      data.compMap.root = data.compMap[comp.id];
      data.compMap.root.id = "root";
      delete data.compMap[comp.id];

      queenApi.showLoading("保存中");
      await this.controls.uploader.uploadBlobs(data);
      await this.https.createComp(data);
      queenApi.messageSuccess("保存成功");
    } catch (error: any) {
      throw Exception.error(error.toString());
    } finally {
      queenApi.hideLoading();
    }
  },

  // 保存项目
  async saveDesign() {
    try {
      // 清除无用组件
      this.helper.clearUnusedComps(this.store.designData.compMap);
      // 封面截屏
      if (!this.store.designData.thumbnail) {
        await this.actions.updateThumbnailByScreenshot();
      }
      queenApi.showLoading("保存中");
      await this.controls.uploader.uploadBlobs(this.store.designData);
      await this.https[this.store.isEditPage ? "saveDesign" : "saveComp"](
        this.store.designData
      );
      queenApi.messageSuccess("保存成功");
    } catch (error: any) {
      throw Exception.error(error.toString());
    } finally {
      queenApi.hideLoading();
    }
  },

  // 截屏保存封面
  async updateThumbnailByScreenshot(autoSave?: boolean) {
    try {
      const rootComp = this.helper.findRootComp();
      if (!rootComp) return;
      queenApi.showLoading("截屏中");
      const blob = await new ScreenshotCtrl().snap({
        element: rootComp.$el,
        ratio: this.store.isEditComp ? 0 : 1,
      });
      const thumbnail = URL.createObjectURL(blob);
      this.store.setDesignThumbnail(thumbnail);

      if (autoSave) {
        await this.controls.uploader.uploadBlobs(this.store.designData);
        await this.https[this.store.isEditPage ? "saveDesign" : "saveComp"](
          pick(this.store.designData, ["_id", "thumbnail"])
        );
        queenApi.messageSuccess("保存成功");
      }
    } catch (error: any) {
      throw Exception.error(error.toString());
    } finally {
      queenApi.hideLoading();
    }
  },

  // 设置组件变换
  setCompTransform(comp: DesignComp, transform: Layout["transform"]) {
    if (!comp) return;

    comp.layout.transform = transform;
    console.log(comp);
  },

  // 设置组件变换
  setCompTransformMatrix(comp: DesignComp, transformMatrix: string) {
    if (!comp) return;

    comp.layout.transformMatrix = transformMatrix;
  },

  // 设置组件浮动
  setCompPositionFloat(comp: DesignComp) {
    comp.layout.position = "absolute";
  },

  // 设置组件浮动
  setCompPosition(comp: DesignComp) {
    comp.layout.position =
      comp.layout.position === "absolute" ? undefined : "absolute";
  },
  // 设置组件显示隐藏
  setCompVisible(comp: DesignComp) {
    comp.layout.visible = comp.layout.visible === false ? true : false;
  },
  // 清除组件变换
  clearCompTransform(comp: DesignComp) {
    comp.layout.margin = "";
    comp.layout.transform = undefined;
  },
  // 设置组件锁定状态
  setCompLock(comp: DesignComp) {
    console.log(comp);
  },
  // 设置组件层级
  setCompLayer(comp: DesignComp, offset: number) {
    comp.layout.zIndex = Math.min(
      Math.max((comp.layout.zIndex || 0) + offset, 0),
      99
    );
  },
  // 宽度铺满
  fullCompWidth(comp: DesignComp) {
    comp.layout.size || (comp.layout.size = []);
    comp.layout.size[0] = 750;
  },
  //
  setCompAlign(comp: DesignComp, align: string) {
    comp.layout.alignSelf = align;
    if (comp.layout.transform?.x) {
      comp.layout.transform.x = 0;
    }
  },

  // 开启组合模式
  enableGroupMode() {
    this.store.setGroupIds(
      this.store.currCompId ? [this.store.currCompId] : []
    );
    this.store.setGroupMode(true);
  },
  // 关闭组合模式
  async disableGroupMode() {
    const groupId = await this.controls.transferCtrl.groupCtrl.combineGroup();
    if (groupId) {
      this.store.setCurrComp(groupId);
    }
    this.store.setGroupIds([]);
    this.store.setGroupMode(false);
  },
  // 取消打组
  cancelGroupComps(groupComp: DesignComp) {
    this.controls.transferCtrl.groupCtrl.cancelGroup(groupComp);
    this.store.setCurrComp(groupComp.children.default?.[0] as string);
  },
});
