<template>
  <el-select
    ref="selectRef"
    v-model="selectedValue"
    :placeholder="placeholder"
    :clearable="clearable"
    :filterable="true"
    :remote="true"
    :remote-method="handleRemoteSearch"
    :loading="loading"
    :reserve-keyword="false"
    :disabled="disabled"
    :size="size"
    :popper-class="['remote-select', popperClass]"
    @change="handleChange"
    @visible-change="handleVisibleChange"
  >
    <el-option
      v-for="option in options"
      :key="getOptionKey(option)"
      :label="getOptionLabel(option)"
      :value="getOptionValue(option)"
      :disabled="option.disabled"
    />
    
    <template #empty>
      <div class="empty-options">
        <span v-if="loading">加载中...</span>
        <span v-else-if="options.length === 0 && !hasSearched">请输入关键词搜索</span>
        <span v-else>无匹配数据</span>
      </div>
    </template>
  </el-select>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import { useRemoteSearch } from '@/hooks/useRemoteSearch'
import type { RemoteSearchConfig, FormOption } from '@/types/search-form'

interface Props {
  modelValue: string | number
  config: RemoteSearchConfig
  placeholder?: string
  clearable?: boolean
  disabled?: boolean
  size?: 'large' | 'default' | 'small'
  popperClass?: string
  optionLabel?: string
  optionValue?: string
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  placeholder: '请搜索选择',
  clearable: true,
  disabled: false,
  size: 'default',
  popperClass: '',
  optionLabel: 'label',
  optionValue: 'value'
})

const emit = defineEmits<{
  'update:modelValue': [value: string | number]
  'change': [value: string | number]
}>()

// 远程搜索实例
const remoteSearch = useRemoteSearch(props.config)

// 本地状态
const selectRef = ref()
const selectedValue = ref(props.modelValue)
const hasSearched = ref(false)
const currentQuery = ref('')

// 计算属性
const loading = computed(() => remoteSearch.state.loading)
const options = computed(() => remoteSearch.state.options)

// 方法
const getOptionKey = (option: FormOption) => {
  return option[props.optionValue] ?? option.value
}

const getOptionLabel = (option: FormOption) => {
  return option[props.optionLabel] ?? option.label
}

const getOptionValue = (option: FormOption) => {
  return option[props.optionValue] ?? option.value
}

const handleRemoteSearch = async (query: string) => {
  currentQuery.value = query
  hasSearched.value = true
  await remoteSearch.search(query)
}

const handleChange = (value: string | number) => {
  selectedValue.value = value
  emit('update:modelValue', value)
  emit('change', value)
}

const handleVisibleChange = (visible: boolean) => {
  if (visible && options.value.length === 0 && !hasSearched.value) {
    handleRemoteSearch('')
  }
}

// 监听外部值变化
watch(() => props.modelValue, (newVal) => {
  if (newVal !== selectedValue.value) {
    selectedValue.value = newVal
  }
})

// 暴露方法
defineExpose({
  search: handleRemoteSearch,
  clearCache: remoteSearch.clearCache,
  focus: () => selectRef.value?.focus()
})

// 初始化
onMounted(() => {
  if (props.config.defaultOptions?.length > 0) {
    remoteSearch.setDefaultOptions(props.config.defaultOptions)
  }
})
</script>