<template>
    <div class="dynamic-component">
        <el-form-item
            :label="config.name"
            :required="isRequired"
            :error="hasError ? errorMessage : undefined"
        >
            <!-- 输入框 -->
            <el-input
                v-if="config.renderType === 'input'"
                v-model="inputValue"
                :type="getInputType()"
                :placeholder="config.description"
                :disabled="disabled"
                clearable
                @blur="handleValidation"
                @input="handleInput"
            />

            <!-- 数字输入框 -->
            <el-input-number
                v-else-if="config.renderType === 'number'"
                v-model="inputValue"
                :placeholder="config.description"
                :disabled="disabled"
                :min="getNumberMin()"
                :max="getNumberMax()"
                :precision="getNumberPrecision()"
                @blur="handleValidation"
                @change="handleInput"
            />

            <!-- 文本域 -->
            <el-input
                v-else-if="config.renderType === 'textarea'"
                v-model="inputValue"
                type="textarea"
                :placeholder="config.description"
                :disabled="disabled"
                :rows="4"
                resize="vertical"
                @blur="handleValidation"
                @input="handleInput"
            />

            <!-- 下拉选择 -->
            <el-select
                v-else-if="config.renderType === 'select'"
                v-model="inputValue"
                :placeholder="`请选择${config.name || ''}`"
                :disabled="disabled"
                clearable
                filterable
                @change="handleInput"
                @blur="handleValidation"
            >
                <el-option
                    v-for="option in selectOptions"
                    :key="option.value"
                    :label="option.label"
                    :value="option.value"
                />
            </el-select>

            <!-- 多选下拉 -->
            <el-select
                v-else-if="config.renderType === 'multiSelect'"
                v-model="checkboxValues"
                :placeholder="`请选择${config.name || ''}`"
                :disabled="disabled"
                multiple
                collapse-tags
                filterable
                @change="handleCheckboxChange"
                @blur="handleValidation"
            >
                <el-option
                    v-for="option in selectOptions"
                    :key="option.value"
                    :label="option.label"
                    :value="option.value"
                />
            </el-select>

            <!-- 复选框组 -->
            <el-checkbox-group
                v-else-if="config.renderType === 'checkbox'"
                v-model="checkboxValues"
                :disabled="disabled"
                @change="handleCheckboxChange"
            >
                <el-checkbox
                    v-for="option in checkboxOptions"
                    :key="option.value"
                    :label="option.value"
                >
                    {{ option.label }}
                </el-checkbox>
            </el-checkbox-group>

            <!-- 单选框组 -->
            <el-radio-group
                v-else-if="config.renderType === 'radio'"
                v-model="inputValue"
                :disabled="disabled"
                @change="handleInput"
            >
                <el-radio
                    v-for="option in radioOptions"
                    :key="option.value"
                    :label="option.value"
                >
                    {{ option.label }}
                </el-radio>
            </el-radio-group>

            <!-- 开关 -->
            <el-switch
                v-else-if="config.renderType === 'switch'"
                v-model="switchValue"
                :disabled="disabled"
                active-text="开启"
                inactive-text="关闭"
                @change="handleSwitchChange"
            />

            <!-- 日期选择器 -->
            <el-date-picker
                v-else-if="config.renderType === 'date'"
                v-model="inputValue"
                type="date"
                :placeholder="`选择${config.name || '日期'}`"
                :disabled="disabled"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
                @change="handleInput"
                @blur="handleValidation"
            />

            <!-- 日期时间选择器 -->
            <el-date-picker
                v-else-if="config.renderType === 'datetime'"
                v-model="inputValue"
                type="datetime"
                :placeholder="`选择${config.name || '日期时间'}`"
                :disabled="disabled"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss"
                @change="handleInput"
                @blur="handleValidation"
            />

            <!-- 日期范围选择器 -->
            <el-date-picker
                v-else-if="config.renderType === 'dateRange'"
                v-model="dateRangeValue"
                type="daterange"
                range-separator="至"
                start-placeholder="开始日期"
                end-placeholder="结束日期"
                :disabled="disabled"
                format="YYYY-MM-DD"
                value-format="YYYY-MM-DD"
                @change="handleDateRangeChange"
                @blur="handleValidation"
            />

            <!-- 日期时间范围选择器 -->
            <el-date-picker
                v-else-if="config.renderType === 'datetimeRange'"
                v-model="dateRangeValue"
                type="datetimerange"
                range-separator="至"
                start-placeholder="开始时间"
                end-placeholder="结束时间"
                :disabled="disabled"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="YYYY-MM-DD HH:mm:ss"
                @change="handleDateRangeChange"
                @blur="handleValidation"
            />

            <!-- 时间选择器 -->
            <el-time-picker
                v-else-if="config.renderType === 'time'"
                v-model="inputValue"
                :placeholder="`选择${config.name || '时间'}`"
                :disabled="disabled"
                format="HH:mm:ss"
                value-format="HH:mm:ss"
                @change="handleInput"
                @blur="handleValidation"
            />

            <!-- 颜色选择器 -->
            <el-color-picker
                v-else-if="config.renderType === 'color'"
                v-model="inputValue"
                :disabled="disabled"
                show-alpha
                @change="handleInput"
            />

            <!-- 评分 -->
            <el-rate
                v-else-if="config.renderType === 'rate'"
                v-model="inputValue"
                :disabled="disabled"
                :max="getRateMax()"
                show-score
                @change="handleInput"
            />

            <!-- 滑块 -->
            <el-slider
                v-else-if="config.renderType === 'slider'"
                v-model="inputValue"
                :disabled="disabled"
                :min="getNumberMin()"
                :max="getNumberMax()"
                :step="getSliderStep()"
                show-input
                @change="handleInput"
            />

            <!-- 级联选择器 -->
            <el-cascader
                v-else-if="config.renderType === 'cascader'"
                v-model="inputValue"
                :options="cascaderOptions"
                :placeholder="`请选择${config.name || ''}`"
                :disabled="disabled"
                clearable
                filterable
                @change="handleInput"
                @blur="handleValidation"
            />

            <!-- 树形选择 -->
            <el-tree-select
                v-else-if="config.renderType === 'treeSelect'"
                v-model="inputValue"
                :data="treeOptions"
                :placeholder="`请选择${config.name || ''}`"
                :disabled="disabled"
                clearable
                filterable
                @change="handleInput"
            />

            <!-- 上传组件 -->
            <el-upload
                v-else-if="config.renderType === 'upload'"
                class="upload-demo"
                :action="uploadAction"
                :on-success="handleUploadSuccess"
                :file-list="fileList"
                :disabled="disabled"
                :limit="getUploadLimit()"
                :accept="getUploadAccept()"
            >
                <el-button type="primary" :disabled="disabled">
                    <el-icon><Upload /></el-icon>
                    上传文件
                </el-button>
            </el-upload>

            <template #label v-if="config.description">
                <span>{{ config.name }}</span>
                <el-tooltip :content="config.description" placement="top">
                    <el-icon class="description-icon"><QuestionFilled /></el-icon>
                </el-tooltip>
            </template>
        </el-form-item>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue'
