<script setup lang="ts">
import { EpPropMergeType } from 'element-plus/es/utils'
import { StrAnyObj, StrAnyObjArr } from '@/typings'
import { FormOptionType } from '@/components/AForm/type'
import { getAsyncResult } from '@/utils'
import { getDictByCode } from '@/utils/dict'

const props = withDefaults(
  defineProps<
    {
      modelValue: EpPropMergeType<
        (
          | BooleanConstructor
          | ObjectConstructor
          | ArrayConstructor
          | NumberConstructor
          | StringConstructor
        )[],
        unknown,
        unknown
      >
      style?: StrAnyObj
      placeholder: string
      clearable: boolean
      disabled: boolean
      filterable?: boolean
      multiple?: boolean
      change?: (value: any) => void
    } & FormOptionType
  >(),
  {
    filterable: true,
    multiple: false,
    autoLoadOption: true,
    keyName: 'key',
    labelName: 'label',
    disabledName: 'disabled'
  }
)

const options = ref<StrAnyObjArr>([])

const emits = defineEmits(['update:modelValue'])

const computedModelValue = computed({
  get() {
    return props.modelValue
  },
  set(newValue) {
    emits('update:modelValue', newValue)
  }
})

defineExpose({ loadOption, reloadOption, clearOption })

if (props.autoLoadOption) {
  loadOption()
}

function loadOption() {
  if (props.dict) {
    getDictByCode(props.dict).then((resp) => {
      options.value = resp
    })
  } else {
    getAsyncResult<StrAnyObjArr>(props.option, []).then((resp) => {
      options.value = resp
    })
  }
}

function reloadOption() {
  clearOption()
  loadOption()
}

function clearOption() {
  emits('update:modelValue', null)
  options.value = []
}
</script>

<template>
  <el-select
    v-model="computedModelValue"
    :placeholder="placeholder"
    :clearable="clearable"
    :disabled="disabled"
    :style="style"
    :filterable="filterable"
    :multiple="multiple"
    style="width: 100%"
    @change="(value: any) => change?.(value)"
  >
    <el-option
      v-for="item in options"
      :key="item[props.dict ? 'value' : keyName]"
      :label="item[props.dict ? 'label' : labelName]"
      :value="item[props.dict ? 'value' : keyName]"
      :disabled="item[disabledName]"
    />
  </el-select>
</template>
