<template>
  <div
    class="es-enable-drag"
    :style="!position.length || showBig ? styleObject : positionObject"
    @mousedown="dragStart"
    @touchstart="dragStart"
  >
    <div
      v-show="!position.length || showBig"
      :class="{
        'show-animation-left':
          iconStatus === 'show' && position.includes('left'),
        'show-animation-top': iconStatus === 'show' && position.includes('top'),
        'show-animation-right':
          iconStatus === 'show' && position.includes('right'),
        'show-animation-bottom':
          iconStatus === 'show' && position.includes('bottom'),
        'hide-animation-left':
          iconStatus === 'hide' && position.includes('left'),
        'hide-animation-top': iconStatus === 'hide' && position.includes('top'),
        'hide-animation-right':
          iconStatus === 'hide' && position.includes('right'),
        'hide-animation-bottom':
          iconStatus === 'hide' && position.includes('bottom')
      }"
      class="es-enable-content"
      @mouseleave="leaveBigIcon"
    >
      <div
        @mousedown="iconMousedown"
        @mouseup="iconMouseUp"
        @dblclick="handleDblClick"
      >
        <slot name="handler">
          <el-button round type="primary" class="es-enable-drag-enter-button">
            <es-icon
              class="es-enable-drag-enter-icon"
              :contents="icon"
            ></es-icon>
          </el-button>
        </slot>
      </div>
    </div>
    <div
      v-show="position.length && !showBig"
      class="es-enable-drag-small-icon-box"
      @mouseenter="enterIcon"
    >
      <slot name="small-icon" :position="position">
        <div
          class="es-enable-drag-small-icon"
          :data-content="smallText"
          :class="{
            'es-left': position.includes('left'),
            'es-right': position.includes('right'),
            'es-top':
              position.includes('top') &&
              !(position.includes('right') || position.includes('left')),
            'es-bottom':
              position.includes('bottom') &&
              !(position.includes('right') || position.includes('left'))
          }"
        >
          <i
            v-show="position.includes('right')"
            class="es-enable-drag-small-tri es-icon-circle-zuo"
          ></i>
          <i
            v-show="position.includes('left')"
            class="es-enable-drag-small-tri es-icon-circle-you"
          ></i>
          <i
            v-show="
              position.includes('bottom') &&
              !(position.includes('right') || position.includes('left'))
            "
            class="es-enable-drag-small-tri es-icon-circle-shang"
          ></i>
          <i
            v-show="
              position.includes('top') &&
              !(position.includes('right') || position.includes('left'))
            "
            class="es-enable-drag-small-tri es-icon-circle-xia"
          ></i>
        </div>
      </slot>
    </div>
  </div>
</template>

