<template>
  <div
    class="shortcut-key-input"
    :class="{ cursor: focus }"
    :style="$props.style"
    tabindex="0"
    @focus="handleFocus"
    @blur="focus = false"
    @keydown="handleKeydown"
  >

    <template v-if="key.text">

      <span>{{ key.text }}  <i class="el-icon-circle-close" @click="handleDeleteKey" /></span>

    </template>
    <div v-else class="placeholder">{{ placeholder }}</div>
  </div>
</template>
<script>
const CODE_NUMBER = Array.from({ length: 10 }, (v, k) => `Digit${k}`)
const CODE_NUMPAD = Array.from({ length: 10 }, (v, k) => `Numpad${k}`)
const CODE_ABC = Array.from(
  { length: 26 },
  (v, k) => `Key${String.fromCharCode(k + 65).toUpperCase()}`
)
// const CODE_FN = Array.from({ length: 12 }, (v, k) => `F${k + 1}`)
const CODE_CONTROL = [
  'Shift',
  'ShiftLeft',
  'ShiftRight',
  'Control',
  'ControlLeft',
  'ControlRight',
  'Alt',
  'AltLeft',
  'AltRight'
] // ShiftKey Control(Ctrl) Alt
const CODE_OTHER = [
  'ArrowRight',
  'ArrowLeft',
  'ArrowUp',
  'ArrowDown',
  'PageUp',
  'PageDown',
  'Equal',
  'Minus',
  'Space'
]
export default {
  name: 'HotKeyInput',
  props: {
    hotkey: {
      type: Object,
      required: true
    },
    // 校验函数 判断是否允许显示快捷键
    verify: {
      type: Function,
      default: () => true
    },
    hotkeyId: {
      type: String,
      required: true
    },
    placeholder: {
      type: String,
      default: ''
    },
    // 快捷键使用范围
    range: {
      type: Array,
      default: () => ['NUMBER', 'NUMPAD', 'ABC', 'OTHER']
    }
  },
  data() {
    return {
      focus: false,
      key: { controlKey: '', text: '' },

      keyRange: []
    }
  },
  watch: {
    key: {
      handler: function(keyObj) {
        if (keyObj.controlKey) this.focus = false
        this.$emit('update:hotkey', this.key)
      },
      immediate: true
    },
    hotkey: {
      handler: function(val) {
        if (!val.text) return
        // var obj = {}
        // const arr = val.text.split('+')
        // const controlKey = {
        //   altKey: val.,
        //   ctrlKey: arr.includes('Control'),
        //   shiftKey: arr.includes('Shift'),
        //   key: arr[arr.length - 1],
        //   code: `Key${arr[arr.length - 1].toUpperCase()}`
        // }
        // obj = {
        //   text: arr.reduce((text, item, i) => {
        //     if (i) text += '+'
        //     if (controlKey.key === item) text += item.toUpperCase()
        //     else text += item
        //     return text
        //   }, ''),
        //   controlKey
        // }

        this.key.text = val.text
        this.key.controlKey = val.controlKey
      },
      immediate: true
    },
    range: {
      handler: function(val) {
        const keyRangeList = {
          NUMBER: CODE_NUMBER,
          NUMPAD: CODE_NUMPAD,
          ABC: CODE_ABC,
          OTHER: CODE_OTHER
          // FN: CODE_FN
        }
        val.forEach((item) => {
          this.keyRange = this.keyRange.concat(
            keyRangeList[item.toUpperCase()]
          )
        })
      },
      immediate: true
    }
  },
  methods: {
    handleFocus() {
      if (!this.key.text) this.focus = true
    },
    handleDeleteKey() {
      this.key.text = ''
      this.key.controlKey = ''
      this.$emit('update:hotkey', this.key)
    },
    handleKeydown(e) {
      console.log(e)
      const { altKey, ctrlKey, shiftKey, key, code } = e
      if (!CODE_CONTROL.includes(key)) {
        if (!this.keyRange.includes(code)) return
        let controlKey = '';
        [
          { key: altKey, text: 'Alt' },
          { key: ctrlKey, text: 'Ctrl' },
          { key: shiftKey, text: 'Shift' }
        ].forEach((curKey) => {
          if (curKey.key) {
            if (controlKey) controlKey += '+'
            controlKey += curKey.text
          }
        })

        if (key) {
          if (controlKey) controlKey += '+'
          if (key === 'ArrowUp') {
            controlKey += '↑'
          } else if (key === 'ArrowDown') {
            controlKey += '↓'
          } else if (key === 'ArrowLeft') {
            controlKey += '←'
          } else if (key === 'ArrowRight') {
            controlKey += '→'
          } else if (key === 'PageUp') {
            controlKey += 'Page Up'
          } else if (key === 'PageDown') {
            controlKey += 'Page Down'
          } else if (key === '+' && shiftKey) {
            controlKey = '+'
          } else if (key === '=' && !shiftKey) {
            controlKey = '='
          } else if (key === '-' && !shiftKey) {
            controlKey = '-'
          } else if (key === ' ' && code === 'Space') {
            controlKey = 'Space'
          } else {
            controlKey += key.toUpperCase()
          }
        }
        this.addHotkey({
          text: controlKey,
          controlKey: { altKey, ctrlKey, shiftKey, key, code }
        })
      }
      e.preventDefault()
    },
    addHotkey(data) {
      data.id = this.hotkeyId
      if (!this.verify(data)) return
      this.key.text = data.text
      this.key.controlKey = data.controlKey
    }
  }
}
</script>

