<template>
  <div class="element-tier-edit">
    <div class="tier-menu">
      <div
        v-for="(column, cindex) in curPage.columns"
        :key="column.id"
        :class="['tier-menu-item', { 'is-active': column.id === curColumn.id }]"
        @click="selectColumn(column)"
      >
        栏{{ cindex + 1 }}
      </div>
    </div>
    <div
      ref="TierList"
      class="tier-list"
      @drop.prevent="dropInnerElement"
      @dragover.prevent="dragOver($event)"
      @dragleave.prevent
    >
      <div
        v-for="element in curColumn.elements"
        :key="element.id"
        :class="[
          'tier-item',
          {
            'after-drop': element.id === curDropElementId && isDragDown,
            'before-drop': element.id === curDropElementId && !isDragDown,
          },
        ]"
        :id="`tier-${element.id}`"
        draggable="true"
        @dragstart="($event) => dragStart($event, element)"
        @dragend.prevent="dragEnd"
        @click="selectElement(element)"
      >
        <div
          :class="[
            'tier-item-cont',
            {
              'is-active': curElement.id === element.id,
            },
          ]"
        >
          {{ element.desc }}
        </div>
        <!-- <div class="tier-item-cont">{{ element.zindex }}:{{ element.id }}</div> -->
      </div>
    </div>
  </div>
</template>

<script>
import { mapState, mapMutations, mapActions } from "vuex";

export default {
  name: "element-tier-edit",
  data() {
    return {
      curColumn: { id: "1", elements: [] },
      curDragElement: null,
      curDropElementId: null,
      dragStartPageY: null,
      isDragDown: false,
    };
  },
  computed: {
    ...mapState("free", ["curPage", "curElement"]),
  },
  watch: {
    curPage: {
      immediate: true,
      handler(val) {
        this.selectColumn(val.columns && val.columns[0]);
      },
    },
    curElement(val) {
      if (!val.id) return;
      const columnIndex = this.curPage.columns.findIndex((column) =>
        column.elements.find((elem) => elem.id === val.id)
      );
      if (columnIndex === -1) return;
      this.selectColumn(this.curPage.columns[columnIndex]);

      this.$nextTick(() => {
        const tierDom = document.getElementById(`tier-${this.curElement.id}`);
        this.$refs.TierList.scrollTop = tierDom.offsetTop;
      });
    },
  },
  methods: {
    ...mapMutations("free", ["setCurElement"]),
    ...mapActions("free", ["moveElementToElement"]),
    selectColumn(column) {
      if (column) {
        if (column.id === this.curColumn.id) return;
        this.curColumn = column;
      } else {
        this.curColumn = { id: "1", elements: [] };
      }
    },
    selectElement(element) {
      this.setCurElement(element);
    },
    getRelateElement(dom) {
      let element = null;
      let parentNode = dom;
      while (!element && !parentNode.className.includes("tier-list")) {
        if (
          !element &&
          parentNode["id"] &&
          parentNode["id"].includes("tier-element")
        ) {
          element = parentNode;
        } else {
          parentNode = parentNode.parentNode;
        }
      }

      return element;
    },
    getElementId(tierId) {
      return tierId.replace("tier-", "");
    },
    checkElementsIsSiblings(elementId1, elementId2) {
      const pos1 = this.curColumn.elements.findIndex(
        (elem) => elem.id === elementId1
      );
      const pos2 = this.curColumn.elements.findIndex(
        (elem) => elem.id === elementId2
      );
      return Math.abs(pos1 - pos2) <= 1;
    },
    getSiblingElement(elementId, offset) {
      const pos = this.curColumn.elements.findIndex(
        (elem) => elem.id === elementId
      );
      return this.curColumn.elements[pos + offset] || null;
    },
    dragStart(e, element) {
      this.dragStartPageY = e.pageY;
      this.curDragElement = element;
    },
    dragOver(e) {
      // console.log(e.target);
      this.isDragDown = e.pageY > this.dragStartPageY;
      if (e.target.className.includes("tier-list")) {
        const curDropElement = this.isDragDown
          ? this.curColumn.elements.slice(-1)[0]
          : this.curColumn.elements[0];
        this.curDropElementId = curDropElement.id;
        return;
      }

      const elementDom = this.getRelateElement(e.target);
      if (!elementDom) return;

      const targetId = this.getElementId(elementDom.id);
      const curDropElement = this.getSiblingElement(targetId, 0);
      this.curDropElementId = curDropElement.id;
    },
    dropInnerElement() {
      // console.log(this.curDragElement.id, this.curDropElementId);
      if (this.curDragElement.id === this.curDropElementId) return;

      // 往下:target上一个位置
      // 往上:target下一个位置
      this.moveElementToElement({
        curElement: this.curDragElement,
        toElementId: this.curDropElementId,
        curColumnId: this.curColumn.id,
        isDragDown: this.isDragDown,
      });
    },
    dragEnd() {
      this.curDragElement = null;
      this.curDropElementId = null;
      this.dragStartPageY = null;
    },
  },
};
</script>