<template>
  <el-form
    ref="formRef"
    :model="model"
    :rules="rules"
    :label-width="labelWidth"
    :inline="inline"
    :label-position="labelPosition"
    class="table-layout-form"
  >
    <template v-for="item in normalizedFormItems" :key="item.prop">
      <FormItem
        :item="item"
        :model-value="model[item.prop]"
        @update:model-value="(value) => (model[item.prop] = value)"
        @change="(value) => item.onChange && item.onChange(value)"
      >
        <template v-for="(_, slotName) in $slots" :key="slotName" #[slotName]="slotProps">
          <slot :name="slotName" v-bind="slotProps" />
        </template>
      </FormItem>
    </template>
  </el-form>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue';
import FormItem from './FormItem.vue';
import type { FormProps } from '../types/Form.d';

defineOptions({
  name: 'Form'
});

const props = withDefaults(defineProps<FormProps>(), {
  formItems: () => [],
  rules: () => ({}),
  labelWidth: '120px',
  inline: false,
  labelPosition: 'right',
  showLabelColon: true,
});

const emit = defineEmits<{
  validate: [callback?: (valid: boolean) => void];
}>();

const formRef = ref<InstanceType<typeof import('element-plus').ElForm> | null>(null);

const normalizedFormItems = computed(() =>
  (props.formItems || []).map((item) => ({
    ...item,
    labelSuffix: item.labelSuffix ?? (props.showLabelColon ? '：' : ''),
  }))
);

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

// 验证指定字段
const validateField = (props, callback) => {
  if (formRef.value) {
    return formRef.value.validateField(props, callback);
  }
};

// 重置表单
const resetFields = () => {
  if (formRef.value) {
    formRef.value.resetFields();
  }
};

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

// 滚动到指定字段
const scrollToField = (prop) => {
  if (formRef.value) {
    formRef.value.scrollToField(prop);
  }
};

defineExpose({
  formRef,
  validate,
  validateField,
  resetFields,
  clearValidate,
  scrollToField,
});
</script>

<style scoped lang="scss">
.table-layout-form {
  width: 100%;

  // 非内联表单样式
  &:not(.el-form--inline) {
    :deep(.el-form-item) {
      display: flex;
      margin-right: 0;
    }
  }
}
</style>

