<template>
  <div class="dict-selector">
    <el-select
      v-if="formType == 'select'"
      v-model="valueSync"
      :placeholder="placeholder"
      clearable
      :multiple="multiple"
      :disabled="disabled"
      :clearable="clearable"
    >
      <el-option
        v-for="dict in formattedList"
        :key="dict.value"
        :label="$l(dict,'label')"
        :value="dict.value"
      />
    </el-select>
    <el-radio-group
      v-if="formType == 'radio'"
      v-model="valueSync"
      :disabled="disabled"
    >
      <el-radio
        v-for="dict in formattedList"
        :key="dict.value"
        :label="dict.value"
        :checked="valueSync === dict.value"
      >{{ $l(dict,'label') }}</el-radio>
    </el-radio-group>
    <el-checkbox-group
      v-if="formType == 'checkbox'"
      v-model="valueSync"
      :disabled="disabled"
    >
      <el-checkbox
        v-for="dict in formattedList"
        :key="dict.value"
        :label="dict.value"
      >{{ $l(dict,'label') }}</el-checkbox>
    </el-checkbox-group>
  </div>
</template>
<script>
const FORMATTERS = {
  string: String,
  bool: function(val) {
    return [false, 'false', 0, '0'].indexOf(val) < 0
  },
  number: Number,
  array: function(val) {
    return typeof val === 'string'
      ? val.split(',').filter((item) => item && item !== '')
      : val
  }
}
export default {
  props: {
    placeholder: {
      type: String
    },
    type: String,
    value: [String, Number, Array, Boolean],
    multiple: Boolean,
    formType: {
      type: String,
      default: 'select'
    },
    formatter: {
      type: [Function, String],
      default: String
    },
    /* forceString: {
            type: Boolean,
            default: true
        }, */
    defaultable: Boolean, // 是否默认选择第一个
    disabled: Boolean,
    clearable: Boolean,
    /**
     * 过滤字典项，用于只使用部分字典项的场景
     */
    filter: {
      type: Function,
      default: () => true
    }
  },
  data() {
    return {
      valueSync: this.multiple ? [] : null
    }
  },
  computed: {
    dictList() {
      return this.getList(this.type).filter(this.filter)
    },
    formattedList() {
      const arr = []
      this.dictList.forEach((item) => {
        arr.push({
          label: item.label,
          labelEn: item.labelEn,
          value: this.format(item.value),
          cssClass: item.cssClass,
          colorType: item.colorType
        })
      })
      return arr
    }
  },
  watch: {
    valueSync(val) {
      // this.$emit('input', this.forceString ? String(this.valueSync) : this.valueSync)
      this.$emit('input', this.format(val))
    },
    value(val) {
      this.setValueSync()
    },
    dictList() {
      this.setDefault()
    }
  },
  created() {
    this.setValueSync()
    this.setDefault()
  },
  methods: {
    format(val) {
      if (val === null || val === undefined) return val
      const formatter =
        typeof this.formatter === 'function'
          ? this.formatter
          : FORMATTERS[this.formatter]
      if (!formatter) {
        console.warn('格式器无效', this.formatter)
        return val
      }
      return formatter(val)
    },
    setValueSync() {
      if (this.value === null || this.value === undefined || this.value === '') {
        this.valueSync = this.multiple ? [] : null
        return
      }
      if (this.multiple) {
        let value = []
        if (typeof this.value === 'string') {
          value = this.value.split(',').filter((item) => item && item !== '')
        }
        this.valueSync = value.map((item) => this.format(item))
      } else {
        this.valueSync = this.format(this.value) === 0 ? null : this.format(this.value)
      }

      /* if(this.forceString && this.multiple){
                this.valueSync = this.value.split(',')
            }else this.valueSync = this.forceString ? String(this.value) : this.value */
    },
    getList() {
      return this.getDictDatas(this.type)
    },
    setDefault() {
      if (!this.defaultable) return
      if (
        this.dictList.length &&
        (this.valueSync === null || this.valueSync === '' || typeof this.valueSync === 'undefined')
      ) {
        this.valueSync = this.multiple ? [] : this.formattedList[0].value
      }
    }
  }
}
</script>
<style scoped>
.dict-selector {
  display: inline-block;
}
</style>
