<template>
  <div class="tool-generator-edit">
    <el-card class="!border-none" shadow="never" v-loading="isLoading">
      <el-form ref="formRef" :model="formData" :rules="formRules" label-width="90px">
        <el-tabs v-model="activeTab" class="generator-tabs">
          <el-tab-pane label="基础设置" name="basic" class="max-w-[600px]">
            <el-form-item label="表名称" prop="table_name">
              <el-input v-model="formData.table_name" disabled />
            </el-form-item>
            <el-form-item label="描述" prop="class_comment">
              <el-input ref="classCommentRef" v-model="formData.class_comment" placeholder="请输入中文描述" />
            </el-form-item>
            <el-form-item label="模块名" prop="module_name">
              <el-input v-model="formData.module_name" placeholder="请输入模块名" />
              <div class="text-sm text-info leading-normal mt-1">
                功能模块/目录名称。非必填，默认使用类名小写。例如：member
              </div>
            </el-form-item>
            <el-form-item label="类名" prop="class_name">
              <el-input ref="classNameRef" v-model="formData.class_name" placeholder="请输入类名" />
              <div class="text-sm text-info leading-normal mt-1">
                文件名称 (Controller/Model等)。自动推断，例如：Member
              </div>
            </el-form-item>
          </el-tab-pane>
          <el-tab-pane label="字段设置" name="fields">
            <el-table :data="formData.fields" border>
              <el-table-column prop="name" label="字段列名" align="center" min-width="120" />
              <el-table-column prop="desc" label="字段描述" align="center" min-width="120">
                <template #default="scope">
                  <el-input v-model="scope.row.desc" size="small" />
                </template>
              </el-table-column>
              <el-table-column prop="type" label="字段类型" align="center" min-width="100" show-overflow-tooltip />
              <el-table-column label="主键" width="60" align="center">
                <template #default="scope">
                  <el-checkbox v-model="scope.row.is_pk" disabled />
                </template>
              </el-table-column>
              <el-table-column label="必须" width="60" align="center">
                <template #default="scope">
                  <el-checkbox v-model="scope.row.is_required" />
                </template>
              </el-table-column>
              <el-table-column label="添加" width="60" align="center">
                <template #default="scope">
                  <el-checkbox v-model="scope.row.is_insert" />
                </template>
              </el-table-column>
              <el-table-column label="编辑" width="60" align="center">
                <template #default="scope">
                  <el-checkbox v-model="scope.row.is_edit" />
                </template>
              </el-table-column>
              <el-table-column label="列表" width="60" align="center">
                <template #default="scope">
                  <el-checkbox v-model="scope.row.is_list" />
                </template>
              </el-table-column>
              <el-table-column label="搜索" width="60" align="center">
                <template #default="scope">
                  <el-checkbox v-model="scope.row.is_query" />
                </template>
              </el-table-column>
              <el-table-column label="搜索方式" align="center" min-width="100">
                <template #default="scope">
                  <el-select v-model="scope.row.query_type" size="small" :disabled="!scope.row.is_query">
                    <el-option label="=" value="=" />
                    <el-option label="LIKE" value="like" />
                    <el-option label=">" value=">" />
                    <el-option label="<" value="<" />
                    <el-option label="BETWEEN" value="between" />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column label="表单类型" align="center" min-width="120">
                <template #default="scope">
                  <el-select v-model="scope.row.form_type" size="small">
                    <el-option label="文本框" value="input" />
                    <el-option label="文本域" value="textarea" />
                    <el-option label="编辑器" value="editor" />
                    <el-option label="下拉框" value="select" />
                    <el-option label="单选框" value="radio" />
                    <el-option label="复选框" value="checkbox" />
                    <el-option label="日期" value="date" />
                    <el-option label="日期时间" value="datetime" />
                    <el-option label="图片上传" value="image" />
                    <el-option label="附件上传" value="file" />
                    <el-option label="视频上传" value="video" />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column label="验证规则" align="center" min-width="120">
                <template #default="scope">
                  <el-select
                    v-model="scope.row.validation_type"
                    size="small"
                    clearable
                    filterable
                    allow-create
                    default-first-option
                  >
                    <el-option label="非空" value="require" />
                    <el-option label="数字" value="number" />
                    <el-option label="整数" value="integer" />
                    <el-option label="浮点数" value="float" />
                    <el-option label="邮箱" value="email" />
                    <el-option label="手机号" value="mobile" />
                    <el-option label="身份证" value="idCard" />
                    <el-option label="URL" value="url" />
                    <el-option label="IP" value="ip" />
                    <el-option label="纯字母" value="alpha" />
                    <el-option label="数字字母" value="alphaNum" />
                    <el-option label="汉字" value="chs" />
                    <el-option label="正则" value="regex" />
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column label="选项(键:值)" align="center" min-width="150">
                <template #default="scope">
                  <div class="flex justify-center items-center" v-if="optionsTypes.includes(scope.row.form_type)">
                    <el-button
                      size="small"
                      type="primary"
                      link
                      @click="handleEditOptions(scope.$index, scope.row.options)"
                    >
                      {{ scope.row.options ? '编辑选项' : '配置选项' }}
                    </el-button>
                    <el-tag class="ml-2" type="success" size="small" effect="plain" v-if="scope.row.options">
                      已配置
                    </el-tag>
                  </div>
                  <div v-else class="text-lg">-</div>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>
          <el-tab-pane label="生成配置" name="config" class="max-w-[600px]">
            <el-form-item label="父级菜单" prop="config.menu_pid">
              <el-tree-select
                class="w-full"
                v-model="formData.config.menu_pid"
                :data="menuTreeWithRoot"
                clearable
                placeholder="请选择父级菜单"
                node-key="id"
                :props="{ label: 'name', children: 'children' }"
                check-strictly
                default-expand-all
              />
              <div class="text-sm text-info leading-normal mt-1">选择生成的菜单放在哪个目录下。</div>
            </el-form-item>
            <el-form-item label="菜单名称" prop="config.menu_name">
              <el-input ref="menuNameRef" v-model="formData.config.menu_name" placeholder="请输入菜单名称" clearable />
              <div class="text-sm text-info leading-normal mt-1">菜单显示名称，如"商品管理"。</div>
            </el-form-item>
            <el-form-item label="删除类型" prop="config.delete_type">
              <el-radio-group v-model="formData.config.delete_type">
                <el-radio :label="0">物理删除</el-radio>
                <el-radio :label="1">软删除</el-radio>
              </el-radio-group>
              <div class="w-full text-sm text-info leading-normal mt-1">
                物理删除：从表中把记录移除。软删除：通过标识使得这条记录在系统逻辑层面上不可见
              </div>
            </el-form-item>
          </el-tab-pane>
          <el-tab-pane label="关联设置" name="relation">
            <el-button type="primary" icon="Plus" @click="handleAddRelation">新增关联</el-button>
            <el-table class="mt-4" :data="formData.config.relations" border>
              <el-table-column prop="type" label="关联类型" align="center" min-width="100" />
              <el-table-column prop="name" label="关联方法名称" align="center" min-width="120" />
              <el-table-column prop="model" label="关联模型" align="center" min-width="140" />
              <el-table-column prop="local_key" label="关联键" align="center" min-width="100" />
              <el-table-column prop="foreign_key" label="外键" align="center" min-width="100" />
              <el-table-column label="操作" fixed="right" width="140" align="center">
                <template #default="scope">
                  <el-button type="primary" link @click="handleEditRelation(scope.$index)">编辑</el-button>
                  <el-button type="danger" link @click="handleDeleteRelation(scope.$index)">删除</el-button>
                </template>
              </el-table-column>
            </el-table>
          </el-tab-pane>
        </el-tabs>
      </el-form>
    </el-card>
    <div class="edit-footer">
      <div class="edit-footer__content">
        <el-button v-perms="['tool.generator/save']" type="warning" :loading="isLoading" @click="handleSave(false)">
          保存配置
        </el-button>
        <el-button v-perms="['tool.generator/generate']" type="primary" :loading="isLoading" @click="handleGenerate">
          开始生成
        </el-button>
        <el-button @click="handleBack">返回</el-button>
      </div>
    </div>
    <!-- 选项编辑器弹窗 -->
    <options ref="optionsRef" @success="handleOptionsSave" />
    <!-- 关联设置弹窗 -->
    <relation ref="relationRef" @success="handleRelationSave" />
  </div>
