<script setup lang="ts">
const props = withDefaults(
  defineProps<{
    modelValue?: any
    id?: string //id变化后重新加载树
    data?: any
    dataFun?: () => Promise<any>
    url?: string
    method?: string
    config?: any
    props?: {
      label?: string
      value?: string
      class?: string
      style?: string
      disabled?: string | ((v?: any) => boolean)
    }
    dataMapFun?: (v: any) => {
      label: string
      value: string
      class?: string
      style?: string
      disabled?: boolean
    }
    needFormate?: boolean
    placeholder?: string
    listeners?: any
    type?: "select" | "checkbox" | "radio"
  }>(),
  {
    placeholder: "请选择",
    type: "select",
    method: "get",
    needFormate: true,
  }
)
const emits = defineEmits<{
  (e: "update:modelValue", v: any): void
  (e: "change", v: any): any
}>()
const { modelValue } = toRefs(props)
const _data = ref<any>([])
const options = computed(() => {
  if (props.dataFun || props.url) {
    return _data.value
  }
  formatData(typeof props.data == "function" ? props.data() : props.data)
  return _data.value
})
function onChange(v: any) {
  emits("update:modelValue", v)
  emits("change", v)
  return v
}
function onChange2(v: Array<any>) {
  emits("update:modelValue", v)
  emits("change", v)
  return v
}

function formatData(data: Array<any>) {
  if (!props.needFormate) {
    _data.value = data
  } else {
    if (props.dataMapFun) {
      _data.value =
        data?.map((v: any) => {
          return props.dataMapFun ? props.dataMapFun(v) : v
        }) || []
    } else if (props.props) {
      _data.value =
        data?.map((v: any) => {
          return {
            label: v[props.props?.label ?? "label"],
            value: v[props.props?.value ?? "value"],
            class: v[props.props?.class ?? "class"],
            style: v[props.props?.style ?? "style"],
            disabled:
              typeof props.props?.disabled == "function"
                ? props.props?.disabled(v)
                : v[props.props?.disabled ?? "disabled"],
          }
        }) || []
    } else {
      _data.value = data
    }
  }
}
function load() {
  if (props.dataFun) {
    props.dataFun().then((res) => {
      formatData(res.data || res)
    })
  } else if (props.url) {
    const opts = Object.assign({}, { method: props.method }, props.config || {})
    RequestService.request(opts).then((res) => {
      formatData(res.data)
    })
  } else {
    formatData(typeof props.data == "function" ? props.data() : props.data)
  }
}
function init() {
  load()
}
watch(() => props.id, init)
onMounted(() => {
  init()
})
</script>
<template>
  <template v-if="type == 'checkbox'">
    <el-checkbox-group
      :id="id"
      v-model="modelValue"
      :placeholder="placeholder"
      @change="onChange2"
      v-bind="$attrs"
      v-on="listeners"
    >
      <el-checkbox
        v-for="(v, i) in options"
        :label="v.value"
        :key="i"
        :class="v.class"
        :style="v.style"
        :disabled="v.disabled"
      >
        {{ v.label }}
      </el-checkbox>
    </el-checkbox-group>
  </template>
  <template v-else-if="type == 'radio'">
    <el-radio-group
      :id="id"
      v-model="modelValue"
      :placeholder="placeholder"
      @change="onChange"
      v-bind="$attrs"
      v-on="listeners"
    >
      <el-radio
        v-for="(v, i) in options"
        :label="v.value"
        :key="i"
        :class="v.class"
        :style="v.style"
        :disabled="v.disabled"
      >
        {{ v.label }}
      </el-radio>
    </el-radio-group>
  </template>
  <template v-else>
    <el-select
      v-model="modelValue"
      :id="id"
      :placeholder="placeholder"
      @change="onChange"
      v-bind="$attrs"
      v-on="listeners"
    >
      <el-option
        v-for="(v, i) in options"
        :label="v.label"
        :value="v.value"
        :key="i"
        :class="v.class"
        :style="v.style"
        :disabled="v.disabled"
      ></el-option>
    </el-select>
  </template>
</template>
<style lang="scss" scoped>
:deep(.el-select-dropdown__list) {
  .el-select-dropdown__item {
    &.hover {
      color: var(--bs-primary);
      background: var(--bs-primary-light);
    }
  }
}
</style>
