<template>
  <div class="right-click-menu">
    <div
      ref="RightMenuBody"
      class="right-menu-body"
      :style="styles"
      v-clickoutside="close"
      v-if="visible"
    >
      <ul>
        <li v-if="elementIsSelected" @click="toEdit">
          <i class="el-icon-edit-outline"></i> 编辑
        </li>
        <li v-if="elementIsSelected" class="li-danger" @click="toDelete">
          <i class="el-icon-delete"></i> 删除
        </li>
        <li v-if="elementIsSelected" @click="toCopy">
          <i class="el-icon-copy-document"></i> 复制
        </li>
        <li v-if="curCopyElement" @click="toPaste">
          <i class="el-icon-document-copy"></i> 粘贴
        </li>
      </ul>
    </div>
  </div>
</template>

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

export default {
  name: "right-click-menu",
  directives: { Clickoutside },
  data() {
    return {
      visible: false,
      curColumnId: null,
      styles: {
        position: "fixed",
        zIndex: 3000
      },
      rightClickPos: {}
    };
  },
  computed: {
    ...mapState("free", ["curElement", "curCopyElement"]),
    elementIsSelected() {
      return !!this.curElement.id;
    }
  },
  mounted() {
    this.init();
  },
  methods: {
    ...mapMutations("free", [
      "setOpenElementEditDialog",
      "setCurElement",
      "setCurCopyElement"
    ]),
    ...mapActions("free", ["actElementById", "removeElement", "pasteElement"]),
    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 { elementId, columnId } = this.getRelateElementId(e.target);
      // 栏外的点击,不做任何处理
      if (!columnId) {
        this.curColumnId = null;
        this.setCurElement({});
        this.rightClickPos = {};
        return;
      }
      const { offsetLeft, offsetTop } = this.getOffsetInfo(
        e.target || e.srcElement
      );
      this.rightClickPos = {
        x: offsetLeft + e.offsetX,
        y: offsetTop + e.offsetY
      };

      this.curColumnId = columnId;
      if (elementId) {
        this.actElementById(elementId);
      } else {
        this.setCurElement({});
      }

      // 既没有要黏贴的元素也没有选中的元素时,不显示右键菜单
      if (!this.curCopyElement.id && !this.curElement.id) return;

      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 elementId = null,
        columnId = null;
      let parentNode = dom;
      while (!(columnId || parentNode.className.includes("page-box"))) {
        if (
          !elementId &&
          parentNode["id"] &&
          parentNode["id"].includes("element-")
        ) {
          elementId = parentNode["id"];
        }

        if (
          !columnId &&
          parentNode["id"] &&
          parentNode["id"].includes("column-")
        ) {
          columnId = parentNode["id"];
        }

        parentNode = parentNode.parentNode;
      }

      return { elementId, columnId };
    },
    getOffsetInfo(dom, endParentClass = "page-column-body") {
      let parentNode = dom;
      let offsetTop = 0,
        offsetLeft = 0;
      while (!parentNode.className.includes(endParentClass)) {
        offsetTop += parentNode.offsetTop;
        offsetLeft += parentNode.offsetLeft;
        parentNode = parentNode.offsetParent;
      }
      return {
        offsetLeft,
        offsetTop
      };
    },
    toEdit() {
      this.close();
      this.setOpenElementEditDialog(true);
    },
    toDelete() {
      this.removeSelectElement();
      // this.close();
      // this.$confirm("确定要删除当前元素吗?", "提示", {
      //   type: "warning"
      // })
      //   .then(() => {
      //     this.removeSelectElement();
      //   })
      //   .catch(() => {});
    },
    removeSelectElement() {
      this.close();
      this.removeElement(this.curElement);
    },
    toCopy() {
      this.close();
      this.setCurCopyElement(deepCopy(this.curElement));
    },
    toPaste() {
      this.close();
      this.pasteElement({
        element: {
          ...deepCopy(this.curCopyElement),
          ...this.rightClickPos,
          id: getElementId(),
          key: randomCode()
        },
        toColumnId: this.curColumnId
      });
    }
  },
  beforeDestroy() {
    document.oncontextmenu = null;
    document.removeEventListener("mouseup", this.docMouseUp);
  }
};
</script>