<template>
  <el-select
    v-model="selected"
    class="th-select"
    :filterable="filterable"
    :filter-method="onFilter"
    v-bind="$attrs"
    @change="onChange"
    @focus="onFocus"
    v-on="$listeners"
  >
    <slot
      :options="realOptions"
      :optionValue="optionValue"
      :optionLabel="optionLabel"
    >
      <el-option
        v-for="item in realOptions"
        :key="item[optionValue]"
        :label="item[optionLabel]"
        :value="item[optionValue]"
        :disabled="item.disabled"
      />
    </slot>
    <template slot="prefix">
      <slot name="prefix" />
    </template>
    <template slot="empty">
      <slot name="empty" />
    </template>
  </el-select>
</template>

<script>
import { deepClone } from '../../../src/utils/util'
var pinyin = require('pinyin')

export default {
  name: 'ThSelect',
  props: {
    // 当前选择项
    value: {
      required: true,
      validator() {
        return true
      }
    },
    // 下拉选项列表
    options: {
      type: Array,
      default: () => []
    },
    // 是否拼音过滤
    pinyinFilter: {
      type: Boolean,
      default: false
    },
    // 是否过滤
    filterable: {
      type: Boolean,
      default: false
    },
    // 选项value字段
    optionValue: {
      type: String,
      default: 'value'
    },
    // 选项label字段
    optionLabel: {
      type: String,
      default: 'label'
    },
    // 过滤方法
    filterMethod: {
      type: Function,
      default: d => d
    }
  },
  data() {
    return {
      selected: '',
      realOptions: []
    }
  },
  computed: {
    getOptions() {
      if (!this.pinyinFilter) {
        return this.options
      }
      const options = this.options.map(d => {
        d[this.optionLabel] = String(pinyin(d[this.optionLabel], {
          style: pinyin.STYLE_FIRST_LETTER
        })[0]).toUpperCase() + ': ' + d[this.optionLabel]
        return d
      }).sort((a, b) => (a[this.optionLabel] + '').localeCompare(b[this.optionLabel] + ''))
      return options
    }
  },
  watch: {
    value: {
      handler(val) {
        this.selected = val
      },
      immediate: true
    },
    options: {
      handler(val) {
        this.realOptions = deepClone(this.getOptions)
      },
      deep: true,
      immediate: true
    }
  },
  methods: {
    onFilter(val) {
      if (this.filterMethod) {
        this.filterMethod(val)
        return
      }
      const realOptions = []
      this.getOptions.forEach(item => {
        if (item[this.optionLabel].indexOf(val) >= 0) {
          realOptions.push(item)
        } else {
          const pys = pinyin(item[this.optionLabel], {
            style: pinyin.STYLE_FIRST_LETTER,
            heteronym: false // 多音字模式
          })
          const key = val.toLowerCase()

          const pys2 = pys.reduce(function(a, b) {
            return a.concat(b)
          })
          if (pys2.join('').indexOf(key) >= 0) {
            realOptions.push(item)
          }
        }
        this.realOptions = realOptions
      })
    },
    onFocus(val) {
      this.realOptions = deepClone(this.getOptions)
      this.$emit('focus', val)
    },
    onChange(val) {
      this.$emit('input', val)
      this.$emit('change', val)
    }
  }
}
</script>