import type { SysConfigVO } from '@/types/sys/config'

interface Props {
    config: SysConfigVO
    modelValue?: any
    disabled?: boolean
    required?: boolean
}

interface Emits {
    (e: 'update:modelValue', value: any): void
    (e: 'change', value: any): void
    (e: 'blur', value: any): void
}

const props = withDefaults(defineProps<Props>(), {
    disabled: false,
    required: false
})

const emit = defineEmits<Emits>()

// 内部值状态
const inputValue = ref('')
const checkboxValues = ref<string[]>([])
const switchValue = ref(false)
const dateRangeValue = ref<[string, string] | null>(null)
const fileList = ref<any[]>([])

// 错误状态
const hasError = ref(false)
const errorMessage = ref('')

// 计算属性
const isRequired = computed(() => props.required || (props.config.re && props.config.re.required))

const selectOptions = computed(() => {
    if (!props.config.options) return []
    if (Array.isArray(props.config.options)) {
        return props.config.options
    }
    // 如果是对象形式，转换为数组
    return Object.entries(props.config.options).map(([key, value]) => ({
        value: key,
        label: value as string
    }))
})

const checkboxOptions = computed(() => selectOptions.value)
const radioOptions = computed(() => selectOptions.value)

// 扩展选项计算属性
const cascaderOptions = computed(() => {
    if (!props.config.options) return []
    return Array.isArray(props.config.options) ? props.config.options : []
})

const treeOptions = computed(() => {
    if (!props.config.options) return []
    return Array.isArray(props.config.options) ? props.config.options : []
})

// 上传相关配置
const uploadAction = computed(() => {
    return props.config.re?.uploadUrl || '/api/upload'
})

// 获取输入框类型
const getInputType = () => {
    const configType = props.config.configType?.toLowerCase()
    switch (configType) {
        case 'integer':
        case 'float':
        case 'double':
            return 'number'
        case 'boolean':
            return 'checkbox'
        default:
            return 'text'
    }
}

// 值转换函数
const convertValue = (value: any) => {
    if (value === null || value === undefined || value === '') {
        return value
    }

    const configType = props.config.configType?.toLowerCase()
    switch (configType) {
        case 'integer':
            return parseInt(value, 10)
        case 'float':
        case 'double':
            return parseFloat(value)
        case 'boolean':
            return Boolean(value)
        default:
            return String(value)
    }
}

// 获取数字相关配置
const getNumberMin = () => {
    return props.config.re?.min ?? 0
}

const getNumberMax = () => {
    return props.config.re?.max ?? 100
}

const getNumberPrecision = () => {
    const configType = props.config.configType?.toLowerCase()
    if (configType === 'integer') return 0
    return props.config.re?.precision ?? 2
}

const getSliderStep = () => {
    return props.config.re?.step ?? 1
}

