<template>
    <!-- 添加过渡动画，让搜索表单显示/隐藏更平滑 -->
    <transition name="search-form-fade">
        <el-card class="search-form-card" v-show="showSearch">
            <el-form ref="formRef" :model="formData" :label-width="labelWidth" :size="size">
                <el-row :gutter="10" style="display: flex; align-items: center">
                    <!-- 左侧表单区域：使用Grid布局，每行固定5个表单项 -->
                    <el-col :span="22" class="form-col">
                        <div class="form-grid">
                            <el-form-item
                                v-for="item in formColumns"
                                :key="item.prop"
                                :label="item.label"
                                :prop="item.prop"
                            >
                                <component
                                    @enter="handleSearch"
                                    :is="getFormComponent(item)"
                                    v-model="formData[item.prop]"
                                    v-bind="getComponentProps(item)"
                                />
                            </el-form-item>
                        </div>
                    </el-col>
                    <!-- 右侧按钮区域：垂直居中显示 -->
                    <el-col :span="2" class="button-col">
                        <div class="button-wrapper">
                            <ComButton type="primary" icon="Search" @click="handleSearch">
                                搜索
                            </ComButton>
                            <ComButton
                                style="margin-left: 0"
                                type="warning"
                                plain
                                icon="Refresh"
                                @click="handleReset"
                            >
                                重置
                            </ComButton>
                        </div>
                    </el-col>
                </el-row>
            </el-form>
        </el-card>
    </transition>
</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) => {
    // 如果用户自定义了 style，使用用户的 style，否则不设置 style（让组件继承父容器宽度）
    const baseProps = {
        placeholder: item.placeholder,
        clearable: item.clearable !== false,
        disabled: item.disabled || false,
        ...(item.style && { style: item.style }),
    }

    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,
                ...(item.style && { style: item.style }),
            }
        case 'month':
            return {
                ...baseProps,
                dateType: 'month',
                valueFormat: item.valueFormat || 'YYYY-MM',
            }
        case 'cascader':
            return {
                ...baseProps,
                options: item.options || [],
            }
        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: 15px 10px 5px 20px !important;
}

/* 搜索表单显示/隐藏动画 */
.search-form-fade-enter-active,
.search-form-fade-leave-active {
    transition: opacity 0.2s ease, transform 0.2s ease;
}

.search-form-fade-enter-from,
.search-form-fade-leave-to {
    opacity: 0;
    transform: translateY(-6px);
}

/* 左侧表单区域 */
.form-col {
    border-right: 1px solid #e6e6e6;
    padding-right: 10px;
}

/* Grid布局：每行固定5个表单项 */
.form-grid {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 10px;
}

/* 表单项样式 */
.form-grid :deep(.el-form-item) {
    margin-bottom: 8px;
}

.form-grid :deep(.el-form-item__label) {
    padding-right: 8px;
}

/* 确保所有表单组件宽度为100%，继承父容器宽度 */
.form-grid :deep(.el-form-item__content) {
    width: 100%;
}

/* 覆盖所有表单组件的宽度，使其继承父容器宽度 */
.form-grid :deep(.el-input),
.form-grid :deep(.el-input__wrapper),
.form-grid :deep(.el-select),
.form-grid :deep(.el-date-editor),
.form-grid :deep(.el-cascader) {
    width: 100% !important;
}

/* 确保输入框内部元素也自适应 */
.form-grid :deep(.el-input__inner) {
    width: 100%;
}

/* 右侧按钮区域 */
.button-col {
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding-left: 10px;
    padding-top: 0;
    min-height: fit-content;
    /* 与表单第一行输入框对齐 */
    /* 由于表单项 margin-bottom: 8px，第一行从顶部开始 */
    /* 如果表单项有label，需要加上label的高度来对齐输入框 */
}

.button-wrapper {
    display: flex;
    flex-direction: column;
    gap: 10px;
    width: 100%;
    justify-content: center;
    align-items: center;
}

/* 确保按钮宽度一致，高度与表单输入框一致（32px） */
.button-wrapper :deep(.el-button) {
    width: 100%;
    min-width: 0;
    height: 32px;
    padding: 0 15px;
    box-sizing: border-box;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    white-space: nowrap;
    flex-shrink: 0;
}

/* 确保按钮内部图标和文字对齐 */
.button-wrapper :deep(.el-button) > i,
.button-wrapper :deep(.el-button) > span {
    display: inline-flex;
    align-items: center;
    line-height: 1;
}
</style>
