import { useCtx } from "@/comm/ctx";
import { pick } from "lodash";
import { Exception, queenApi } from "queenjs";
import { EditorModule } from "..";
import { ScreenshotCtrl } from "../../controllers/ScreenshotCtrl";
import { CompObject } from "../../controllers/SelectCtrl/compObj";
import { Matrix } from "../../controllers/SelectCtrl/matrix";
import { DesignComp } from "../../objects/DesignTemp/DesignComp";
import { cloneObj, createObj, history } from "../../objects/DesignTemp/factory";
import { ICompKeys } from "../../typings";

const ctrlState = {
  selected: [] as string[],
  type: 0, // 1 ctrlc 2 ctrlx 3 ctrlq
  cardId: "", //当前的卡片Id
  screenId: "", //屏幕Id
  selWidth: 0,
  selX: 0,
  selY: 0,
};

export const editActions = EditorModule.action({
  async addImageToDesign(url) {
    queenApi.showLoading("图片加载中");
    const maxW = this.controls.screenCtrl.getCurrScreenWidth();
    try {
      const temImg: any = await this.helper.loadImage(url);
      const ratio = temImg.width / temImg.height;
      const W = temImg.width > maxW ? maxW : temImg.width;
      const H = W / ratio;
      const page = this.controls.pageCtrl;
      await this.actions.clickCompToDesign("Image", (comp) => {
        comp.setSize(W, H);
        comp.value.url = url;
        page.saveAssetsLocal(comp);
      });
    } catch (e) {
      queenApi.hideLoading();
      queenApi.messageError("图片加载失败");
      return;
    }
    queenApi.hideLoading();
  },
  async dragAddImageToDesign(e: MouseEvent, url) {
    const page = this.controls.pageCtrl;
    if (!page.currStreamCardId) {
      queenApi.messageError("请先选中一个卡片");
      return;
    }

    queenApi.showLoading("图片加载中");
    const maxW = this.controls.screenCtrl.getCurrScreenWidth();
    try {
      const temImg: any = await this.helper.loadImage(url);
      const ratio = temImg.width / temImg.height;
      const W = temImg.width > maxW ? maxW : temImg.width;
      const H = W / ratio;

      const currCard = page.currStreamCard;
      const currComp = createObj({ compKey: "Image" }, false);
      currComp.setSize(W, H);
      currComp.value.url = url;
      page.designData.compMap[currComp.id] = currComp;
      page.saveAssetsLocal(page.designData.compMap[currComp.id]);
      // page.setCompPid(currComp.id, page.currStreamCardId);
      const childIds = [...page.currStreamCard.children.default];
      childIds.push(currComp.id);
      currCard.children.setDefault(childIds);
      this.controls.editorCtrl.clickPickComp(currComp.id);
      this.actions.centerLastComp(e);
    } catch (e) {
      queenApi.hideLoading();
      queenApi.messageError("图片加载失败");
      return;
    }
    queenApi.hideLoading();
    history.submit();
  },

  async dragAddVideoToDesign(e: MouseEvent, url) {
    const page = this.controls.pageCtrl;
    if (!page.currStreamCardId) {
      queenApi.messageError("请先选中一个卡片");
      return;
    }

    queenApi.showLoading("视频加载中");
    // const maxW = this.controls.screenCtrl.getCurrScreenWidth();
    try {
      // const temImg :any = await this.helper.loadImage(url);
      // const ratio = temImg.width / temImg.height;
      // const W = temImg.width > maxW ? maxW : temImg.width;
      // const H = W / ratio;

      const currCard = page.currStreamCard;
      const currComp = createObj({ compKey: "Video" }, false);
      // currComp.setSize(W,  H );
      currComp.value.url = url;
      page.designData.compMap[currComp.id] = currComp;
      page.saveAssetsLocal(page.designData.compMap[currComp.id]);
      // page.setCompPid(currComp.id, page.currStreamCardId);
      const childIds = [...page.currStreamCard.children.default];
      childIds.push(currComp.id);
      currCard.children.setDefault(childIds);
      this.controls.editorCtrl.clickPickComp(currComp.id);
      this.actions.centerLastComp(e);
    } catch (e) {
      queenApi.hideLoading();
      queenApi.messageError("图片加载失败");
      return;
    }
    queenApi.hideLoading();
    history.submit();
  },

  // 通过点击添加组件到画布
  async clickCompToDesign(
    compKey: ICompKeys,
    cb?: (comp: DesignComp) => void,
    history = true
  ) {
    const page = this.controls.pageCtrl;

    if (!page.currStreamCardId) {
      queenApi.messageError("请先选中一个卡片");
      return;
    }

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

    const currComp = createObj({ compKey }, false);
    // debugger
    //@ts-ignore
    const objs: any[] = currComp.children.objs || [];
    if (objs.length > 0) {
      objs.forEach((o) => {
        page.designData.compMap[o.id] = o;
        page.setCompPid(o.id, currComp.id);
      });
    }
    page.designData.compMap[currComp.id] = currComp;
    if (compKey == "Video") {
      page.saveAssetsLocal(page.designData.compMap[currComp.id]);
    }
    page.setCompPid(currComp.id, currCard.id);
    const childIds = [...currCard.children.default];
    childIds.push(currComp.id);
    currCard.children.setDefault(childIds);
    const compId = currComp.id;
    cb?.(currComp);

    const w = this.controls.screenCtrl.getCurrScreenWidth();
    //添加组件到当前选中的组件下面
    let xOffset = this.helper.designSizeToPx(
      w / 2.0 - (currComp.layout.size?.[0] || w) / 2
    );
    const obj = new CompObject(currComp);
    //没有选中组件添加到当前卡片最后
    const children = currCard.children.default || [];
    if (yOffset == 0 && children.length >= 2) {
      const prevCompIndex = children.indexOf(compId) - 1;
      const bound = this.helper.getCardCompBound(children[prevCompIndex]);
      yOffset = bound.y + bound.h;
    }
    obj.worldTransform.translate(xOffset, yOffset);
    currComp.layout.transformMatrix = obj.worldTransform.getMatrixStr();

    this.controls.editorCtrl.clickPickComp(compId);
    this.helper.extendStreamCard(currCard.id);

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

    if (history) this.history.submit();
  },

  // 通过点击添加组件到画布
  async clickCompUserToDesign(id: string, isSys) {
    const page = this.controls.pageCtrl;

    if (!page.currStreamCardId) {
      queenApi.messageError("请先选中一个卡片");
      return;
    }
    const { result } = await this.https.getCompDetail(id, isSys);

    const currCard = page.currStreamCard;
    const comp = page.addUserCard(result);

    const compId = comp.id;
    const childIds = [...(currCard.children.default || [])];
    childIds.push(compId);
    currCard.children.setDefault(childIds);

    page.setCompPid(compId, currCard.id);

    this.actions.initAddedCompPos(this.store.currCompId, compId, currCard.id);

    this.controls.editorCtrl.clickPickComp(compId);

    history.submit();
  },

  initAddedCompPos(currId: string, addedId: string, cardId: string) {
    let yOffset = 0;
    if (currId != this.controls.pageCtrl.currStreamCardId && currId != "root") {
      const paths = this.helper.getCompTrees(currId);
      const bound = this.helper.getCardCompBound(paths[2].id);
      yOffset = bound.y + bound.h;
    }

    const currComp = this.helper.findComp(addedId) as DesignComp;
    const w = this.controls.screenCtrl.getCurrScreenWidth();

    //添加组件到当前选中的组件下面
    let xOffset = this.helper.designSizeToPx(
      w / 2.0 - (currComp.layout.size?.[0] || w) / 2
    );
    const obj = new CompObject(currComp);

    const currCard = this.helper.findComp(cardId) as DesignComp;

    //没有选中组件添加到当前卡片最后
    const children = currCard.children.default || [];
    if (yOffset == 0 && children.length >= 2) {
      const prevCompIndex = children.indexOf(addedId) - 1;
      const bound = this.helper.getCardCompBound(children[prevCompIndex]);
      yOffset = bound.y + bound.h;
    }
    obj.worldTransform.translate(xOffset, yOffset);
    currComp.layout.transformMatrix = obj.worldTransform.getMatrixStr();
    this.helper.extendStreamCard(currCard.id);
    this.controls.cropCtrl.close();
  },

  // 通过拖拽添加组件到画布
  async dragCompToDesign(event: MouseEvent, compKey: string, data: any) {
    const page = this.controls.pageCtrl;

    if (compKey == "CompCard") {
      const { result } = await this.https.getCompDetail(data.id, data.isSys);
      const comp = page.addUserCard(result);

      const currCard = page.currStreamCard;
      const compId = comp.id;
      const childIds = [...(currCard.children.default || [])];
      childIds.push(compId);
      currCard.children.setDefault(childIds);

      page.setCompPid(compId, currCard.id);

      this.controls.editorCtrl.clickPickComp(compId);
    } else {
      await this.actions.addCompToDesign(compKey as any);
    }

    setTimeout(() => {
      this.actions.centerLastComp(event);
      const currComp = this.controls.pageCtrl.currComp;
      if (compKey == "Text") {
        this.actions.textFocus(currComp.id, true);
      }

      history.submit();
    }, 100);
  },

  centerLastComp(event:MouseEvent) {
    const currCardDom = this.controls.pageCtrl.currStreamCard.$el;
    const cardPoints = this.helper.getPointOffsetWith(event, currCardDom);
    const page = this.controls.pageCtrl;
    let selCtrl = this.controls.selectCtrl;

    const w = this.controls.screenCtrl.getCurrScreenWidth();

    selCtrl.translate(
      this.helper.designSizeToPx(
        w / 2.0 - (page.currComp.layout.size?.[0] || w) / 2
      ),
      cardPoints.y
    );
    this.helper.extendStreamCard(page.state.currStreamCardId);
    this.controls.cropCtrl.close();
  },

  // 添加组件到画布
  async addCompToDesign(compKey: ICompKeys, index?: number) {
    const page = this.controls.pageCtrl;
    if (!page.state.currStreamCardId) {
      //必须选中一个streamCard
      return;
    }
    if (compKey == "Container") {
      const compId = page.insertDesignCard(index);
      this.controls.editorCtrl.clickPickComp(compId);
      return;
    }

    const compId = page.insertCompContainer(
      compKey,
      this.controls.pageCtrl.currStreamCard
    );

    this.controls.editorCtrl.clickPickComp(compId);
  },

  pickParentComp(compId: string) {
    const page = this.controls.pageCtrl;
    const parentComp = this.helper.findParentComp(compId);
    parentComp && page.setCurrComp(parentComp.id);
  },

  ctrlc() {
    const page = this.controls.pageCtrl;

    ctrlState.selected = [];
    const children = page.currStreamCard.children.default || [];
    const gizmo = this.controls.selectCtrl.gizmo;
    const selected = gizmo.selected.map((item) => item.comp.id);

    children.forEach((c) => {
      if (selected.indexOf(c) > -1) {
        ctrlState.selected.push(c);
      }
    });
    ctrlState.screenId = this.controls.screenCtrl.currScreenId;
    ctrlState.cardId = page.currStreamCardId;
    ctrlState.type = 1;
    const objc = this.controls.selectCtrl.objContainer;
    ctrlState.selWidth = this.helper.pxToDesignSize(objc.width);
    objc.setPivot(0);
    const currX = objc.parent.x,
      currY = objc.parent.y;
    ctrlState.selX = currX;
    ctrlState.selY = currY;
    objc.setPivot(4);
  },

  copyLastSelected() {
    if (this.store.currCompId && this.store.currCompId != "root") {
      ctrlState.selected = [this.store.currCompId];
      ctrlState.cardId = this.controls.pageCtrl.currStreamCardId;
      ctrlState.type = 1;
    }
  },

  setSameSize(isWidth: boolean) {
    const selectCtrl = this.controls.selectCtrl;
    const gizmo = selectCtrl.objContainer;
    const layout = this.controls.pageCtrl.currComp.layout;

    const w = this.controls.screenCtrl.getCurrScreenWidth();
    if (this.selected.length == 1) {
      const size: any = layout.size.slice(0);
      let isSame = false;
      if (isWidth) {
        isSame = w == size[0];
        size[0] = w;
      }
      else {
        isSame = size[1] == this.controls.pageCtrl.currStreamCard.layout.size[1]
        size[1] = this.controls.pageCtrl.currStreamCard.layout.size[1];
      }
      if (!isSame) {
        layout.setSize(size);
        this.history.submit();
      }
      return;
    }

    const anchorBox = this.helper.findComp(gizmo.state.lastId);
    if (!anchorBox) return;

    gizmo.parent.children.forEach((c) => {
      const child = c as CompObject;
      const r = child.getBox();
      if (isWidth) child.comp.layout.size[0] = anchorBox.layout.size[0];
      else child.comp.layout.size[1] = anchorBox.layout.size[1];
    });

    gizmo.updateSize();

    selectCtrl.upgateGizmoStyle();
    history.submit();
  },

  toogleGroup() {
    const gizmo = this.controls.selectCtrl.gizmo;

    if (gizmo.selected.length > 1) {
      this.actions.createGroupComps();
      return;
    }
    if (gizmo.selected.length == 1) {
      const c = gizmo.selected[0].comp;
      if (c.compKey == "Group") {
        this.actions.cancelGroupComps(c);
      }
    }
  },
  ctrlq() {
    const page = this.controls.pageCtrl;
    if (!page.currCompId) return;
    ctrlState.selected = [page.currCompId];
    ctrlState.screenId = this.controls.screenCtrl.currScreenId;
    ctrlState.cardId = page.currStreamCardId;
    ctrlState.type = 3;
  },
  ctrlx() {
    //console.log("ctrlv ", this.store.selected);
    //console.log("ctrlv ", this.store.selected);
    const page = this.controls.pageCtrl;
    const gizmo = this.controls.selectCtrl.gizmo;
    const selected = gizmo.selected.map((item) => item.comp.id);

    //保持图层顺序
    ctrlState.selected = [];
    const children = page.currStreamCard.children.default || [];
    children.forEach((c) => {
      if (selected.indexOf(c) > -1) {
        ctrlState.selected.push(c);
      }
    });

    ctrlState.cardId = page.state.currStreamCardId;
    ctrlState.type = 2;
    ctrlState.screenId = this.controls.screenCtrl.currScreenId;
    const objc = this.controls.selectCtrl.objContainer;
    ctrlState.selWidth = this.helper.pxToDesignSize(objc.width);
    objc.setPivot(0);
    const currX = objc.parent.x,
      currY = objc.parent.y;
    ctrlState.selX = currX;
    ctrlState.selY = currY;
    objc.setPivot(4);
  },

  ctrlv() {
    if (ctrlState.selected.length < 1) return;
    const ctrl = this.controls.pageCtrl;

    const news: string[] = [];

    const deepCopy = (c: DesignComp) => {
      const childs = c.children.default || [];
      if (childs.length > 0) {
        childs.forEach((id, index) => {
          const cp = this.helper.findComp(id) as DesignComp;
          const cp1 = cloneObj(cp);
          ctrl.compMap[cp1.id] = cp1;
          ctrl.setCompPid(cp1.id, c.id);
          childs[index] = cp1.id;
          deepCopy(cp1);
        });
      }
    };

    ctrlState.selected.forEach((c) => {
      const cp = this.helper.findComp(c) as DesignComp;
      const cp1 = cloneObj(cp);
      news.push(cp1.id);
      ctrl.compMap[cp1.id] = cp1;
      ctrl.setCompPid(cp1.id, ctrl.currStreamCardId);
      deepCopy(cp1);
    });
    this.actions.addComps(news);

    this.controls.selectCtrl.gizmo.selectObjs(news);

    //剪辑

    if (ctrlState.type == 2) {
      //剪辑删除原来的组件
      const card = this.helper.findComp(ctrlState.cardId) as DesignComp;
      const childs = card.children.default?.slice(0) || [];
      ctrlState.selected.forEach((s) => {
        let i = childs.indexOf(s);
        if (i != -1) {
          childs.splice(i, 1);
        }
      });
      card.children.default = childs;
      this.helper.extendStreamCard(ctrlState.cardId);
      ctrlState.selected = [];
    }

    //获取当前选中的内容
    if (ctrlState.cardId != ctrl.currStreamCardId) {
      //跨卡片拷贝
      let pox = this.helper.getCardNextPosY(
        ctrl.currStreamCardId,
        ctrlState.selWidth
      );
      this.controls.selectCtrl.translate(0, pox.y - ctrlState.selY);
      return;
    }

    if (ctrlState.screenId == this.controls.screenCtrl.currScreenId) {
      this.controls.selectCtrl.translate(20, 20);
    }

    history.submit();
  },

  addComps(ids: string[]) {
    const childs = this.controls.pageCtrl.currStreamCard.children.default.slice(0);
    childs.push(...ids);
    this.controls.pageCtrl.currStreamCard.children.setDefault(childs);
  },

  ctrlAndA() {
    const childrens = (this.controls.pageCtrl.currStreamCard.children.default || []).slice(
      0
    );
    this.controls.selectCtrl.gizmo.selectObjs(childrens);
  },

  // 删除组件
  removeSelectComps() {
    const selected = this.controls.selectCtrl.gizmo.selected.slice(0);
    this.controls.editorCtrl.clickPickComp("");
    let n = selected.length;
    while (n--) {
      this.actions.removeComp(selected[n].comp.id);
    }
    history.submit();
  },

  // 删除组件
  removeComp(compId: string, submitHistory = false) {
    const ctrl = this.controls.pageCtrl;

    const paths = this.helper.getCompTrees(compId);
    if (!paths[2]) {
      if (this.helper.isStreamCard(compId)) {
        this.actions.removeStreamCard(compId);
        return;
      }
      return;
    }
    compId = paths[2].id;

    if (this.helper.isCompCanDelete(compId)) {
      if (this.helper.isStreamCard(compId)) {
        this.actions.removeStreamCard(compId);
        return;
      }
      const cardid = ctrl.currStreamCardId;
      if (compId === ctrl.currCompId) {
        ctrl.setCurrComp(ctrl.currStreamCardId);
      }
      ctrl.deleteComp(compId);

      this.helper.extendStreamCard(cardid);

      this.controls.editorCtrl.clickPickComp("");
    }

    if (submitHistory) {
      history.submit();
    }
  },

  async removeStreamCard(compId: string) {
    const ctrl = this.controls.pageCtrl;

    await queenApi.showConfirm({
      title: "删除提示",
      content: "确认删除当前页面?",
      type: "danger",
    });

    let nextCard = ctrl.currStreamCardId;
    if (compId == ctrl.currStreamCardId) {
      const i = ctrl.streamCardIds.indexOf(compId);
      nextCard = ctrl.streamCardIds[i + 1];
      if (!nextCard) {
        nextCard = ctrl.streamCardIds[i - 1];
      }
    }
    this.controls.selectCtrl.gizmo.selectObjs([]);
    this.controls.propsCtrl.showProp("root");

    ctrl.setCurrComp(nextCard);
    ctrl.deleteComp(compId);
  },

  // 移动组件顺序
  moveComp(selIndex: number, targetIndex: number) {
    this.controls.editorCtrl.clickPickComp("root");
    if (selIndex === targetIndex) return;

    this.controls.pageCtrl.moveComp(selIndex, targetIndex);
  },

  // 保存容器为组件
  async saveAsComp(comp: DesignComp) {
    const ctrl = this.controls.pageCtrl;

    try {
      const CompSave = this.components.CompSave as any;
      let title = "";
      let type = "comp";

      try {
        const ret: any = await queenApi.dialog(<CompSave />, {
          width: "300px",
          title: "保存到我的",
        });
        if (!ret) {
          return;
        }
        title = ret.title;
        type = ret.type;
      } catch (error) {
        return;
      }

      console.log(title, type);

      // 组件封面
      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 ddata = ctrl.toJson();

      const data = {
        title,
        type,
        thumbnail,
        compMap: ddata.compMap,
      };
      this.helper.clearUnusedComps(data.compMap, comp.id);
      data.compMap.root = data.compMap[comp.id];
      data.compMap.root.id = "root";

      //清除平移距离
      const mtx = Matrix.createFromMatrixStr(
        data.compMap.root.layout.transformMatrix as string
      );
      mtx.tx = 0;
      mtx.ty = 0;
      data.compMap.root.layout.transformMatrix = mtx.getMatrixStr();

      delete data.compMap[comp.id];

      queenApi.showLoading("保存中");
      this.controls.uploader.ignoreDashField = true;
      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() {
    const ctrl = this.controls.pageCtrl;

    try {
      // 清除无用组件
      this.helper.clearProjectUnusedComps(ctrl.designData.compMap);
      const c = this.controls.screenCtrl;
      c.saveScreenPage();
      const root = this.helper.findRootComp() as DesignComp;
      root.value.useFor = c.state.screen.useFor;
      root.value.pageMode = c.state.screen.pageMode;
      root.value.pageSizeType = c.state.screen.pageSizeType;

      // 封面截屏
      // if (!ctrl.designData.thumbnail) {
      //   await this.actions.updateThumbnailByScreenshot();
      // }

      queenApi.showLoading("保存中");

      await this.actions.saveDesignLocal();
      // await this.controls.uploader.uploadBlobs(ctrl.designData);
      // if (this.store.isWk) {
      //   await this.https[this.store.isEditPage ? "saveWkDesign" : "saveComp"](
      //     ctrl.toJson()
      //   );
      // } else {
      //   await this.https[this.store.isEditPage ? "saveDesign" : "saveComp"](
      //     ctrl.toJson()
      //   );
      // }
      queenApi.messageSuccess("保存成功");
    } catch (error: any) {
      throw Exception.error(error.toString());
    } finally {
      queenApi.hideLoading();
    }
  },
  async saveDesignLocal() {
    const ctrl = this.controls.pageCtrl;

    const { deviceCtrl, prjCtrl } = useCtx();
    const ok = await deviceCtrl.WriteFileText(
      `${prjCtrl.RootDir}/queen5/project.queen5`,
      JSON.stringify(ctrl.toJson())
    );
    if (!ok) {
      return Promise.reject("保存失败");
    }
  },

  // 截屏保存封面
  async updateThumbnailByScreenshot(autoSave?: boolean) {
    const ctrl = this.controls.pageCtrl;

    try {
      const rootComp = ctrl.rootPage;
      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);
      ctrl.setDesignThumbnail(thumbnail);

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

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

    comp.layout.transformMatrix = transformMatrix;
  },

  // 设置组件显示隐藏
  setCompVisible(comp: DesignComp) {
    comp.layout.visible = comp.layout.visible === false ? true : false;
  },
  // 组件重命名
  async resetCompName(comp: DesignComp) {
    const res = await queenApi.showInput({
      title: "重命名",
      defaultValue: comp.title,
    });
    if (!res) return;
    comp.title = res;
  },
  // 清除组件变换
  // clearCompTransform(comp: DesignComp) {
  //   comp.layout.margin = "";
  //   comp.layout.transform = undefined;
  // },
  // 设置组件锁定状态
  setCompLock(comp: DesignComp) {
    comp.layout.setLocked(!comp.layout.locked);
  },
  // 设置组件层级
  setCompLayer(comp: DesignComp, offset: number) {
    const currCard = this.controls.pageCtrl.currStreamCard;
    const cards = currCard.children.default.slice(0);

    const i = cards.indexOf(comp.id);
    if (i == -1) return;

    if (offset < 0) {
      //向下移动
      if (i == 0) return;
      const temp = cards[i - 1];
      cards[i - 1] = comp.id;
      cards[i] = temp;
      currCard.children.setDefault(cards);
      history.submit();
      return;
    }

    if (i == cards.length - 1) return;
    const temp = cards[i + 1];
    cards[i + 1] = comp.id;
    cards[i] = temp;
    currCard.children.setDefault(cards);
    history.submit();
  },
  //横向对齐
  setAlignX(flag: 0 | 1 | 2 | 3, isGroup = false) {
    console.log("alignX");

    const selectCtrl = this.controls.selectCtrl;
    const w = this.helper.designSizeToPx(
      this.controls.screenCtrl.getCurrScreenWidth()
    );
    const gizmo = selectCtrl.gizmo;

    if (gizmo.selected.length == 1 || isGroup) {
      const box = gizmo.getBound();

      switch (flag) {
        case 0:
          selectCtrl.translate(-box.left, 0);
          break;
        case 1:
          selectCtrl.translate(-(box.center.x - w / 2.0), 0);
          break;
        case 2:
          selectCtrl.translate(w - box.right, 0);
          break;
      }
      history.submit();
      return;
    }

    //多选元素对齐模式
    const anchorBox = this.helper.findComp(gizmo.state.lastId);
    if (!anchorBox) return;

    const anchor = new CompObject(anchorBox);
    const anchorRect = anchor.getBox();

    let min = 10000,
      max = -10000;
    let step = 0;
    if (flag == 3) {
      //Y轴均匀排布
      gizmo.parent.children.forEach((c) => {
        const child = c as CompObject;
        const r = child.getBox();
        const x = r.x + r.w / 2.0;
        if (x < min) min = x;
        if (x > max) max = x;
      });
      const stepCount = gizmo.parent.children.length;

      step = (max - min) / (stepCount - 1);

      const stepIndexMap: any = {};

      gizmo.parent.children.forEach((c) => {
        const child = c as CompObject;
        const r = child.getBox();
        const x = r.x + r.w / 2.0;

        let minIndex = -1;
        let minV = 10000;
        for (let i = 0; i < stepCount; i++) {
          const ty = i * step + min;
          if (Math.abs(x - ty) < minV && !stepIndexMap[i]) {
            minV = Math.abs(x - ty);
            minIndex = i;
          }
        }
        stepIndexMap[minIndex] = true;
        child.translate(minIndex * step + min - x, 0);
      });
      gizmo.parent.updateTransform();
      history.submit();
      return;
    }

    gizmo.parent.children.forEach((c) => {
      const child = c as CompObject;
      if (child.comp.id == gizmo.state.lastId) return;
      const r = child.getBox();
      switch (flag) {
        case 0:
          child.translate(anchorRect.x - r.x, 0);
          break;
        case 1:
          child.translate(
            anchorRect.x + anchorRect.w / 2.0 - (r.x + r.w / 2.0),
            0
          );
          break;
        case 2:
          child.translate(anchorRect.x + anchorRect.w - (r.x + r.w), 0);
          break;
      }
    });
    gizmo.parent.updateTransform();
    history.submit();
  },

  setAlignY(flag: 0 | 1 | 2 | 3, isGroup = false) {
    const selectCtrl = this.controls.selectCtrl;
    const gizmo = selectCtrl.gizmo;
    if (gizmo.selected.length == 1 || isGroup) {
      const objc = selectCtrl.objContainer;
      const box = objc.getBound();

      const card = new CompObject(this.controls.pageCtrl.currStreamCard);
      const cardBox = card.getBox();

      switch (flag) {
        case 0:
          selectCtrl.translate(0, -box.top);
          break;
        case 1:
          selectCtrl.translate(0, -(box.center.y - cardBox.h / 2.0));
          break;
        case 2:
          selectCtrl.translate(0, cardBox.h - box.bottom);
          break;
      }
      history.submit();
      return;
    }

    const anchorBox = this.helper.findComp(gizmo.state.lastId);
    if (!anchorBox) return;

    const anchor = new CompObject(anchorBox);
    const anchorRect = anchor.getBox();

    const objc = selectCtrl.objContainer;

    let min = 10000;
    let max = -10000;
    let step = 0;

    if (flag == 3) {
      //Y轴均匀排布
      objc.parent.children.forEach((c) => {
        const child = c as CompObject;
        const r = child.getBox();
        const y = r.y + r.h / 2.0;
        if (y < min) min = y;
        if (y > max) max = y;
      });
      const stepCount = objc.parent.children.length;

      step = (max - min) / (stepCount - 1);

      const stepIndexMap: any = {};

      objc.parent.children.forEach((c) => {
        const child = c as CompObject;
        const r = child.getBox();
        const y = r.y + r.h / 2.0;

        let minIndex = -1;
        let minV = 10000;
        for (let i = 0; i < stepCount; i++) {
          const ty = i * step + min;
          if (Math.abs(y - ty) < minV && !stepIndexMap[i]) {
            minV = Math.abs(y - ty);
            minIndex = i;
          }
        }
        stepIndexMap[minIndex] = true;
        child.translate(0, minIndex * step + min - y);
      });

      gizmo.parent.updateTransform();
      history.submit();
      return;
    }

    objc.parent.children.forEach((c) => {
      const child = c as CompObject;
      if (child.comp.id == gizmo.state.lastId) return;
      const r = child.getBox();
      switch (flag) {
        case 0:
          child.translate(0, anchorRect.y - r.y);
          break;
        case 1:
          child.translate(
            0,
            anchorRect.y + anchorRect.h / 2.0 - (r.y + r.h / 2.0)
          );
          break;
        case 2:
          child.translate(0, anchorRect.y + anchorRect.h - (r.y + r.h));
          break;
      }
    });
    history.submit();
  },

  // 宽度铺满
  fullCompWidth(comp: DesignComp) {
    comp.layout.size[0] = this.controls.screenCtrl.getCurrScreenWidth();
  },

  // 取消打组
  cancelGroupComps(groupComp: DesignComp) {
    const childs = groupComp.children.default;
    const gizmo = this.controls.selectCtrl.gizmo;

    const parentMtrx = gizmo.parent.worldTransform.clone();
    gizmo.selectObjs([]); //取消选择

    childs.forEach((o) => {
      const obj = this.helper.findComp(o) as DesignComp;
      const mxt = Matrix.createFromMatrixStr(
        obj.layout.transformMatrix as string
      );
      mxt.prepend(parentMtrx);
      obj.layout.setTransformMatrix(mxt.getMatrixStr());
    });

    const paths = this.helper.getCompTrees(groupComp.id);
    const card = paths[1];
    const parentChilds = (card.children.default || []).filter(
      (item) => item != groupComp.id
    );
    parentChilds.push(...childs);
    const page = this.controls.pageCtrl;
    childs.forEach((item) => {
      page.setCompPid(item, card.id);
    });
    card.children.setDefault(parentChilds);
    this.controls.editorCtrl.clickPickComp(childs[0]);

    history.submit();
  },

  createGroupComps() {
    const gizmo = this.controls.selectCtrl.gizmo;
    const page = this.controls.pageCtrl;

    const sels = gizmo.selected.map((item) => item.comp.id);
    const id = this.controls.compUICtrl.createCompId("Group");
    const comp = this.helper.findComp(id) as DesignComp;
    const chils = this.controls.pageCtrl.currStreamCard.children.default || [];
    const newChilds: any = [];
    const groupChilds: string[] = [];
    chils.forEach((c) => {
      if (sels.indexOf(c) == -1) newChilds.push(c);
      else {
        groupChilds.push(c);
      }
    });
    newChilds.push(id);

    //更新节点的新位置
    const newMatrixMap: any = {};
    gizmo.parent.children.forEach((obj) => {
      const cobj = obj as CompObject;
      const comp = cobj.comp;
      newMatrixMap[comp.id] = cobj.localTransform.getMatrixStr();
    });
    page.currStreamCard.children.setDefault(newChilds);

    //再添加新的节点
    comp.layout.setSize([
      this.helper.pxToDesignSize(gizmo.width),
      this.helper.pxToDesignSize(gizmo.height),
    ]);
    comp.layout.setTransformMatrix(gizmo.parent.worldTransform.getMatrixStr());

    this.controls.selectCtrl.gizmo.selectObjs([]);

    groupChilds.forEach((c) => {
      const comp = this.helper.findComp(c) as DesignComp;
      comp.layout.setTransformMatrix(newMatrixMap[c]);
      page.setCompPid(c, id);
    });
    comp.children.setDefault(groupChilds);

    this.controls.propsCtrl.showProp(comp.id);

    this.controls.selectCtrl.gizmo.selectObjs([comp.id]);

    history.submit();
  },

  handleSelectMoving(key: string) {
    if (this.controls.selectCtrl.gizmo.selected.length < 1) return;
    let x = 0,
      y = 0;
    switch (key) {
      case "left":
        x = -1;
        break;
      case "right":
        x = 1;
        break;
      case "up":
        y = -1;
        break;
      case "down":
        y = 1;
        break;
    }
    this.controls.selectCtrl.translate(x * 0.5, y * 0.5);
    this.controls.selectCtrl.assistCtrl?.flashDrawCardDists();

    history.submit();
  },

  // 点击模板
  async clickTplToDesign(record) {
    const ctrl = this.controls.pageCtrl;

    const res = await queenApi.showConfirm({
      title: "",
      content: "要替换正在编辑的内容？",
    });
    if (!res) return;

    const frameData = await this.https.getDesignDetail(record._id, {
      isSys: true,
    });
    const { compMap, content, desc, thumbnail, title, _id } = frameData.result;

    const designData = {
      _id: ctrl.designData._id,
      version: ctrl.designData.version,
      compMap,
      content,
      desc,
      thumbnail,
      title,
    };

    this.controls.editorCtrl.clickPickComp("root");
    ctrl.setDesignData(designData);

    ctrl.state.setDesignId(_id as string);
  },
});