const getRateMax = () => {
    return props.config.re?.max ?? 5
}

const getUploadLimit = () => {
    return props.config.re?.limit ?? 1
}

const getUploadAccept = () => {
    return props.config.re?.accept || '*'
}

// 校验函数
const validateValue = (value: any): { valid: boolean; message?: string } => {
    const rules = props.config.re
    if (!rules) return { valid: true }

    // 必填校验
    if (rules.required && (!value || (Array.isArray(value) && value.length === 0))) {
        return { valid: false, message: `${props.config.name}是必填项` }
    }

    // 如果值为空且非必填，跳过其他校验
    if (!value && !rules.required) {
        return { valid: true }
    }

    // 正则校验
    if (rules.pattern && typeof value === 'string') {
        const regex = new RegExp(rules.pattern)
        if (!regex.test(value)) {
            return { valid: false, message: rules.message || `${props.config.name}格式不正确` }
        }
    }

    // 最小长度校验
    if (rules.minLength && value.length < rules.minLength) {
        return { valid: false, message: `${props.config.name}最少需要${rules.minLength}个字符` }
    }

    // 最大长度校验
    if (rules.maxLength && value.length > rules.maxLength) {
        return { valid: false, message: `${props.config.name}最多允许${rules.maxLength}个字符` }
    }

    // 最小值校验
    if (rules.min !== undefined && Number(value) < rules.min) {
        return { valid: false, message: `${props.config.name}不能小于${rules.min}` }
    }

    // 最大值校验
    if (rules.max !== undefined && Number(value) > rules.max) {
        return { valid: false, message: `${props.config.name}不能大于${rules.max}` }
    }

    return { valid: true }
}

// 事件处理
const handleInput = () => {
    let value = inputValue.value
    
    // 数据类型转换
    value = convertValue(value)
    
    emit('update:modelValue', value)
    emit('change', value)
    
    // 清除错误状态（输入时）
    if (hasError.value) {
        hasError.value = false
        errorMessage.value = ''
    }
}

const handleCheckboxChange = () => {
    // 复选框直接使用数组值，不进行转换
    const value = checkboxValues.value
    emit('update:modelValue', value)
    emit('change', value)
}

const handleSwitchToggle = () => {
    if (props.disabled) return
    
    switchValue.value = !switchValue.value
    const value = convertValue(switchValue.value)
    
    emit('update:modelValue', value)
    emit('change', value)
}

const handleSwitchChange = (value: boolean) => {
    switchValue.value = value
    emit('update:modelValue', value)
    emit('change', value)
}

const handleDateRangeChange = (value: [string, string] | null) => {
    dateRangeValue.value = value
    emit('update:modelValue', value)
    emit('change', value)
}

const handleUploadSuccess = (response: any, file: any, fileList: any[]) => {
    const urls = fileList.map(item => item.response?.url || item.url).filter(Boolean)
    emit('update:modelValue', urls)
    emit('change', urls)
}

const handleValidation = () => {
    let value: any = inputValue.value
    
    // 处理复选框和多选下拉的值
    if (props.config.renderType === 'checkbox' || props.config.renderType === 'multiSelect') {
        value = checkboxValues.value
    }
    // 处理开关的值
    else if (props.config.renderType === 'switch') {
        value = switchValue.value
    }
    // 处理日期范围的值
    else if (props.config.renderType === 'dateRange' || props.config.renderType === 'datetimeRange') {
        value = dateRangeValue.value
    }
    
    const validation = validateValue(value)
    hasError.value = !validation.valid
    errorMessage.value = validation.message || ''
    
    emit('blur', value)
}

// 初始化值
const initializeValue = () => {
    const modelValue = props.modelValue
    
    if (props.config.renderType === 'checkbox' || props.config.renderType === 'multiSelect') {
        if (Array.isArray(modelValue)) {
            checkboxValues.value = modelValue
        } else if (typeof modelValue === 'string' && modelValue) {
            // 处理逗号分隔的字符串
            checkboxValues.value = modelValue.split(',').map(v => v.trim())
        } else {
            checkboxValues.value = modelValue ? [modelValue] : []
        }
    } else if (props.config.renderType === 'switch') {
        switchValue.value = Boolean(modelValue)
    } else if (props.config.renderType === 'dateRange' || props.config.renderType === 'datetimeRange') {
        dateRangeValue.value = Array.isArray(modelValue) && modelValue.length === 2 ? modelValue as [string, string] : null
    } else {
        inputValue.value = modelValue || props.config.value || ''
    }
}

// 监听 modelValue 变化
watch(() => props.modelValue, () => {
    initializeValue()
}, { immediate: true })

// 组件挂载时初始化
onMounted(() => {
    initializeValue()
})

// 暴露校验方法给父组件
defineExpose({
    validate: () => {
        handleValidation()
        return !hasError.value
    },
    clearError: () => {
        hasError.value = false
        errorMessage.value = ''
    }
})
</script>

<style lang="scss" scoped>
@import url("./DynamicComponent.scss");
</style>