<template>
  <div class="dict-selector">
    <el-select v-if="formType == 'select'" v-model="valueSync" filterable :placeholder="placeholder || $t('请选择')" :clearable="clearable" :multiple="multiple" :disabled="disabled" @change="(val) => $emit('change', val)">
      <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" :label="dict.value" :checked="valueSync === dict.value" :key="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" :label="dict.value" :key="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,
      default: null
    },
    type: String,
    value: [String, Number, Array, Boolean],
    multiple: Boolean,
    formType: {
      type: String,
      default: "select"
    },
    formatter: {
      type: [Function, String],
      default: String
    },
    defaultable: Boolean, // 是否默认选择第一个
    disabled: Boolean,
    /**
     * 过滤字典项，用于只使用部分字典项的场景
     */
    filter: {
      type: Function,
      default: () => true
    },
    clearable: Boolean
  },
  data() {
    return {
      valueSync: this.multiple ? [] : null
    }
  },
  computed: {
    dicts() {
      return this.getList(this.type)
    },
    dictList() {
      return this.dicts.filter(this.filter)
    },
    formattedList() {
      let 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", val)
    },
    value(val) {
      if (val != this.valueSync) this.setValueSync()
    },
    dictList() {
      this.setDefault()
    }
  },
  created() {
    this.setValueSync()
    this.setDefault()
  },
  methods: {
    format(val) {
      if (val === null || val == undefined || val == "") return val

      let formatter = typeof this.formatter == "function" ? this.formatter : FORMATTERS[this.formatter]

      if (!formatter) {
        console.warn("格式器无效", this.formatter)
        return val
      }

      return formatter(val)
    },
    changeValue(val) {
      this.valueSync = val
    },
    setValueSync() {
      if (this.value === null || this.value === undefined || this.value === "") {
        return (this.valueSync = this.multiple ? [] : this.value)
      }
      if (this.multiple) {
        let value = this.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)
      }
    },
    getList() {
      return this.getDictDatas(this.type)
    },
    setDefault() {
      if (!this.defaultable) return
      if (this.dictList.length && (this.valueSync === null || this.valueSync == undefined || this.valueSync == "")) {
        this.valueSync = this.multiple ? [] : this.formattedList[0].value
      }
    }
  }
}
</script>
<style scoped>
.dict-selector {
  display: inline-block;
}
</style>
