<template>
  <div class="right-click-menu">
    <div
      v-if="visible"
      ref="RightMenuBody"
      v-clickoutside="close"
      class="right-menu-body"
      :style="styles"
    >
      <ul v-if="isClickSide">
        <li @click="toEdit">
          <i class="el-icon-edit-outline"></i>
          编辑元素
        </li>
        <li class="li-danger" @click="toDelete">
          <i class="el-icon-delete"></i>
          删除元素
        </li>
      </ul>
      <ul v-else>
        <li @click="toEdit">
          <i class="el-icon-edit-outline"></i>
          {{ IS_CONTAINER_ELEMENT ? "编辑元素" : "编辑编辑框" }}
        </li>
        <li class="li-danger" @click="toDelete">
          <i class="el-icon-delete"></i>
          {{ IS_CONTAINER_ELEMENT ? "删除元素" : "删除编辑框" }}
        </li>
        <li v-if="IS_CONTAINER_ELEMENT" @click="toCopyElementChild">
          <i class="el-icon-copy-document"></i> 复制元素
        </li>
        <li v-if="IS_CONTAINER && curCopyElement" @click="toPasteElementChild">
          <i class="el-icon-document-copy"></i> 粘贴元素
        </li>
      </ul>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";
import { deepCopy } from "../../card/plugins/utils";
import Clickoutside from "element-ui/src/utils/clickoutside";
import { findElementById } from "../store";

export default {
  name: "RightClickMenu",
  directives: { Clickoutside },
  data() {
    return {
      visible: false,
      curCopyElement: null,
      styles: {
        position: "fixed",
        zIndex: 3000,
      },
      isClickSide: false,
    };
  },
  computed: {
    ...mapState("paper-export", ["curElement", "topics", "curPage"]),
    IS_CONTAINER_ELEMENT() {
      return !!this.curElement.container;
    },
    IS_CONTAINER() {
      return (
        this.curElement.type === "CONTAINER" ||
        (this.curElement.container &&
          this.curElement.container.type === "CONTAINER")
      );
    },
  },
  mounted() {
    this.init();
  },
  beforeDestroy() {
    document.oncontextmenu = null;
    document.removeEventListener("mouseup", this.docMouseUp);
  },
  methods: {
    ...mapMutations("paper-export", [
      "setOpenElementEditDialog",
      "setCurElement",
    ]),
    ...mapActions("paper-export", [
      "removeElement",
      "removeElementChild",
      "removeSideElement",
      "pasteElementChild",
      "rebuildPages",
    ]),
    init() {
      // 注册自定义右键事件菜单
      document.oncontextmenu = function () {
        return false;
      };
      document.addEventListener("mouseup", this.docMouseUp);
    },
    close() {
      this.visible = false;
    },
    show() {
      this.visible = true;
    },
    docMouseUp(e) {
      if (e.button === 2) {
        this.rightClick(e);
      }
    },
    rightClick(e) {
      const id = this.getRelateElementId(e.target);
      if (!id) return;

      let curElement = findElementById(id, this.topics);
      if (!curElement) {
        curElement = this.curPage.sides.find((item) => item.id === id);
        if (curElement) {
          this.setCurElement(curElement);
          this.isClickSide = true;
        } else {
          this.isClickSide = false;
          return;
        }
      } else {
        this.isClickSide = false;
      }
      this.show();

      this.$nextTick(() => {
        const { x: clickLeft, y: clickTop } = e;
        const { offsetWidth: menuWidth, offsetHeight: menuHeight } =
          this.$refs.RightMenuBody;

        const { innerWidth: wWidth, innerHeight: wHeight } = window;

        let menuLeft = clickLeft,
          menuTop = clickTop;
        if (menuWidth + clickLeft > wWidth) {
          menuLeft = clickLeft - menuWidth;
        }
        if (menuHeight + clickTop > wHeight) {
          menuTop = clickTop - menuHeight;
        }

        this.styles = Object.assign({}, this.styles, {
          top: menuTop + "px",
          left: menuLeft + "px",
        });
      });
    },
    getRelateElementId(dom) {
      let parentNode = dom;
      while (
        !(
          (parentNode["id"] && parentNode["id"].includes("element-")) ||
          parentNode.className.includes("page-column-body") ||
          parentNode.className.includes("paper-template-design")
        )
      ) {
        parentNode = parentNode.parentNode;
      }
      const elementType = parentNode.getAttribute("data-type");

      return parentNode["id"] && elementType ? parentNode["id"] : null;
    },
    toEdit() {
      this.curElement._edit = true;
      this.curElement._side = this.isClickSide;
      this.close();
      this.setOpenElementEditDialog(true);
    },
    toDelete() {
      this.close();
      this.$confirm("确定要删除当前元素吗?", "提示", {
        type: "warning",
      })
        .then(() => {
          this.removeSelectElement();
        })
        .catch(() => {});
    },
    removeSelectElement() {
      if (this.isClickSide) {
        this.removeSideElement(this.curElement);
        return;
      }
      if (this.curElement["container"]) {
        this.removeElementChild(this.curElement);
      } else {
        this.removeElement(this.curElement);
      }
      this.toRebuildPages();
    },
    toCopyElementChild() {
      this.close();
      this.curCopyElement = deepCopy(this.curElement);
    },
    toPasteElementChild() {
      this.close();
      const id = this.curElement.container
        ? this.curElement.container.id
        : this.curElement.id;
      const pasteElement =
        this.curCopyElement.container.id === id
          ? Object.assign({}, this.curCopyElement, {
              y: this.curCopyElement.y + 20,
            })
          : this.curCopyElement;

      this.pasteElementChild({
        curElement: this.curElement,
        pasteElement,
      });
      this.toRebuildPages();
    },
    toRebuildPages() {
      this.$nextTick(() => {
        this.rebuildPages();
      });
    },
  },
};
</script>
