<template>
  <el-form ref="formRef" :model="formData" :rules="formRules" :label-width="labelWidth" :label-position="labelPosition"
    :size="size" :disabled="disabled" :inline="inline" v-bind="$attrs">
    <!-- 内联表单 -->
    <template v-if="inline">
      <el-form-item v-for="(item, index) in formConfig" :key="index" :label="item.label" :prop="item.name"
        :required="item.req" :rules="getItemRules(item)">
        <!-- 输入框 -->
        <el-input v-if="item.type === 'text'" v-model="formData[item.name]"
          :placeholder="item.placeholder || `请输入${item.label}`" :clearable="item.clearable !== false"
          :disabled="item.disabled" :maxlength="item.maxlength" :show-word-limit="item.showWordLimit"
          v-bind="item.props" />

        <!-- 文本域 -->
        <el-input v-else-if="item.type === 'textarea'" v-model="formData[item.name]" type="textarea"
          :placeholder="item.placeholder || `请输入${item.label}`" :rows="item.rows || 3"
          :clearable="item.clearable !== false" :disabled="item.disabled" :maxlength="item.maxlength"
          :show-word-limit="item.showWordLimit" v-bind="item.props" />

        <!-- 数字输入框 -->
        <el-input-number v-else-if="item.type === 'number'" v-model="formData[item.name]"
          :placeholder="item.placeholder || `请输入${item.label}`" :min="item.min" :max="item.max" :step="item.step"
          :precision="item.precision" :disabled="item.disabled" :controls="item.controls !== false"
          v-bind="item.props" />

        <!-- 选择器 -->
        <el-select v-else-if="item.type === 'select'" v-model="formData[item.name]"
          :placeholder="item.placeholder || `请选择${item.label}`" :clearable="item.clearable !== false"
          :disabled="item.disabled" :multiple="item.multiple" :filterable="item.filterable" :remote="item.remote"
          :remote-method="item.remoteMethod" :loading="item.loading" v-bind="item.props"
          :style="inline ? 'width: 180px' : 'width: 100%'">
          <el-option v-for="option in getOptions(item)" :key="getOptionValue(option, item)"
            :label="getOptionLabel(option, item)" :value="getOptionValue(option, item)" />
        </el-select>

        <!-- 日期选择器 -->
        <el-date-picker v-else-if="item.type === 'date'" v-model="formData[item.name]" :type="item.dateType || 'date'"
          :placeholder="item.placeholder || `请选择${item.label}`" :format="item.format" :value-format="item.valueFormat"
          :clearable="item.clearable !== false" :disabled="item.disabled" :show-time="item.showTime"
          :range-separator="item.rangeSeparator || '至'" :start-placeholder="item.startPlaceholder"
          :end-placeholder="item.endPlaceholder" v-bind="item.props" style="width: 180px" />

        <!-- 时间选择器 -->
        <el-time-picker v-else-if="item.type === 'time'" v-model="formData[item.name]"
          :placeholder="item.placeholder || `请选择${item.label}`" :format="item.format" :value-format="item.valueFormat"
          :clearable="item.clearable !== false" :disabled="item.disabled" v-bind="item.props" style="width: 180px" />

        <!-- 开关 -->
        <el-switch v-else-if="item.type === 'switch'" v-model="formData[item.name]" :disabled="item.disabled"
          :active-text="item.activeText" :inactive-text="item.inactiveText" :active-value="item.activeValue"
          :inactive-value="item.inactiveValue" v-bind="item.props" />

        <!-- 单选框组 -->
        <el-radio-group v-else-if="item.type === 'radio'" v-model="formData[item.name]" :disabled="item.disabled"
          v-bind="item.props">
          <el-radio v-for="option in getOptions(item)" :key="getOptionValue(option, item)"
            :label="getOptionValue(option, item)">
            {{ getOptionLabel(option, item) }}
          </el-radio>
        </el-radio-group>

        <!-- 复选框组 -->
        <el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="formData[item.name]" :disabled="item.disabled"
          v-bind="item.props">
          <el-checkbox v-for="option in getOptions(item)" :key="getOptionValue(option, item)"
            :label="getOptionValue(option, item)">
            {{ getOptionLabel(option, item) }}
          </el-checkbox>
        </el-checkbox-group>

        <!-- 自定义插槽 -->
        <slot v-else-if="item.type === 'slot'" :name="item.slotName || item.name" :item="item"
          :value="formData[item.name]" :formData="formData" />

        <!-- 范围选择器 -->
        <div v-else-if="item.type === 'range'" class="range-input"
          style="display: flex; align-items: center; gap: 10px">
          <el-input v-model="formData[item.beginField || 'begin']" :placeholder="item.startPlaceholder || '开始值'"
            :clearable="item.clearable !== false" :disabled="item.disabled" style="flex: 1" />
          <span style="color: #999; font-size: 14px">至</span>
          <el-input v-model="formData[item.endField || 'end']" :placeholder="item.endPlaceholder || '结束值'"
            :clearable="item.clearable !== false" :disabled="item.disabled" style="flex: 1" />
        </div>

        <!-- 默认文本显示 -->
        <span v-else>{{ formData[item.name] }}</span>
      </el-form-item>
    </template>

    <!-- 栅格布局表单 -->
    <el-row v-else :gutter="gutter">
      <el-col v-for="(item, index) in formConfig" :key="index" :span="item.span || 4" :xs="item.xs || 12"
        :sm="item.sm || 8" :md="item.md || 6" :lg="item.lg || 4" :xl="item.xl || 4">
        <el-form-item :label="item.label" :prop="item.name" :required="item.req" :rules="getItemRules(item)">
          <!-- 输入框 -->
          <el-input v-if="item.type === 'text'" v-model="formData[item.name]"
            :placeholder="item.placeholder || `请输入${item.label}`" :clearable="item.clearable !== false"
            :disabled="item.disabled" :maxlength="item.maxlength" :show-word-limit="item.showWordLimit"
            v-bind="item.props" />

          <!-- 文本域 -->
          <el-input v-else-if="item.type === 'textarea'" v-model="formData[item.name]" type="textarea"
            :placeholder="item.placeholder || `请输入${item.label}`" :rows="item.rows || 3"
            :clearable="item.clearable !== false" :disabled="item.disabled" :maxlength="item.maxlength"
            :show-word-limit="item.showWordLimit" v-bind="item.props" />

          <!-- 数字输入框 -->
          <el-input-number v-else-if="item.type === 'number'" v-model="formData[item.name]"
            :placeholder="item.placeholder || `请输入${item.label}`" :min="item.min" :max="item.max" :step="item.step"
            :precision="item.precision" :disabled="item.disabled" :controls="item.controls !== false"
            v-bind="item.props" style="width: 100%" />

          <!-- 选择器 -->
          <el-select v-else-if="item.type === 'select'" v-model="formData[item.name]"
            :placeholder="item.placeholder || `请选择${item.label}`" :clearable="item.clearable !== false"
            :disabled="item.disabled" :multiple="item.multiple" :filterable="item.filterable" :remote="item.remote"
            :remote-method="item.remoteMethod" :loading="item.loading" v-bind="item.props" style="width: 100%">
            <el-option v-for="option in getOptions(item)" :key="getOptionValue(option, item)"
              :label="getOptionLabel(option, item)" :value="getOptionValue(option, item)" />
          </el-select>

          <!-- 日期选择器 -->
          <el-date-picker v-else-if="item.type === 'date'" v-model="formData[item.name]" :type="item.dateType || 'date'"
            :placeholder="item.placeholder || `请选择${item.label}`" :format="item.format" :value-format="item.valueFormat"
            :clearable="item.clearable !== false" :disabled="item.disabled" :show-time="item.showTime"
            :range-separator="item.rangeSeparator || '至'" :start-placeholder="item.startPlaceholder"
            :end-placeholder="item.endPlaceholder" v-bind="item.props" style="width: 100%" />

          <!-- 时间选择器 -->
          <el-time-picker v-else-if="item.type === 'time'" v-model="formData[item.name]"
            :placeholder="item.placeholder || `请选择${item.label}`" :format="item.format" :value-format="item.valueFormat"
            :clearable="item.clearable !== false" :disabled="item.disabled" v-bind="item.props" style="width: 100%" />

          <!-- 开关 -->
          <el-switch v-else-if="item.type === 'switch'" v-model="formData[item.name]" :disabled="item.disabled"
            :active-text="item.activeText" :inactive-text="item.inactiveText" :active-value="item.activeValue"
            :inactive-value="item.inactiveValue" v-bind="item.props" />

          <!-- 单选框组 -->
          <el-radio-group v-else-if="item.type === 'radio'" v-model="formData[item.name]" :disabled="item.disabled"
            v-bind="item.props">
            <el-radio v-for="option in getOptions(item)" :key="getOptionValue(option, item)"
              :label="getOptionValue(option, item)">
              {{ getOptionLabel(option, item) }}
            </el-radio>
          </el-radio-group>

          <!-- 复选框组 -->
          <el-checkbox-group v-else-if="item.type === 'checkbox'" v-model="formData[item.name]"
            :disabled="item.disabled" v-bind="item.props">
            <el-checkbox v-for="option in getOptions(item)" :key="getOptionValue(option, item)"
              :label="getOptionValue(option, item)">
              {{ getOptionLabel(option, item) }}
            </el-checkbox>
          </el-checkbox-group>

          <!-- 自定义插槽 -->
          <slot v-else-if="item.type === 'slot'" :name="item.slotName || item.name" :item="item"
            :value="formData[item.name]" :formData="formData" />

          <!-- 范围选择器 -->
          <div v-else-if="item.type === 'range'" class="range-input"
            style="display: flex; align-items: center; gap: 10px">
            <el-input v-model="formData[item.beginField || 'begin']" :placeholder="item.startPlaceholder || '开始值'"
              :clearable="item.clearable !== false" :disabled="item.disabled" style="flex: 1" />
            <span style="color: #999; font-size: 14px">至</span>
            <el-input v-model="formData[item.endField || 'end']" :placeholder="item.endPlaceholder || '结束值'"
              :clearable="item.clearable !== false" :disabled="item.disabled" style="flex: 1" />
          </div>

          <!-- 默认文本显示 -->
          <span v-else>{{ formData[item.name] }}</span>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>

