<!-- src/components/RemoteMultiSelect.vue -->
<template>
  <el-select
    v-model="selectedValues"
    :placeholder="placeholder"
    :multiple="multiple"
    :filterable="remote || filterable"
    :remote="remote"
    :remote-method="handleRemoteSearch"
    :loading="loading"
    :reserve-keyword="false"
    :clearable="clearable"
    :collapse-tags="collapseTags"
    :max-collapse-tags="maxCollapseTags"
    :size="size"
    :popper-class="['remote-multi-select', popperClass]"
    :disabled="disabled"
    @change="handleChange"
    @visible-change="handleVisibleChange"
  >
    <!-- 自定义下拉头部：全选功能 -->
    <template #header v-if="showCheckAll && multiple">
      <div class="select-header">
        <el-checkbox
          v-model="checkAll"
          :indeterminate="indeterminate"
          @change="handleCheckAllChange"
          :disabled="disabled"
        >
          {{ checkAllLabel }}
        </el-checkbox>
      </div>
    </template>
    
    <!-- 选项列表 -->
    <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 { computed, ref, watch, toRefs, defineProps, defineEmits } from 'vue'
import { useRemoteSearch } from '@/hooks/useRemoteSearch'
import type { RemoteSearchConfig } from '@/hooks/useRemoteSearch'

interface OptionItem {
  label: string
  value: string | number
  disabled?: boolean
  [key: string]: any
}

interface Props {
  modelValue: (string | number)[] | string | number
  config: RemoteSearchConfig
  placeholder?: string
  multiple?: boolean
  clearable?: boolean
  collapseTags?: boolean
  maxCollapseTags?: number
  size?: 'large' | 'default' | 'small'
  disabled?: boolean
  showCheckAll?: boolean
  checkAllLabel?: string
  popperClass?: string
  
  // 自定义选项键名
  labelKey?: string
  valueKey?: string
  optionKey?: string
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: () => ([]),
  placeholder: '请选择',
  multiple: true,
  clearable: true,
  collapseTags: true,
  maxCollapseTags: 1,
  size: 'large',
  disabled: false,
  showCheckAll: true,
  checkAllLabel: '全选',
  labelKey: 'label',
  valueKey: 'value',
  optionKey: 'value'
})

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

const {
  config,
  multiple,
  showCheckAll,
  checkAllLabel,
  labelKey,
  valueKey,
  optionKey
} = toRefs(props)

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

// 本地状态
const selectedValues = ref<(string | number)[] | string | number>(
  Array.isArray(props.modelValue) ? [...props.modelValue] : props.modelValue
)
const hasSearched = ref(false)
const currentQuery = ref('')

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

const checkAll = computed({
  get() {
    if (!props.multiple || !Array.isArray(selectedValues.value)) return false
    const enabledOptions = options.value.filter(opt => !opt.disabled)
    return selectedValues.value.length === enabledOptions.length && enabledOptions.length > 0
  },
  set(val: boolean) {
    handleCheckAllChange(val)
  }
})

const indeterminate = computed(() => {
  if (!props.multiple || !Array.isArray(selectedValues.value)) return false
  const enabledOptions = options.value.filter(opt => !opt.disabled)
  return selectedValues.value.length > 0 && selectedValues.value.length < enabledOptions.length
})

// 方法
const getOptionKey = (option: OptionItem) => {
  return option[optionKey.value] ?? option.value
}

const getOptionLabel = (option: OptionItem) => {
  return option[labelKey.value] ?? option.label
}

const getOptionValue = (option: OptionItem) => {
  return option[valueKey.value] ?? option.value
}

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

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

const handleCheckAllChange = (checked: boolean) => {
  if (!props.multiple) return
  
  if (checked) {
    // 全选：只选择非禁用的选项
    selectedValues.value = options.value
      .filter(opt => !opt.disabled)
      .map(opt => getOptionValue(opt))
  } else {
    selectedValues.value = []
  }
  
  emit('update:modelValue', selectedValues.value)
  emit('change', selectedValues.value)
}

const handleVisibleChange = (visible: boolean) => {
  if (visible && options.value.length === 0 && !hasSearched.value) {
    // 下拉框打开时，如果没有搜索过，执行一次搜索
    handleRemoteSearch('')
  }
}

// 监听外部值变化
watch(() => props.modelValue, (newVal) => {
  if (JSON.stringify(newVal) !== JSON.stringify(selectedValues.value)) {
    selectedValues.value = newVal
  }
}, { deep: true })

// 监听配置变化
watch(() => props.config, (newConfig) => {
  // 重新初始化远程搜索实例（实际实现中可能需要更复杂的处理）
  Object.assign(remoteSearch, useRemoteSearch(newConfig))
}, { deep: true })

// 初始化
if (config.value.defaultOptions?.length > 0) {
  remoteSearch.setDefaultOptions(config.value.defaultOptions)
}

// 暴露方法给父组件
defineExpose({
  search: handleRemoteSearch,
  clearCache: remoteSearch.clearCache,
  preload: remoteSearch.preload
})
</script>

<style scoped>
.select-header {
  padding: 8px 12px;
  border-bottom: 1px solid var(--el-border-color-lighter);
  background-color: var(--el-bg-color);
  
  .el-checkbox {
    width: 100%;
    
    .el-checkbox__label {
      font-weight: 500;
      color: var(--el-color-primary);
    }
  }
}

.empty-options {
  padding: 8px 12px;
  text-align: center;
  color: var(--el-text-color-secondary);
  font-size: 14px;
}
</style>

<style>
.remote-multi-select .el-select-dropdown__list {
  padding-top: 0;
}

.remote-multi-select .el-select-dropdown__item {
  padding: 8px 12px;
}

.remote-multi-select .el-select-dropdown__item.selected {
  background-color: var(--el-color-primary-light-9);
}

.remote-multi-select .el-select-dropdown__item.is-disabled {
  opacity: 0.6;
}
</style>