</template>

<script setup lang="ts" name="ToolGeneratorEdit">
import type { FormInstance } from 'element-plus'
import { useRoute } from 'vue-router'
import { generatorCode, generatorColumns, generatorSave } from '@/api/tool/generator'
import { menuOptions } from '@/api/permission/menu'
import options from './components/options.vue'
import relation from './components/relation.vue'
import useTabsStore from '@/stores/modules/tabs'

// 组件参数
const route = useRoute()
const activeTab = ref('basic')
const isLoading = ref(false)
const formRef = shallowRef<FormInstance>()
const classCommentRef = ref<HTMLInputElement | null>()
const classNameRef = ref<HTMLInputElement | null>()
const menuNameRef = ref<HTMLInputElement | null>()
const formData = reactive({
  id: 0,
  table_name: '',
  class_comment: '',
  module_name: '',
  class_name: '',
  fields: [] as any[],
  config: {
    delete_type: 0,
    relations: [] as any[],
    menu_pid: 0,
    menu_name: ''
  }
})
const formRules = {
  class_comment: [{ required: true, message: '请输入描述', trigger: ['blur', 'change'] }],
  class_name: [{ required: true, message: '请输入类名', trigger: ['blur', 'change'] }],
  ['config.menu_pid']: [{ required: true, message: '请选择父级菜单', trigger: ['blur', 'change'] }],
  ['config.menu_name']: [{ required: true, message: '请输入菜单名称', trigger: ['blur', 'change'] }],
  ['config.delete_type']: [{ required: true, message: '请选择删除类型', trigger: ['blur', 'change'] }]
}
const menuTree = ref<any[]>([])
const menuTreeWithRoot = computed(() => {
  return [{ id: 0, name: '顶级菜单', children: menuTree.value }]
})
const optionsTypes = ref(['select', 'radio', 'checkbox'])
const relationRef = shallowRef<InstanceType<typeof relation>>()
const optionsRef = shallowRef<InstanceType<typeof options>>()

