<template>
  <!-- <el-row style="flex-wrap: nowrap"> -->
  <el-select
    v-model="model"
    class="select"
    placeholder="请选择"
    :empty-values="[null, undefined, '']"
    loading-text="加载中..."
    v-bind="{
      ...getEvent,
    }"
    :loading="loading"
    @change="changeFn"
  >
    <el-option
      v-for="item in getOptions"
      :key="item.value"
      :label="item.label"
      :value="item.value"
    />
  </el-select>
  <!-- </el-row> -->
</template>
<script lang="ts" setup>
import { cloneDeep } from 'lodash-es'
interface IOption {
  [key: string]: unknown
}
const props = withDefaults(
  defineProps<{
    options: Array<IOption>
    value?: string
    label?: string
    hasAllOptions?: boolean
    labelIsValue?: boolean // value 使用label字段
    initChange?: boolean // 首次是否触发change事件
    modelValue?: string | number | string[] | number[]
    isRefresh?: boolean
    isValueKey?: boolean

    load?: (arg: (val: boolean) => void) => void // focus后再加载数据的
  }>(),
  {
    options: () => [],
    value: 'value', // 值字段名 默认字段为value
    label: 'label', // 描述字段名 默认字段为label
    hasAllOptions: false, // 使用全部下拉选项
    labelIsValue: false, // value 是 label
    initChange: false,
    modelValue: '',
    isRefresh: false,

    isValueKey: false,
  },
)

const emits = defineEmits<{
  (e: 'change', option: IOption, value: string | number): void
  (
    e: 'update:modelValue',
    data: string | number | string[] | number[] | undefined,
  ): void
  (e: 'updatedOption'): void
}>()

const loading = ref<boolean>(false)

const model = ref(props.modelValue)

const allOption = {
  value: '',
  label: '全部',
}
const fields = reactive<{ value: string; label: string }>({
  value: '',
  label: '',
})

watch(
  [() => props.value, () => props.label],
  (val) => {
    console.log('modelValue', val)
    fields['value'] = val[0]
    fields['label'] = val[1]
  },
  { immediate: true },
)

// 选项处理
const getOptions = computed(() => {
  const value = props.labelIsValue ? fields.label : fields.value
  const arr = cloneDeep(props.options)

  const data = arr.map((item) => {
    !item.value && (item.value = eval(`item.${value}`))
    !item.label && (item.label = eval(`item.${fields.label}`))
    return item
  })

  if (props.hasAllOptions) {
    data.unshift(allOption)
    return data
  }

  return data
})

const changeFn = (id: string | number) => {
  const value = props.labelIsValue ? fields.label : fields.value
  const findItem = props.options.find((item) => item[value] === id)

  if (findItem) {
    emits('change', findItem, id)
  }
}

watch(model, (val) => {
  emits('update:modelValue', val)
})

if (props.initChange) {
  watch([() => props.modelValue, getOptions], ([val, getOptionsVal]) => {
    if (val !== 0) {
      model.value = val
      getOptionsVal.length && changeFn(val as string | number)
    }
  })
} else {
  watch(
    () => props.modelValue,
    (val) => {
      // if (val !== 0) {
      model.value = val
      // }
    },
  )
}

const FocusFn = () => {
  try {
    props.load &&
      props.load((val: boolean) => {
        loading.value = val
      })
  } catch (err) {
    console.log(err)
  }
}

const getEvent = computed(() => {
  let result = {}
  if (props.load) {
    result = {
      onFocus: FocusFn,
    }
  }
  return result
})
</script>
<style lang="scss" scoped>
.select {
  width: 100%;
  height: 100%;
}
.iConFont {
  margin-left: 8px;
  cursor: pointer;
  &:hover {
    color: #2f9bff;
  }
}
</style>