<script setup>
import { ref, reactive, watch, computed, onMounted } from "vue";

const props = defineProps({
  // 表单配置
  config: {
    type: Array,
    default: () => [],
  },
  // 表单数据
  modelValue: {
    type: Object,
    default: () => ({}),
  },
  // 标签宽度
  labelWidth: {
    type: String,
    default: "120px",
  },
  // 标签位置
  labelPosition: {
    type: String,
    default: "right",
  },
  // 尺寸
  size: {
    type: String,
    default: "default",
  },
  // 是否禁用
  disabled: {
    type: Boolean,
    default: false,
  },
  // 栅格间距
  gutter: {
    type: Number,
    default: 20,
  },
  // 是否内联表单
  inline: {
    type: Boolean,
    default: false,
  },
});

const emit = defineEmits(["update:modelValue", "change", "validate"]);

const formRef = ref();
const formData = reactive({});
const formRules = reactive({});

// 监听父组件传入的modelValue变化，同步到formData
watch(
  () => props.modelValue,
  (newValue) => {
    if (newValue) {
      Object.assign(formData, newValue);
    }
  },
  { immediate: true, deep: true }
);

// 监听formData变化，同步回父组件
watch(
  formData,
  (newData) => {
    emit("update:modelValue", { ...newData });
  },
  { deep: true }
);

