<script setup lang="ts">
import type { BasicForm, AdvancedForm, formSlot } from '@/types/form'
import { ElMessage } from 'element-plus'

interface Props {
  formConfig: BasicForm | AdvancedForm
  formData: any
  create: Function
  update: Function
}

const props = defineProps<Props>()

const formProps: any = ref({
  labelWidth: '100px',
  labelPosition: 'top',
  size: 'large',
  ...props.formConfig?.props
})

const formInitData = computed(() => {
  return props.formData
})
const formRef = ref()

// 构造表单插槽
const formSlots = ref<formSlot[]>([])
if (props.formConfig.advanced) {
  props.formConfig.formItems.forEach((item: any) => {
    item.group.forEach((subItem: any) => Array.prototype.push.apply(formSlots.value, subItem.slots))
  })
} else {
  props.formConfig.formItems.forEach((item: any) => Array.prototype.push.apply(formSlots.value, item.slots))
}

const submit = async () => {
  let message
  return formRef.value.validate().then(async () => {
    try {
      if (formInitData.value.id) {
        await props.update(formInitData.value)
        message = '编辑成功'
      } else {
        await props.create(formInitData.value)
        message = '新增成功'
      }

      ElMessage({
        type: 'success',
        message
      })
      return true
    } catch (error) {
      return false
    }
  })
}

defineExpose({
  submit
})
</script>

<template>
  <el-form :model="formInitData" ref="formRef" v-bind="formProps" class="form">
    <advanced-form :formConfig="formConfig" :formData="formInitData" v-if="formConfig.advanced">
      <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
        <slot :name="slot.alias" v-bind="slotProps"></slot>
      </template>
    </advanced-form>
    <basic-form :formConfig="formConfig" :formData="formInitData" v-else>
      <template #[slot.alias]="slotProps" v-for="slot in formSlots" :key="slot.alias">
        <slot :name="slot.alias" v-bind="slotProps"></slot>
      </template>
    </basic-form>
  </el-form>
</template>

<style lang="scss" scoped>
:deep(.el-select) {
  width: 100%;
}
</style>
