<template>
  <el-select v-model="innerValue" v-bind="$attrs" @change="selectChange" @clear="clear">
    <!-- 默认插槽，支持自定义选项 -->
    <slot>
      <!-- 默认根据options生成选项 -->
      <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
    </slot>
  </el-select>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  modelValue: [String, Number, Array, Object],
  /** 这个必须有（即便使用插槽模式） */
  options: {
    type: Array,
    default: () => [],
    validator: value => value.every(item => 'value' in item && 'label' in item)
  }
})

const emit = defineEmits(['update:modelValue', 'change', 'clear'])
const selectChange = (val) => {
  // emit('update:modelValue', val)
  emit('change', val)
}
const clear = (val) => {
  // emit('update:modelValue', val)
  emit('clear', val)
}
// 计算有效的选项值集合
const validValues = computed(() =>
  props.options.reduce((acc, cur) => {
    acc.push(cur.value)
    return acc
  }, [])
)

// 处理后的双向绑定值
const innerValue = computed({
  get() {
    const val = props.modelValue
    if (val === null || val === undefined) return val

    if (Array.isArray(val)) {
      // 多选模式过滤无效值
      return val.filter(v => validValues.value.includes(v))
    }
    // 单选模式检查有效性
    return validValues.value.includes(val) ? val : null
  },
  // 先不修改原值，只是不显示无效值
  set(value) {
    emit('update:modelValue', value)
  }
})
</script>
