<template>
    <el-card class="search-form-card" v-show="showSearch">
        <el-form ref="formRef" :inline="true" :model="formData" :label-width="labelWidth">
            <el-form-item
                :key="item.prop"
                :label="item.label"
                :prop="item.prop"
                v-for="item in formColumns"
            >
                <component
                    @enter="handleSearch"
                    :is="getFormComponent(item)"
                    v-model="formData[item.prop]"
                    v-bind="getComponentProps(item)"
                />
            </el-form-item>
            <el-form-item>
                <ComButton type="primary" icon="Search" @click="handleSearch">搜索</ComButton>
                <ComButton type="warning" plain icon="Refresh" @click="handleReset">重置</ComButton>
            </el-form-item>
        </el-form>
    </el-card>
</template>

<script setup>
import { ref, reactive, watch } from 'vue'
import ComButton from '@/components/ComButton/index.vue'
import ItemInput from './FormItem/ItemInput.vue'
import ItemSelect from './FormItem/ItemSelect.vue'
import ItemDate from './FormItem/ItemDate.vue'
import ItemCascader from './FormItem/ItemCascader.vue'

const props = defineProps({
    // 表单列配置
    formColumns: {
        type: Array,
        default: () => [],
    },
    // 是否显示搜索表单
    showSearch: {
        type: Boolean,
        default: true,
    },
    // 表单大小
    size: {
        type: String,
        default: 'default',
    },
    // 表单标签宽度
    labelWidth: {
        type: String,
        default: 'auto',
    },
    // 默认表单数据
    defaultFormData: {
        type: Object,
        default: () => ({}),
    },
})

const emit = defineEmits(['search', 'reset'])

const formRef = ref(null)
const formData = reactive({})

// 组件映射表
const componentMap = {
    input: ItemInput,
    select: ItemSelect,
    date: ItemDate,
    month: ItemDate,
    cascader: ItemCascader,
}

// 初始化表单数据
const initFormData = () => {
    props.formColumns.forEach((item) => {
        if (props.defaultFormData[item.prop] !== undefined) {
            formData[item.prop] = props.defaultFormData[item.prop]
        } else {
            formData[item.prop] =
                item.defaultValue ??
                (item.type === 'date' && item.dateType?.includes('range') ? [] : '')
        }
    })
}

// 获取表单组件
const getFormComponent = (item) => {
    return componentMap[item.type] || ItemInput
}

// 获取组件属性
const getComponentProps = (item) => {
    const baseProps = {
        placeholder: item.placeholder,
        clearable: item.clearable !== false,
        disabled: item.disabled || false,
        style: item.style || {
            width: '200px',
        },
    }

    switch (item.type) {
        case 'select':
            return {
                ...baseProps,
                options: item.options || [],
            }
        case 'date':
            return {
                ...baseProps,
                dateType: item.dateType || 'date',
                valueFormat: item.valueFormat || 'YYYY-MM-DD',
                rangeSeparator: item.rangeSeparator || '-',
                startPlaceholder: item.startPlaceholder,
                endPlaceholder: item.endPlaceholder,
                style: item.style,
            }
        case 'month':
            return {
                ...baseProps,
                dateType: 'month',
                valueFormat: item.valueFormat || 'YYYY-MM',
            }
        case 'cascader':
            return {
                ...baseProps,
                options: item.options || [],
                props: item.props || {},
            }
        default:
            return baseProps
    }
}

// 处理表单数据，将 paramsList 配置的数组值转换为指定参数名
const processFormData = (data) => {
    const processedData = { ...data }

    props.formColumns.forEach((item) => {
        // 检查是否有 paramsList 配置
        if (item.paramsList && Array.isArray(item.paramsList) && item.paramsList.length > 0) {
            const value = processedData[item.prop]

            // 如果值是数组且不为空，将其拆分为指定的参数名
            if (Array.isArray(value) && value.length > 0) {
                item.paramsList.forEach((paramName, index) => {
                    if (
                        value[index] !== undefined &&
                        value[index] !== null &&
                        value[index] !== ''
                    ) {
                        processedData[paramName] = value[index]
                    }
                })
            }

            // 删除原来的数组字段，避免出现 month[0] 和 month[1] 的形式
            delete processedData[item.prop]
        }
    })

    return processedData
}

// 搜索
const handleSearch = () => {
    const processedData = processFormData(formData)
    emit('search', processedData)
}

// 重置
const handleReset = () => {
    formRef.value?.resetFields()
    initFormData()
    const processedData = processFormData(formData)
    emit('reset', processedData)
}

// 暴露方法供父组件调用
defineExpose({
    getFormData: () => processFormData(formData),
    resetForm: handleReset,
    formRef,
})

// 初始化
initFormData()

// 监听表单列变化
watch(
    () => props.formColumns,
    () => {
        initFormData()
    },
    { deep: true },
)
</script>

<style scoped>
.search-form-card {
    margin-bottom: 10px;
}

.search-form-card :deep(.el-card__body) {
    padding: 20px 20px 5px 20px !important;
}

.el-form--inline .el-form-item {
    margin-right: 10px;
}
</style>
