<template>
  <div>
    <el-tag
      v-for="item in values"
      :key="item[labelName]"
      closable
      :disable-transitions="false"
      @close="() => handleClose(item)">
      {{item[labelName]}}
    </el-tag>
    <el-input
      class="input-new-tag"
      v-if="inputVisible"
      v-model="inputValue"
      ref="saveTagInput"
      size="small"
      @keyup.enter.native="handleInputConfirm"
      @blur="handleInputConfirm"
    >
    </el-input>
    <el-button v-else class="button-new-tag" size="small" @click="showInput">+ 新建</el-button>
  </div>
</template>

<script>
  export default {
    name: 'EditableTag',
    props: [
      'value',
      'label',
      'soureType', // String, StringArray, ObjectArray, 默认 String
    ],
    data() {
      return {
        inputVisible: false,
        inputValue: '',
        values: [],
        labelName: 'tag',
      };
    },
    watch: {
      'label': {
        handler (newVal) {
          if (newVal) {
            this.labelName = newVal
          }
        },
        immediate: true,
      },
      'value': {
        handler (newVal) {
          // 支持 string, [ string ], [ object ] 三种形式
          // 如果是 string 或者 [string] 形式, 则会被转换成 [ { xTagInx, label } ] 格式的数组
          if (this.soureType === 'ObjectArray') {
            this.values = newVal || []
          } else if (this.soureType === 'StringArray') {
            this.values = (newVal || []).map((x, i) => ({ xTagInx: i, [`${this.labelName}`]: x }))
          } else {
            this.values = (newVal || '').split(',').filter(x => x).map((x, i) => ({ xTagInx: i, [`${this.labelName}`]: x }))
          }
        },
        immediate: true,
      },
    },
    created () {
    },
    methods: {
      handleClose(item) {
        const target = item[this.labelName]

        this.$confirm(`确认删除 ${target}?`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          if (this.soureType === 'ObjectArray') {
            this.$emit('delete', item)
            this.$emit('input', this.values.filter(x => x[this.labelName] != target))
          } else if (this.soureType === 'StringArray') {
            this.$emit('delete', target)
            this.$emit('input', this.values.filter(x => x[this.labelName] != target).map(x => x[this.labelName]))
          } else {
            this.$emit('delete', target)
            this.$emit('input', this.values.filter(x => x[this.labelName] != target).map(x => x[this.labelName]).join(','))
          }
        }).catch(() => {})
      },
      showInput() {
        this.inputVisible = true;
        this.$nextTick(() => {
          this.$refs.saveTagInput.$refs.input.focus()
        })
      },

      handleInputConfirm() {
        const inputValue = this.inputValue
        if (inputValue) {
          // 输出结果与输入类型一致
          if (this.soureType === 'ObjectArray') {
            const newVal = { [`${this.labelName}`]: inputValue }
            this.$emit('insert', newVal)
            this.$emit('input', (this.value || []).concat(newVal))
          } else if (this.soureType === 'StringArray') {
            this.$emit('insert', inputValue)
            this.$emit('input', (this.value || []).concat(inputValue))
          } else {
            this.$emit('insert', inputValue)
            this.$emit('input', (this.value || '').split(',').filter(x => x).concat(inputValue).join(','))
          }
        }
        this.inputVisible = false
        this.inputValue = ''
      }
    }
  }
</script>

<style>
  .el-tag + .el-tag {
    margin-left: 10px;
  }
  .button-new-tag {
    margin-left: 10px;
    height: 32px;
    line-height: 30px;
    padding-top: 0;
    padding-bottom: 0;
  }
  .input-new-tag {
    width: 90px;
    margin-left: 10px;
    vertical-align: bottom;
  }
</style>
