<template>
	<a-select v-bind="$attrs" :loading="loading" :options="options" :field-names="fieldNames" @focus="handleFocus">
		<template v-for="(_, slot) of $slots" #[slot]="scope">
			<slot :name="slot" v-bind="scope || {}" />
		</template>
	</a-select>
</template>

<script setup>
import { ref, computed, watch } from 'vue'
import { useDictionaryStore } from '@/stores/modules/dictionary'
import request from '@/utils/request'

defineOptions({
	name: 'ScSelect',
	inheritAttrs: false,
})

const props = defineProps({
	// 数据源类型：data（直接数据）、api（接口数据）、dictionary（字典数据）
	sourceType: {
		type: String,
		default: 'data',
		validator: (value) => ['data', 'api', 'dictionary'].includes(value),
	},
	// 直接数据（当 sourceType 为 data 时使用）
	data: {
		type: Array,
		default: () => [],
	},
	// API 接口地址（当 sourceType 为 api 时使用）
	api: {
		type: String,
		default: '',
	},
	// API 请求参数（当 sourceType 为 api 时使用）
	apiParams: {
		type: Object,
		default: () => ({}),
	},
	// 字典编码（当 sourceType 为 dictionary 时使用）
	dictionaryCode: {
		type: String,
		default: '',
	},
	// 是否启用 API 数据缓存（当 sourceType 为 api 时使用）
	enableApiCache: {
		type: Boolean,
		default: true,
	},
	// API 缓存时间（毫秒，当 sourceType 为 api 时使用）
	apiCacheTime: {
		type: Number,
		default: 5 * 60 * 1000, // 默认 5 分钟
	},
	// 字段映射配置
	fieldNames: {
		type: Object,
		default: () => ({
			label: 'label',
			value: 'value',
		}),
	},
	// 是否在组件挂载时立即加载数据
	immediate: {
		type: Boolean,
		default: false,
	},
	// 数据处理函数，用于自定义数据格式转换
	dataProcessor: {
		type: Function,
		default: null,
	},
})

const dictionaryStore = useDictionaryStore()
const loading = ref(false)
const apiData = ref(null)
const apiCacheTime = ref(null)
const options = computed(() => {
	switch (props.sourceType) {
		case 'data':
			return processData(props.data)
		case 'api':
			return processData(apiData.value || [])
		case 'dictionary':
			return processData(getDictionaryData())
		default:
			return []
	}
})

// API 数据缓存
const apiCache = new Map()

/**
 * 处理数据格式
 */
function processData(data) {
	if (!data || !Array.isArray(data)) {
		return []
	}

	// 如果有自定义处理函数，使用自定义处理
	if (props.dataProcessor && typeof props.dataProcessor === 'function') {
		return props.dataProcessor(data)
	}

	// 默认处理：确保数据有 label 和 value 字段
	return data.map((item) => {
		if (typeof item === 'string' || typeof item === 'number') {
			return {
				label: item,
				value: item,
			}
		}
		// 如果已经有 label 和 value 字段，直接返回
		if (item.label !== undefined && item.value !== undefined) {
			return item
		}
		// 尝试使用 fieldNames 映射
		const labelKey = props.fieldNames.label || 'label'
		const valueKey = props.fieldNames.value || 'value'
		return {
			label: item[labelKey] || item.name || item.title || item.id,
			value: item[valueKey] !== undefined ? item[valueKey] : item.id,
			...item,
		}
	})
}

/**
 * 获取字典数据
 */
function getDictionaryData() {
	if (!props.dictionaryCode) {
		return []
	}
	return dictionaryStore.dictionaries[props.dictionaryCode] || []
}

/**
 * 加载 API 数据
 */
async function loadApiData() {
	if (!props.api) {
		return
	}

	// 检查缓存
	if (props.enableApiCache) {
		const cacheKey = props.api + JSON.stringify(props.apiParams)
		const cached = apiCache.get(cacheKey)

		if (cached && Date.now() - cached.time < props.apiCacheTime) {
			apiData.value = cached.data
			return
		}
	}

	loading.value = true
	try {
		const res = await request.get(props.api, { params: props.apiParams })

		if (res.code === 200) {
			const data = res.data || res.list || []
			apiData.value = data

			// 缓存数据
			if (props.enableApiCache) {
				const cacheKey = props.api + JSON.stringify(props.apiParams)
				apiCache.set(cacheKey, {
					data,
					time: Date.now(),
				})
			}
		}
	} catch (error) {
		console.error('加载 API 数据失败:', error)
		apiData.value = []
	} finally {
		loading.value = false
	}
}

/**
 * 加载字典数据
 */
async function loadDictionaryData() {
	if (!props.dictionaryCode) {
		return
	}

	// 检查缓存
	if (dictionaryStore.dictionaries[props.dictionaryCode]) {
		return
	}

	loading.value = true
	try {
		await dictionaryStore.getDictionary(props.dictionaryCode)
	} catch (error) {
		console.error('加载字典数据失败:', error)
	} finally {
		loading.value = false
	}
}

/**
 * 处理 focus 事件，按需加载数据
 */
async function handleFocus() {
	switch (props.sourceType) {
		case 'api':
			if (!apiData.value || apiData.value.length === 0) {
				await loadApiData()
			}
			break
		case 'dictionary':
			if (!dictionaryStore.dictionaries[props.dictionaryCode]) {
				await loadDictionaryData()
			}
			break
	}
}

/**
 * 强制刷新数据
 */
async function refresh() {
	switch (props.sourceType) {
		case 'api':
			await loadApiData()
			break
		case 'dictionary':
			await dictionaryStore.getDictionary(props.dictionaryCode, true)
			break
	}
}

// 监听数据源变化
watch(
	() => props.data,
	(newVal) => {
		if (props.sourceType === 'data') {
			// data 类型不需要特殊处理，计算属性会自动更新
		}
	},
	{ immediate: true },
)

watch(
	() => props.api,
	() => {
		if (props.sourceType === 'api') {
			apiData.value = null
		}
	},
)

watch(
	() => props.apiParams,
	() => {
		if (props.sourceType === 'api') {
			apiData.value = null
		}
	},
	{ deep: true },
)

watch(
	() => props.dictionaryCode,
	() => {
		if (props.sourceType === 'dictionary') {
			// dictionary 变化时，数据会自动从 store 获取
		}
	},
)

// 组件挂载时立即加载数据
if (props.immediate) {
	switch (props.sourceType) {
		case 'api':
			loadApiData()
			break
		case 'dictionary':
			loadDictionaryData()
			break
	}
}

// 暴露方法供外部调用
defineExpose({
	refresh,
	loadApiData,
	loadDictionaryData,
})
</script>

<style scoped lang="scss">
// 组件样式继承自 a-select
</style>