<script>
export default {
  name: 'EsEnableDrag',
  props: {
    //默认拖动按钮图标
    icon: {
      type: String,
      default: 'es-icon-yingyong'
    },
    smallText: String,
    //边界距离（小于这个距离就隐藏）
    distance: {
      type: Number,
      default: 10,
      validator: function (value) {
        return value >= 0;
      }
    },
    // 初始距离顶部的位置
    topDistance: String,
    // 初始距离左边的位置
    leftDistance: String,
    // 是否可以拖拽
    isDragg: {
      type: Boolean,
      default: true
    },
    //允许隐藏的方位
    berth: {
      type: Array,
      default() {
        return ['right'];
      },
      validator: function (value) {
        return (
          value.length == 0 ||
          value.includes('right') ||
          value.includes('left') ||
          value.includes('top') ||
          value.includes('bottom')
        );
      }
    },
    // 列表数据
    list: {
      type: Array,
      default: () => {
        return [{}, {}];
      }
    },
    // 自定义列表的时候传入的高度（有高度才有动画）
    customHeight: {
      type: String,
      default: () => {
        return '';
      }
    }
  },
  data() {
    return {
      width: 0, // 元素的宽度
      height: 0, // 元素的高度
      clickState: false, // 是点击还是拖拽
      dbClick: false, // 双击状态
      canDrag: true, // 临时状态：是否可以拖拽
      firstLoad: true, // 第一次加载
      iconStatus: 'normal', // 大图标显示状态
      showBig: false, // 是否显示大图标
      moved: false, // 是否移动过
      mouseX: 0, // 初始位置的X坐标
      mouseY: 0, // 初始位置的Y坐标
      // 拖拽位置的样式
      styleObject: {
        top: 0,
        left: 0
      },
      positionObject: {},
      position: [] // 是否贴边
    };
  },
  computed: {},
  created() {},
  mounted() {
    this.init();
  },
  methods: {
    init() {
      const rect = this.$el.getBoundingClientRect();
      this.width = rect.width;
      this.height = rect.height;
      if (this.topDistance) {
        this.styleObject.top = this.topDistance;
      } else {
        this.styleObject.top =
          window.innerHeight - this.distance - this.height + 'px';
      }
      if (this.leftDistance) {
        this.styleObject.left = this.leftDistance;
      } else {
        this.styleObject.left =
          window.innerWidth - this.distance - this.width + 'px';
      }
    },
    /**
     * @description 双击
     */
    async handleDblClick(event) {
      event && event.stopPropagation();
      event && event.preventDefault();
      // 说明触发了双击状态
      this.dbClick = true;
      console.log('双击了---------------');
      this.$emit('DblClick');
    },
    /**
     * @description 是否打开智能助手
     */
    iconMouseUp() {
      this.T = setTimeout(() => {
        // 不是双击
        if (!this.dbClick) {
          // 防止首次动画
          this.firstLoad = false;
          // 防止拖动影响到了click事件
          if (this.clickState) {
            // TODO 执行点击事件
            console.log('单击了---------------');
            this.$emit('click');
          }
        }
      }, 160);
    },
    /**
     * @description 点击ai入口事件
     */
    iconMousedown() {
      // 发生点击就重置双击状态
      this.dbClick = false;
      // 说明发生了点击
      this.clickState = true;
      // 可以拖拽
      this.canDrag = true;
      this.T && clearTimeout(this.T);
      this.T = null;
    },
    handleItem() {
      console.log('点击了单个列表---------------');
      this.$emit('handleItem');
    },
    /**
     * @description 进入小图标
     */
    enterIcon(samll) {
      if (samll) {
        // 显示大图标
        this.showBig = true;
        // 大图标动画
        this.iconStatus = 'show';
      }
    },
    /**
     * @description 离开大图标
     */
    leaveBigIcon() {
      // 显示大图标
      this.showBig = false;
      // 大图标动画
      this.iconStatus = 'hide';
    },
    /**
     * @description 检测位置合理性
     */
    checkPosition() {
      if (this.position.includes('right')) {
        this.styleObject.left = window.innerWidth + 'px';
      }
      if (this.position.includes('bottom')) {
        this.styleObject.top = window.innerHeight + 'px';
      }
      this.moved = true;
      this.dragEnd();
    },
    /**
     * @description 拖拽开始
     */
    dragStart(e) {
      if (this.isDragg && this.canDrag) {
        e.preventDefault();
        this.moved = false;
        const rect = this.$el.getBoundingClientRect();
        this.mouseY = e.y - rect.y;
        this.mouseX = e.x - rect.x;
        document.addEventListener('mousemove', this.drag);
        document.addEventListener('touchmove', this.drag);
        document.addEventListener('mouseup', this.dragEnd);
        document.addEventListener('touchend', this.dragEnd);
      } else {
        return false;
      }
    },
    /**
     * @description 拖拽中
     */
    drag(e) {
      this.moved = true;
      const x = e.x - this.mouseX;
      const y = e.y - this.mouseY;
      this.styleObject.left = `${x}px`;
      this.styleObject.top = `${y}px`;
    },
    /**
     * @description 拖拽结束
     */
    dragEnd() {
      if (this.moved) {
        this.clickState = false;
        let x = this.styleObject.left.replace('px', '');
        let y = this.styleObject.top.replace('px', '');
        this.position = [];
        this.positionObject = { top: y, left: x };
        if (x < this.distance) {
          this.styleObject.left = this.distance + 'px';
          this.berth.includes('left') && this.position.push('left');
          this.positionObject.left = 0;
        }
        if (x > window.innerWidth - this.distance - this.width) {
          this.styleObject.left =
            window.innerWidth - this.distance - this.width + 'px';
          this.berth.includes('right') && this.position.push('right');
          delete this.positionObject.left;
          this.positionObject.right = 0;
        }
        if (y < this.distance) {
          this.styleObject.top = this.distance + 'px';
          this.berth.includes('top') && this.position.push('top');
          this.positionObject.top = 0;
        }
        if (y > window.innerHeight - this.distance - this.height) {
          this.styleObject.top =
            window.innerHeight - this.distance - this.height + 'px';
          this.berth.includes('bottom') && this.position.push('bottom');
          delete this.positionObject.top;
          this.positionObject.bottom = 0;
        }
      }
      document.removeEventListener('mousemove', this.drag);
      document.removeEventListener('touchmove', this.drag);
      document.removeEventListener('mouseup', this.dragEnd);
      document.removeEventListener('touchend', this.dragEnd);
    }
  },
  destroyed() {
    // 移除监听
    window.removeEventListener('resize', this.onResize);
    document.removeEventListener('mousemove', this.drag);
    document.removeEventListener('touchmove', this.drag);
    document.removeEventListener('mouseup', this.dragEnd);
    document.removeEventListener('touchend', this.dragEnd);
  }
};
</script>
<style lang="scss" scoped></style>
