<template>
    <el-select
        ref="selectRef"
        v-show="typeof(row.show) === 'function' ? row.show?.(modelData): true"
        v-model="model"
        class="info-select"
        :filterable="row.filterable"
        :allow-create="row.isCustom"
        :clearable="typeof(row.clearable) === 'function' ? row.clearable() : row.clearable"
        default-first-option
        :collapse-tags="row.collapseTags"
        :placeholder="$t(row.placeholder?.() || 'pleaseSelect')"
        :multiple-limit="row.multipleLimit"
        :no-data-text="$t(row.noDataText || 'noData')"
        :disabled="row.disabled?.(modelData)"
        :value-key="row.optionsValue || 'value'"
        :multiple="row.multiple"
        :size="row.size"
        :teleported="row.teleported === undefined ? true : row.teleported"
        :popper-class="row.popperClass"
        :loading="row.loading?.()"
        @visible-change="visibleChanges"
        @change="changes"
        @remove-tag="removeTag"
        @clear="clear"
    >
        <!-- 这里需要加一个空字符串，否则会报错 -->
        <el-option
            v-for="(item, index) in options.list"
            :key="index"
            :label="row.i18n ? getLabel(item) + '' : $t(getLabel(item) + '')"
            :value="getValue(item)"
            :disabled="item.disabled?.()"
        />
        <!-- <template #prefix v-if="!!row.prefixIcon">
            <i
                :class="['el-input__icon', row.prefixIcon]"
            />
        </template> -->
    </el-select>
</template>
<script lang="ts">
import { defineComponent, PropType, reactive, ref, onMounted, onBeforeUnmount } from 'vue'
import { isPromise, ObjectInterface } from '../../../script'
import { OptionsInterface, SelectInterface } from './index'
import useModel from '../../../script/help/useModel'

export default defineComponent({
    name: 'InfoSelect',
    props: {
        row: {
            type: Object as PropType<SelectInterface>,
            default: () => {}
        },
        modelData: {
            type: Object,
            default: () => {}
        },
        addIndex: {
            type: [Number, String],
            default: () => ''
        }
    },
    emits: ['change'],
    setup (props, ctx) {
        // eslint-disable-next-line vue/no-setup-props-destructure
        const { modelData, row } = props
        const selectRef = ref()
        const model = useModel(modelData, row.model, row.deepData, props.addIndex)
        // 保存用户输入的自定义值（用于失焦自动确认）
        const pendingCustomValue = ref('')
        // 缓存 input 元素引用，确保事件监听正确移除
        let inputEl: HTMLInputElement | null = null
        const options = reactive<OptionsInterface>({
            list: row.options(modelData)
        })

        // 监听 input 事件的处理函数（只保存非空值，避免 el-select 关闭时清空覆盖）
        const handleInput = (e: Event) => {
            const target = e.target as HTMLInputElement
            if (target.value) {
                pendingCustomValue.value = target.value
            }
        }

        // 挂载时添加 input 事件监听
        onMounted(() => {
            if (row.isCustom && row.filterable && selectRef.value?.$el) {
                // 多选模式使用 .el-select__input，单选模式使用 .el-input__inner
                const selector = row.multiple
                    ? '.el-select__input'
                    : '.el-input__inner'
                inputEl = selectRef.value.$el.querySelector(selector) || selectRef.value.$el.querySelector('input')
                if (inputEl) {
                    inputEl.addEventListener('input', handleInput)
                    inputEl.addEventListener('compositionend', handleInput)
                }
            }
        })

        // 卸载时移除事件监听
        onBeforeUnmount(() => {
            if (inputEl) {
                inputEl.removeEventListener('input', handleInput)
                inputEl.removeEventListener('compositionend', handleInput)
                inputEl = null
            }
        })
        const getLabel = (item: ObjectInterface): string | number => {
            return row.optionsLabel ? item[row.optionsLabel] : item.label
        }
        const getValue = (item: ObjectInterface): string | number | boolean | object => {
            return row.valueItem ? item : row.optionsValue ? item[row.optionsValue] : item.value
        }
        const getSelectValue = (value: any): ObjectInterface[] => { // 获取选中的值
            let valueList = value instanceof Array ? value : [value]
            let key = row.optionsValue || 'value'
            return options.list.filter((option: ObjectInterface) => valueList.includes(option[key]))
        }
        const changes = (value: any): void => {
            ctx.emit('change')
            if (row.methods) {
                let item = row.valueItem ? value : getSelectValue(value)
                row.methods(value, row.multiple ? item : item[0], modelData)
            }
        }
        const removeTag = (tagVal) => row.removeTag && row.removeTag(tagVal)
        const clear = () => row.clear && row.clear()
        const visibleChanges = (isDropDown: boolean): void => {
            // 失焦时自动确认自定义输入值
            if (!isDropDown && row.isCustom && row.filterable) {
                // 优先使用暂存值，如果为空则尝试从 DOM 读取
                let inputValue = pendingCustomValue.value?.trim()
                if (!inputValue && inputEl && inputEl.value) {
                    inputValue = inputEl.value.trim()
                }

                if (inputValue) {
                    // 检查是否已存在于选项列表中
                    const existsInOptions = options.list.some((item: any) => {
                        const itemLabel = row.optionsLabel ? item[row.optionsLabel] : item.label
                        const itemValue = row.optionsValue ? item[row.optionsValue] : item.value
                        return String(itemValue) === inputValue || String(itemLabel) === inputValue
                    })

                    // 如果输入的值不在选项列表中（真正的自定义值），自动设置
                    if (!existsInOptions) {
                        if (row.multiple) {
                            // 多选模式：追加到数组（避免重复）
                            const currentArr = Array.isArray(model.value) ? model.value : []
                            if (!currentArr.includes(inputValue)) {
                                model.value = [...currentArr, inputValue]
                                changes(model.value)
                            }
                        } else {
                            // 单选模式：直接替换
                            if (inputValue !== model.value) {
                                model.value = inputValue
                                changes(inputValue)
                            }
                        }
                    }
                }
                // 清空暂存值
                pendingCustomValue.value = ''
            }

            // 原有逻辑
            row.visibleChanges?.(isDropDown, model, modelData, row)
            if (isDropDown) {
                // 打开下拉框时清空上次暂存值
                pendingCustomValue.value = ''
                options.list = row.options(modelData)
                if (isPromise(options.list)) {
                    options.list!.then((res: any[]) => {
                        options.list = res
                    })
                }
            }
        }
        return {
            selectRef,
            model,
            options,
            getLabel,
            getValue,
            changes,
            visibleChanges,
            removeTag,
            clear
        }
    }
})
</script>
<style lang="scss" scoped>
.el-select {
    width: 100%;
}
</style>