// 初始化数据
const initData = async (id: number) => {
  isLoading.value = true
  const res = await generatorColumns({ id })
  isLoading.value = false
  formData.id = id
  formData.fields = res.fields || []
  formData.table_name = res.info?.table_name || ''
  formData.class_comment = res.info?.class_comment || ''
  formData.module_name = res.info?.module_name || ''
  formData.class_name = res.info?.class_name || ''
  if (res.info.config) Object.assign(formData.config, res.info.config)
  if (!formData.config.relations) formData.config.relations = []
  if (!formData.config.menu_name && formData.class_comment) {
    formData.config.menu_name = formData.class_comment
  }
  if (formData.class_comment && formData.class_name) {
    activeTab.value = 'fields'
  }
  menuOptions().then((res: any) => {
    menuTree.value = res
  })
}
// 编辑配置选项
const handleEditOptions = (index: number, options: any) => {
  optionsRef.value?.open(index)
  optionsRef.value?.setFormData(options)
}
// 保存选项
const handleOptionsSave = (index: number, item: any) => {
  formData.fields[index].options = item
}
// 新增关联设置
const handleAddRelation = () => {
  relationRef.value?.open()
  relationRef.value?.setRelationFields(formData.fields)
}
// 编辑关联设置
const handleEditRelation = (index: number) => {
  relationRef.value?.open(index)
  relationRef.value?.setRelationFields(formData.fields)
  relationRef.value?.setFormData(formData.config.relations[index])
}
// 删除关联设置
const handleDeleteRelation = async (index: number) => {
  formData.config.relations.splice(index, 1)
}
// 保存关联设置
const handleRelationSave = async (index: number, item: any) => {
  if (index === -1) {
    formData.config.relations.push({ ...item })
  } else {
    formData.config.relations[index] = { ...item }
  }
}
// 生成代码
const handleGenerate = async () => {
  await formRef.value?.validate()
  isLoading.value = true
  try {
    await handleSave(true)
    await generatorCode({ id: formData.id })
    ElMessage.success('生成成功！')
    handleBack()
  } finally {
    isLoading.value = false
  }
}
// 保存配置
const handleSave = async (silent = false) => {
  await formRef.value?.validate(async (valid: boolean, invalidFields: any) => {
    if (valid) {
      isLoading.value = true
      try {
        await generatorSave(formData)
        if (!silent) {
          ElMessage.success('保存配置成功')
          handleBack()
        }
      } finally {
        isLoading.value = false
      }
    } else {
      ElMessage.warning('请填写完整信息')
      handleValidationError(invalidFields)
    }
  })
}
// 处理表单验证失败
const handleValidationError = (invalidFields: any) => {
  const firstErrorField = Object.keys(invalidFields)[0]
  if (firstErrorField) {
    let targetTab = 'basic'
    if (firstErrorField.includes('config.menu')) {
      targetTab = 'config'
    }
    activeTab.value = targetTab
    setTimeout(() => {
      let refKey = null
      if (firstErrorField === 'class_comment') {
        refKey = classCommentRef
      } else if (firstErrorField === 'class_name') {
        refKey = classNameRef
      } else if (firstErrorField === 'config.menu_name') {
        refKey = menuNameRef
      }
      if (refKey?.value) {
        refKey.value?.focus()
      }
    }, 100)
  }
}
// 返回
const handleBack = () => {
  useTabsStore().closeOpenPage('/tool/generator')
}

onMounted(() => {
  const id = Number(route.query.id)
  if (id) {
    initData(id)
  }
})
</script>

<style lang="scss" scoped>
.tool-generator-edit {
  .edit-footer {
    height: 56px;

    .edit-footer__content {
      @apply absolute bottom-0 left-0 right-0;
      @apply flex justify-center px-4 py-3;
      background: var(--el-bg-color);
      z-index: 1000;
    }
  }
}
</style>
