<template>
  <el-form ref="formRef" :model="formData" :rules="formRules" label-width="110px" v-bind="$attrs">
    <!-- 动态表单项 -->
    <el-row :gutter="props.rowGutter || 0">
      <template v-for="(item, index) in formItems" :key="index">
        <el-col v-if="item.show !== false" :span="props.colSpan || 24">
          <el-form-item
            :label="item.label"
            :prop="item.prop"
            :required="item.required"
            :label-position="item.labelPosition || 'left'"
            :label-width="item.labelWidth || '125px'"
            :class="item.class"
          >
            <!-- 输入框 -->
            <el-input
              v-if="item.type === 'input'"
              v-model="formData[item.prop]"
              :placeholder="item.placeholder"
              :disabled="item.disabled"
              clearable
            />
            <!-- 密码输入框 -->
            <el-input
              v-else-if="item.type === 'password'"
              v-model="formData[item.prop]"
              :placeholder="item.placeholder"
              :disabled="item.disabled"
              clearable
              show-password
              type="password"
            />
            <!-- 长文本输入框 -->
            <el-input
              v-else-if="item.type === 'textarea'"
              v-model="formData[item.prop]"
              :placeholder="item.placeholder"
              :disabled="item.disabled"
              clearable
              show-password
              type="textarea"
            />
            <!-- 下拉选择框 -->
            <el-select
              v-else-if="item.type === 'select'"
              v-model="formData[item.prop]"
              :placeholder="item.placeholder"
              :disabled="item.disabled"
              clearable
              style="width: 100%"
              @change="handleItemChange(item.prop, formData[item.prop])"
            >
              <el-option
                v-for="option in props.optionsMap?.[item.prop] || []"
                :key="option.value"
                :label="option.label"
                :value="option.value"
              >
                <template v-if="option.icon" #label>
                  <span style="display: flex; align-items: center; gap: 8px">
                    <el-icon v-if="option.icon">
                      <component :is="option.icon" />
                    </el-icon>
                    <span>{{ option.label }}</span>
                  </span>
                </template>
              </el-option>
            </el-select>

            <!-- 数字输入框 -->
            <el-input-number
              v-else-if="item.type === 'number'"
              v-model="formData[item.prop]"
              :min="item.min"
              :max="item.max"
              :placeholder="item.placeholder"
              :disabled="item.disabled"
              :controls="item.controls ?? true"
              :align="item.align || 'left'"
              style="width: 100%"
            />

            <!-- 单选框组 -->
            <el-radio-group v-else-if="item.type === 'radio'" v-model="formData[item.prop]" :disabled="item.disabled">
              <el-radio
                v-for="option in props.optionsMap?.[item.prop] || []"
                :key="option.value"
                :value="option.value"
              >
                {{ option.label }}
              </el-radio>
            </el-radio-group>

            <!-- 复选框组 -->
            <el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="formData[item.prop]">
              <el-checkbox
                v-for="option in props.optionsMap?.[item.prop] || []"
                :key="option.value"
                :value="option.value"
              >
                {{ option.label }}
              </el-checkbox>
            </el-checkbox-group>
            <el-switch
              v-else-if="item.type === 'switch'"
              v-model="formData[item.prop]"
              :active-value="1"
              :inactive-value="2"
            />
            <!-- 日期选择器（单个/范围） -->
            <el-date-picker
              v-else-if="item.type === 'date'"
              v-model="formData[item.prop]"
              :type="item.dateType || 'date'"
              :range-separator="item.rangeSeparator || '至'"
              :start-placeholder="item.startPlaceholder || '开始时间'"
              :end-placeholder="item.endPlaceholder || '结束时间'"
              :value-format="item.valueFormat || 'YYYY-MM-DD'"
              :clearable="item.clearable ?? true"
              :disabled-date="item.disabledDate"
              :locale="'zhCn'"
            />
            <!-- 时间选择器（单个/范围） -->
            <el-time-picker
              v-else-if="item.type === 'time'"
              v-model="formData[item.prop]"
              :range-separator="item.rangeSeparator || '至'"
              :start-placeholder="item.startPlaceholder || '开始时间'"
              :end-placeholder="item.endPlaceholder || '结束时间'"
              :value-format="item.valueFormat || 'HH:mm:ss'"
              :is-range="item.isRange ?? true"
            />
            <!-- 自定义插槽 -->
            <slot v-else :name="item.slotName" :formData="formData" />
          </el-form-item>
        </el-col>
      </template>
    </el-row>
  </el-form>
</template>

<script setup lang="ts">
import type { FormInstance, FormRules } from 'element-plus'
import type { Component } from 'vue'

interface FormItem {
  type:
    | 'input'
    | 'select'
    | 'number'
    | 'radio'
    | 'slot'
    | 'checkbox'
    | 'date'
    | 'switch'
    | 'edit'
    | 'password'
    | 'time'
    | 'upload'
    | 'textarea'
  label: string
  prop: string
  placeholder?: string
  required?: boolean
  disabled?: boolean
  show?: boolean // 控制是否显示
  min?: number
  max?: number
  slotName?: string // 自定义插槽名称
  labelPosition?: 'left' | 'right' | 'top'
  labelWidth?: string
  class?: string
  dateType?: 'date' | 'daterange' | 'monthrange' | 'yearrange' | 'datetimerange'
  timeType?: 'time' | 'timerange'
  rangeSeparator?: string
  startPlaceholder?: string
  endPlaceholder?: string
  valueFormat?: string
  clearable?: boolean
  disabledDate?: (time: Date) => boolean
  isRange?: boolean
  controls?: boolean
  align?: "left" | "right" | "center"
}

interface Props {
  formData: Record<string, any>
  formRules: FormRules
  formItems: FormItem[]
  optionsMap?: Record<
    string,
    Array<{
      label: string | undefined
      value: string | number
      icon?: Component
    }>
  >
  rowGutter?: number // 新增：全局栅格间距（默认0）
  colSpan?: number // 新增：全局表单项列宽（默认24）
}

const formRef = ref<FormInstance>()
const props = defineProps<Props>()
const emit = defineEmits(['form-item-change'])

const handleItemChange = (field: string, value: any) => {
  emit('form-item-change', field, value)
}
// 暴露表单验证方法
defineExpose({
  validate: () => formRef.value?.validate(),
  resetFields: () => formRef.value?.resetFields(),
})
</script>
