<template>
  <div :class="['dk-drag-number-input', direction]">
    <el-input v-model="data" type="text" :controls="false" @input="updateValue">
      <template v-slot:prefix>
        <span
          class="el-input__prefix w-resize"
          :class="[`${direction}-resize`] "
          @mousedown.stop="startChange"
          @mouseup="stopChange"
        >
          <el-tooltip class="item" effect="dark" :disabled="!tooltipContent" :content="tooltipContent" placement="top" :open-delay="500">
            <i :class="icon || 'el-icon-rank'" />
          </el-tooltip>
        </span>
      </template>
    </el-input>
    <span v-if="showUnit" class="unit-selector">
      <el-select v-model="unit">
        <el-option v-for="(item,index) in units" :key="index" :label="item" :value="item" />
      </el-select>
    </span>
  </div>
</template>

<script>
import utils from 'xe-utils'

export default {
  name: 'DkDragNumberInput',
  props: {
    value: {
      default: '',
      type: [String, Number]
    },
    // icon
    icon: {
      default: '',
      type: String
    },
    // 方向：horizontal、vertical
    direction: {
      default: 'horizontal',
      type: String
    },
    // 默认单位列表
    units: {
      type: Array,
      default: () => {
        return [
          'px', '%'
        ]
      }
    },
    // 存在单位时，是否显示单位选择器
    showUnit: {
      default: true,
      type: Boolean
    },
    // 提示内容
    tooltipContent: {
      default: '',
      type: String
    }
  },
  data() {
    return {
      data: '',
      isDragging: false, // 是否开始拖拽
      startY: null, // 开始的Y坐标
      startX: null, // 开始的X坐标
      disabledTooltip: false,
      trackMouseBound: null,
      stopChangeBound: null,
      unit: this.units[0] // 默认单位
    }
  },
  computed: {},
  created() {
    this.data = this.value
  },
  mounted() {
  },
  methods: {
    trackMouse(event) {
      if (this.isDragging) {
        let increment
        if (this.direction === 'horizontal') {
          const dx = event.clientX - this.startX
          increment = Math.floor(dx / 10)
          this.startX += increment * 10
        } else if (this.direction === 'vertical') {
          const dy = event.clientY - this.startY
          increment = Math.floor(dy / 10)
          this.startY += increment * 10
        }
        // 需要防止精度丢失
        this.data = this.formatValue(utils.add(this.data, increment))
        if (this.showUnit) {
          this.data = this.data + this.unit
        }
        this.updateValue()
      }
    },
    startChange(event) {
      this.disabledTooltip = true
      this.trackMouseBound = this.trackMouse.bind(this)
      document.addEventListener('mousemove', this.trackMouseBound)
      this.stopChangeBound = this.stopChange.bind(this)
      document.addEventListener('mouseup', this.stopChangeBound)
      this.isDragging = true
      this.startX = event.clientX
      this.startY = event.clientY
    },
    stopChange() {
      this.position = null
      // 在mouseup事件发生时，从文档对象上移除事件监听器
      document.removeEventListener('mousemove', this.trackMouseBound)
      document.removeEventListener('mouseup', this.stopChangeBound)
      this.isDragging = false
      this.disabledTooltip = false
      this.startX = null
      this.startY = null
    },
    formatValue(val) {
      return parseFloat(val) || 0
    },
    updateValue() {
      this.$emit('input', this.data)
    }
  }
}
</script>

<style scoped lang="scss">
.dk-drag-number-input {

  user-select: none;
  display: flex;
  align-items: center;
  .el-input{
    width: calc(100% - 70px);
  }
  .unit-selector {
    margin-left: 5px;
    width: 70px;
  }
  &.horizontal {
    flex-direction: row;
    .el-input__inner {
      width: 90px;
    }
    .w-resize {
      cursor: ew-resize;
    }
  }
  &.vertical {
    //flex-direction: column;
    align-items: baseline;
    .el-input__inner {
      height: 30px;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .w-resize {
      cursor: ns-resize;
    }
  }
}
</style>
