<template>
  <popup v-model="showDialog" :title="popupTitle" width="600px" :close-on-click-modal="false" @confirm="handleSubmit">
    <el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
      <el-form-item label="关联类型" prop="type">
        <el-select v-model="formData.type" placeholder="请选择角色">
          <el-option label="一对一 (hasOne)" value="hasOne" />
          <el-option label="一对多 (hasMany)" value="hasMany" />
          <el-option label="属于 (belongsTo)" value="belongsTo" />
        </el-select>
      </el-form-item>
      <el-form-item label="关联方法名称" prop="name">
        <el-input v-model="formData.name" placeholder="请输入关联方法名称" />
      </el-form-item>
      <el-form-item label="关联模型" prop="model">
        <el-select v-model="formData.model" placeholder="请选择关联模型" filterable popper-style="max-width: 100vw;">
          <el-option
            v-for="item in modelList"
            :key="item.value"
            :label="item.name + ' (' + item.value + ')'"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item label="关联键" prop="local_key">
        <el-select v-model="formData.local_key" placeholder="请选择关联键" allow-create filterable>
          <el-option
            v-for="item in relationFields"
            :key="item.name"
            :label="item.name + ' (' + item.desc + ')'"
            :value="item.name"
          />
        </el-select>
        <div class="text-sm text-info">当前模型中的关联字段，例如 user_id</div>
      </el-form-item>
      <el-form-item label="外键" prop="foreign_key">
        <el-input v-model="formData.foreign_key" placeholder="请输入外键" />
        <div class="text-sm text-info">对方模型中的关联字段，例如 id</div>
      </el-form-item>
    </el-form>
  </popup>
</template>

<script setup lang="ts">
import type { FormInstance } from 'element-plus'
import { generatorModels } from '@/api/tool/generator'

// 定义组件事件
const emit = defineEmits<{
  (event: 'success', index: number, data: any): void
}>()

// 表单引用
const formRef = shallowRef<FormInstance>()
// 关联索引：-1=新增，其他=编辑
const relationIndex = ref<number>(-1)
// 是否显示弹窗
const showDialog = ref(false)
// 弹窗标题
const popupTitle = computed(() => {
  return relationIndex.value === -1 ? '新增关联' : '编辑关联'
})
// 初始表单数据
const initialFormData = {
  type: 'hasOne',
  name: '',
  model: '',
  local_key: '',
  foreign_key: ''
}
// 表单数据
const formData = reactive<Record<string, any>>({ ...initialFormData })
// 表单验证规则
const formRules = reactive({
  type: [
    {
      required: true,
      message: '请选择关联类型',
      trigger: ['blur', 'change']
    }
  ],
  name: [
    {
      required: true,
      message: '请输入关联方法名称',
      trigger: ['blur', 'change']
    }
  ],
  model: [
    {
      required: true,
      message: '请选择关联模型',
      trigger: ['blur', 'change']
    }
  ],
  local_key: [
    {
      required: true,
      message: '请选择关联键',
      trigger: ['blur', 'change']
    }
  ],
  foreign_key: [
    {
      required: true,
      message: '请输入外键',
      trigger: ['blur', 'change']
    }
  ]
})
// 关联模型列表
const modelList = ref<any[]>([])
// 关联字段列表
const relationFields = ref<any[]>([])

// 打开弹窗
const open = (index: number = -1) => {
  getModelLists()
  relationIndex.value = index
  showDialog.value = true
}
// 设置表单数据
const setFormData = async (data?: any) => {
  resetForm()
  if (data) {
    Object.keys(formData).forEach((key: string) => {
      if (data[key] != undefined) formData[key] = data[key]
    })
  }
}
// 设置关联字段列表
const setRelationFields = (fields: any[]) => {
  relationFields.value = fields
}
// 表单重置
const resetForm = () => {
  Object.assign(formData, initialFormData)
  formRef.value?.resetFields()
}
// 获取关联模型列表
const getModelLists = () => {
  generatorModels().then((res: any) => {
    modelList.value = res
  })
}
// 提交表单
const handleSubmit = () => {
  formRef.value?.validate(async (valid) => {
    if (valid) {
      emit('success', relationIndex.value, formData)
      showDialog.value = false
    }
  })
}

defineExpose({
  open,
  setFormData,
  setRelationFields
})
</script>
