<template>
  <div
    class="ui-select"
    :class="[{'is-adaption': adaption, 'is-viewable': !editable}, 'ui-select--' + size]"
  >
    <template v-if="editable">
      <template v-if="adaption">
        <span class="ui-select__handle">
          <span v-if="!isEmpty" class="ui-select__current">
            {{ displayValue }}
          </span>
          <span v-else class="ui-select__placeholder">
            {{ placeholder }}
          </span>
          <span v-if="!isEmpty && clearable" class="ui-select__clear" @click="handleClearClick"></span>
          <span v-else class="ui-select__arrow"></span>
        </span>
      </template>
      <el-select
        ref="control"
        class="ui-select__control"
        v-model="innerValue"
        :placeholder="placeholder"
        :size="size"
        :multiple="multiple"
        :disabled="disabled"
        :filterable="filterable"
        :filter-method="filterMethod"
        :remote="remote"
        :remote-method="remoteMethod"
      >
        <el-option
          v-for="(item, index) in options"
          :key="index"
          :label="item[textField]"
          :value="item[valueField]"
        >
          <slot name="item" :item="item" :index="index"></slot>
        </el-option>
      </el-select>
    </template>
    <template v-else>
      {{ showText }}
    </template>
  </div>
</template>
<script>
import Select from 'element-ui/lib/select'
import Option from 'element-ui/lib/option'
import 'element-ui/lib/theme-chalk/select.css'
import 'element-ui/lib/theme-chalk/option.css'

export default {
  name: 'UiSelect',
  components: {
    ElSelect: Select,
    ElOption: Option
  },
  props: {
    adaption: {
      type: Boolean,
      default: false
    },
    value: {
      type: [Array, String, Boolean, Number],
      default: undefined
    },
    multiple: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean
    },
    editable: {
      type: Boolean,
      default: true
    },
    size: {
      type: String,
      default: 'medium'
    },
    items: {
      type: Array,
      default: () => []
    },
    clearable: {
      type: Boolean,
      default: false
    },
    queryMethod: {
      type: Function
    },
    filterable: {
      type: Boolean
    },
    filterMethod: {
      type: Function
    },
    remote: {
      type: Boolean
    },
    textField: {
      type: String,
      default: 'text'
    },
    valueField: {
      type: String,
      default: 'value'
    },
    placeholder: {
      type: String
    }
  },
  computed: {
    innerValue: {
      get() {
        return this.value
      },
      set(val) {
        this.$emit('input', val)
        if (!this.multiple) {
          if (!val) {
            this.$emit('select', {
              item: null
            })
          } else {
            const item = this.options.find(v => v[this.valueField] === val)
            this.$emit('select', {
              item
            })
          }
        }
      }
    },
    isEmpty() {
      if (this.multiple) {
        return !this.value || !this.value.length
      } else {
        return this.value === null || this.value === undefined || this.value === ''
      }
    },
    remoteMethod() {
      if (!this.remote) {
        return
      }
      return (keyword) => {
        return this.loadOptions(keyword)
      }
    },
    showText() {
      if (!this.value) {
        return
      }
      if (this.multiple) {
        if (!this.value.length) {
          return
        }
        return this.value.map(v => {
          const item = this.options.find(vv => vv[this.valueField] === v)
          if (item) {
            return item[this.textField]
          } else {
            return v
          }
        }).join('、')
      } else {
        const item = this.options.find(v => v[this.valueField] === this.value)
        if (item) {
          return item[this.textField]
        } else {
          return this.value
        }
      }
    }
  },
  data() {
    return {
      options: this.items,
      displayValue: null
    }
  },
  watch: {
    items() {
      this.options = this.items
    }
  },
  created() {
    this.loadOptions()
  },
  mounted() {
    if (this.adaption) {
      this.$refs.control.$watch('selected', (value) => {
        if (value) {
          if (Array.isArray(value)) {
            this.displayValue = value.map(v => v.label).join('、')
          } else {
            this.displayValue = value.label
          }
        } else {
          this.displayValue = ''
        }
      })
      this.displayValue = this.$refs.control.selectedLabel
    }
  },
  methods: {
    loadOptions(keyword) {
      if (!this.queryMethod) {
        return Promise.reject()
      }
      this.loading = true
      this.queryMethod({
        keyword
      }).then(rs => {
        this.options = rs
      }).finally(() => {
        this.loading = false
      })
    },
    handleClearClick() {
      this.innerValue = null
    }
  }
}
</script>
<style lang="less">
.ui-select__control{
  width: 100%;
}
.ui-select{
  font-size: 14px;
  &.is-adaption{
    display: inline-block;
    vertical-align: top;
    position: relative;
    overflow: hidden;
    &.ui-select--medium{
      height: 40px;
      line-height: 40px;
    }
    &.ui-select--small{
      height: 32px;
      line-height: 32px;
    }
    &.ui-select--mini{
      height: 28px;
      line-height: 28px;
    }
    .ui-select__handle{
      display: block;
      padding-right: 18px;
      position: relative;
    }
    .ui-select__arrow{
      position: absolute;
      top: 50%;
      right: 4px;
      transform: translateY(-50%);
      border: 4px solid #999;
      border-left-color: transparent;
      border-right-color: transparent;
      border-bottom: 0;
    }
    .ui-select__control{
      position: absolute;
      left: 0;
      top: 0;
      bottom: 0;
      overflow: hidden;
      z-index: 3;
      opacity: 0;
      .el-select__tags,
      .el-input{
        height: 100%;
      }
      &:after {
        content: '';
        position: absolute;
        left: 0;
        top: 0;
        bottom: 0;
        right: 0;
        z-index: 3;
      }
    }
    .ui-select__clear{
      display: inline-block;
      position: absolute;
      width: 14px;
      height: 14px;
      background-color: #ccc;
      border-radius: 50%;
      top: 50%;
      right: 0;
      margin-top: -7px;
      transform: rotate(45deg);
      z-index: 10;
      cursor: pointer;
      &:after,&:before{
        content: '';
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        background-color: #fff;
      }
      &:after {
        width: 9px;
        height: 1px;
      }
      &:before {
        width: 1px;
        height: 9px;
      }
      &:hover {
        background-color: #999;
      }
    }
  }
  &.is-viewable {
    &.ui-select--medium {
      line-height: 22px;
      padding: 9px 0;
    }
    &.ui-select--small {
      line-height: 22px;
      padding: 5px 0;
    }
    &.ui-select--mini {
      line-height: 22px;
      padding: 3px 0;
    }
  }
}
</style>