<style scoped>
@keyframes Blink {
  0% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

.shortcut-key-input {
  position: relative;
  border: 1px solid #dcdcdc;
  border-radius: 4px;
  color: #333;
  width: 100%;
  height: 32px;
  padding: 2px 0;
  cursor: text;
  transition: border-color 0.2s cubic-bezier(0.645, 0.045, 0.355, 1);
}

.shortcut-key-input:focus {
  border-color: #428bca;
  box-shadow: 0 0 4px #428bca;
}

/* .shortcut-key-input.cursor::after {
  content: "|";
  animation: Blink 1.2s ease 0s infinite;
  font-size: 18px;
  position: absolute;
  top: 7px;
  left: 8px;
} */

.shortcut-key-input span {
  position: relative;
  display: inline-block;
  box-sizing: border-box;

  color: #909399;
  padding: 0 22px 0 8px;
  height: 20px;
  font-size: 13px;
  line-height: 20px;
  border-radius: 4px;
  margin: 5px;
}

.shortcut-key-input .placeholder {
  position: absolute;
  top: 5px;
  left: 5px;
  color: #c0c4cc;
  font-size: 13px;
  text-indent: 4px;
  font: 400 13.3333px Arial;
}

.shortcut-key-input span i {
  position: absolute;
  top: 2px;
  right: 4px;
  content: "";
  /* background: url("data:image/svg+xml,%3Csvg class='icon' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cpath d='M512 64C264.58 64 64 264.58 64 512s200.58 448 448 448 448-200.58 448-448S759.42 64 512 64zm0 832c-212.08 0-384-171.92-384-384s171.92-384 384-384 384 171.92 384 384-171.92 384-384 384z' fill='%23909399'/%3E%3Cpath d='M625.14 353.61L512 466.75 398.86 353.61a32 32 0 0 0-45.25 45.25L466.75 512 353.61 625.14a32 32 0 0 0 45.25 45.25L512 557.25l113.14 113.14a32 32 0 0 0 45.25-45.25L557.25 512l113.14-113.14a32 32 0 0 0-45.25-45.25z' fill='%23909399'/%3E%3C/svg%3E")
    no-repeat center;
  background-size: contain; */
  width: 14px;
  height: 14px;
  transform: scale(0.9);
  opacity: 0.6;
}

.shortcut-key-input span i:hover {
  cursor: pointer;
  opacity: 1;
}
</style>