// 计算属性
const formConfig = computed(() => props.config);

// 初始化表单数据
const initFormData = () => {
  formConfig.value.forEach((item) => {
    if (formData[item.name] === undefined) {
      formData[item.name] = item.value || getDefaultValue(item.type);
    }
  });
};

// 获取默认值
const getDefaultValue = (type) => {
  const defaults = {
    text: "",
    textarea: "",
    number: null,
    select: null,
    date: null,
    time: null,
    switch: false,
    radio: null,
    checkbox: [],
  };
  return defaults[type] || "";
};

// 初始化表单验证规则
const initFormRules = () => {
  formConfig.value.forEach((item) => {
    if (item.req) {
      formRules[item.name] = [
        { required: true, message: `请输入${item.label}`, trigger: "blur" },
      ];
    }
    if (item.rules) {
      formRules[item.name] = formRules[item.name] || [];
      formRules[item.name].push(...item.rules);
    }
  });
};

// 获取表单项验证规则
const getItemRules = (item) => {
  const rules = [];
  if (item.req) {
    rules.push({
      required: true,
      message: `请输入${item.label}`,
      trigger: "blur",
    });
  }
  if (item.rules) {
    rules.push(...item.rules);
  }
  return rules;
};

// 获取选项数据
const getOptions = (item) => {
  return item.option || [];
};

// 获取选项标签
const getOptionLabel = (option, item) => {
  if (typeof option === "string") return option;
  return option[item.optionLabel] || option.label || option.name || option;
};

// 获取选项值
const getOptionValue = (option, item) => {
  if (typeof option === "string") return option;
  return option[item.optionValue] || option.value || option.id || option;
};

// 监听外部数据变化
watch(
  () => props.modelValue,
  (newVal) => {
    Object.assign(formData, newVal);
  },
  { deep: true, immediate: true }
);

// 监听表单数据变化
watch(
  formData,
  (newVal) => {
    emit("update:modelValue", { ...newVal });
    emit("change", { ...newVal });
  },
  { deep: true }
);

// 表单验证
const validate = (callback) => {
  return formRef.value.validate(callback);
};

// 重置表单
const resetFields = () => {
  formRef.value.resetFields();
  // 重置为初始值
  formConfig.value.forEach((item) => {
    formData[item.name] = item.value || getDefaultValue(item.type);
  });
};

// 清除验证
const clearValidate = (props) => {
  formRef.value.clearValidate(props);
};

// 暴露方法
defineExpose({
  validate,
  resetFields,
  clearValidate,
  formRef,
});

// 初始化
onMounted(() => {
  initFormData();
  initFormRules();
});
</script>

<style scoped>
.el-form-item {
  margin-bottom: 18px;
}
</style>
