<template>
  <div class="dk-input-group">
    <div v-if="!isMerge" class="alone">
      <el-input v-for="(item ,key) in inputList" :key="key" v-model="positions[item.position]" type="input" :controls="false" @change="updateValue">
        <template v-slot:prefix>
          <span
            class="el-input__prefix w-resize"
            @mousedown.stop="startChange(item.position, $event)"
            @mouseup="stopChange"
          >
            <el-tooltip :open-delay="500" class="item" effect="dark" :content="item.name" placement="top-start" :disabled="disabledTooltip">
              <i :class="item.icon" />
            </el-tooltip>
          </span>
        </template>
      </el-input>
    </div>
    <template v-else>
      <el-input v-model="positions.all" type="text" :controls="false" @input="updateValue">
        <template v-slot:prefix>
          <span
            class="el-input__prefix w-resize"
            @mousedown.stop="startChange('all', $event)"
            @mouseup="stopChange"
          >
            <i class="el-icon-rank" />
          </span>
        </template>
      </el-input>
    </template>
    <el-select v-model="unit" @change="updateValue">
      <el-option value="px">px</el-option>
      <el-option value="%">%</el-option>
      <el-option value="em">em</el-option>
    </el-select>
    <div v-if="showMerge" class="dk-full" @click="changIsMerge">
      <el-tooltip class="item" effect="dark" :content="isMerge?'独立配置':'批量配置'" placement="top" :open-delay="100">
        <i class="el-icon-full-screen" />
      </el-tooltip>
    </div>
  </div>
</template>

<script>
import utils from 'xe-utils'

export default {
  name: 'DkBoxSizeInput',
  props: {
    value: {
      type: [String, Number],
      default: '0px'
    },
    defaultMerge: {
      type: Boolean,
      default: true
    },
    type: {
      type: String,
      default: 'padding'
    },
    // 默认单位列表
    units: {
      type: Array,
      default: () => {
        return [
          'px', '%'
        ]
      }
    },
    defaultIsMerge: {
      type: Boolean,
      default: true
    },
    showMerge: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      positions: {
        all: '',
        top: '0',
        right: '0',
        bottom: '0',
        left: '0'
      },
      unit: 'px',
      position: null,
      isMerge: true,
      inputList: [],
      isDragging: false, // 是否开始拖拽
      startX: null, // 开始的X坐标
      disabledTooltip: false,
      trackMouseBound: null,
      stopChangeBound: null
    }
  },
  computed: {
    padding() {
      if (!this.isMerge) {
        return `${this.positions.top}${this.unit} ${this.positions.right}${this.unit} ${this.positions.bottom}${this.unit} ${this.positions.left}${this.unit}`
      } else {
        return `${this.positions.all}${this.unit}`
      }
    }
  },
  watch: {
    value(val) {
      this.parseValue()
      this.updateValue()
    }
  },
  created() {
    this.isMerge = this.defaultIsMerge
    if (this.type === 'radius') {
      this.inputList = [
        { position: 'top', name: '左上', icon: 'el-icon-top-left' },
        { position: 'right', name: '右上', icon: 'el-icon-top-right' },
        { position: 'left', name: '左下', icon: 'el-icon-bottom-left' },
        { position: 'bottom', name: '左下', icon: 'el-icon-bottom-right' }
      ]
    } else {
      this.inputList = [
        { position: 'top', name: '上', icon: 'el-icon-arrow-up' },
        { position: 'right', name: '右', icon: 'el-icon-arrow-right' },
        { position: 'bottom', name: '下', icon: 'el-icon-arrow-down' },
        { position: 'left', name: '左', icon: 'el-icon-arrow-left' }
      ]
    }
    this.parseValue()
    this.updateValue()
  },
  methods: {
    formatValue(val) {
      return parseFloat(val) || 0
    },
    changIsMerge() {
      this.isMerge = !this.isMerge
      this.updateValue()
    },
    trackMouse(position, event) {
      if (this.isDragging) {
        const dx = event.clientX - this.startX
        const increment = Math.floor(dx / 10)
        // 需要防止精度丢失
        this.positions[position] = utils.add(this.positions[position], increment)
        this.startX += increment * 10
        this.updateValue()
      }
    },
    startChange(position, event) {
      this.isDragging = true
      this.startX = event.clientX
      this.position = position
      this.trackMouseBound = this.trackMouse.bind(this, position)
      this.stopChangeBound = this.stopChange.bind(this)
      document.addEventListener('mousemove', this.trackMouseBound)
      document.addEventListener('mouseup', this.stopChangeBound)
    },
    stopChange() {
      this.isDragging = false
      this.position = null
      document.removeEventListener('mousemove', this.trackMouseBound)
      document.removeEventListener('mouseup', this.stopChangeBound)
    },
    parseValue() {
      const arr = this.value.split(' ') || ['0px']
      const [top, right = top, bottom = top, left = right] = arr
      if (arr.length === 4) {
        this.isMerge = false
        this.positions.top = parseInt(top, 10) || 0
        this.positions.right = parseInt(right, 10) || 0
        this.positions.bottom = parseInt(bottom, 10) || 0
        this.positions.left = parseInt(left, 10) || 0
      } else {
        this.positions.all = parseInt(top, 10) || 0
      }
      // 获取单位 top=10px或者10%等
      const unitReg = /(\d+)(px|%|em|rem|pt|pc|mm|in|ex|ch|vw|vh|vmin|vmax)?/g
      const unitMatch = unitReg.exec(this.value)
      if (unitMatch) {
        this.unit = unitMatch[2] || 'px'
      } else {
        this.unit = 'px'
      }
    },
    updateValue() {
      let value = ''
      if (!this.isMerge) {
        value = `${this.positions.top}${this.unit} ${this.positions.right}${this.unit} ${this.positions.bottom}${this.unit} ${this.positions.left}${this.unit}`
      } else {
        value = `${this.positions.all}${this.unit}`
      }
      this.$emit('input', value)
    }
  }
}
</script>
<style scoped lang="scss">
.dk-input-group {
  user-select: none;
  display: inline-block;
  .w-resize{
    cursor: w-resize;
  }
  .el-input {
    min-width: 60px;
    max-width: calc(40% - 30px);
    display: inline-block;
  }
  .alone {
    display: inline;
    .el-input {
      min-width: 60px;
      max-width: calc(20% - 5px);
      &::v-deep {
        .el-input__inner {
          padding: 0 !important;
          padding-left: 30px !important;
        }
      }
    }
  }
  .el-select {
    display: inline-block;
    min-width: 70px;
    max-width: 16%;
  }
  .dk-full {
    cursor: pointer;
    display: inline-block;
    margin: 0 4px;

    i {
      font-size: 16px;
      padding: 0 5px;
    }

    &:hover {
      background: #f2f2f2;
      border-radius: 4px;
    }
  }
}
</style>
