<template>
  <div class="page-stack">
    <section class="page-toolbar">
      <div>
        <h1>病例库</h1>
        <p>{{ pageDescription }}</p>
      </div>
      <div class="toolbar-actions">
        <el-button :icon="Upload" @click="openImportDialog">PDF 导入</el-button>
        <el-button :icon="Plus" type="primary" @click="openCreateDialog">新增草稿</el-button>
      </div>
    </section>

    <section class="filter-bar case-filter" :class="{ 'content-case-filter': isContentAdmin }">
      <el-input v-model="filters.search" :prefix-icon="Search" clearable :placeholder="searchPlaceholder" @keyup.enter="loadCases" />
      <el-select v-model="filters.case_type" clearable placeholder="病例类型">
        <el-option label="传统病例" value="traditional" />
        <el-option label="教学病例" value="teaching" />
      </el-select>
      <el-select v-model="filters.publish_status" clearable placeholder="发布状态">
        <el-option label="草稿" :value="0" />
        <el-option label="正常" :value="1" />
        <el-option label="已发布" :value="2" />
      </el-select>
      <el-input v-if="canManageInstitution" v-model="filters.institution" clearable placeholder="机构ID" @keyup.enter="loadCases" />
      <template v-else>
        <el-input v-model="filters.department" clearable placeholder="科室ID" @keyup.enter="loadCases" />
        <el-input v-model="filters.status" clearable placeholder="状态" @keyup.enter="loadCases" />
        <el-select v-model="filters.osce_enabled" clearable placeholder="OSCE">
          <el-option label="开启" value="true" />
          <el-option label="关闭" value="false" />
        </el-select>
        <el-select v-model="filters.ordering" clearable placeholder="排序">
          <el-option label="最近更新" value="-updated_at" />
          <el-option label="最早更新" value="updated_at" />
          <el-option label="最近创建" value="-created_at" />
          <el-option label="最早创建" value="created_at" />
        </el-select>
      </template>
      <el-button :icon="Search" type="primary" @click="handleSearch">查询</el-button>
      <el-button :icon="Refresh" @click="resetFilters">重置</el-button>
    </section>

    <section class="data-section">
      <el-table v-loading="loading" :data="cases" empty-text="暂无病例数据" row-key="id">
        <el-table-column prop="id" label="ID" width="90" />
        <el-table-column prop="title" label="病例标题" min-width="220">
          <template #default="{ row }">
            <strong>{{ row.title }}</strong>
            <span v-if="row.chiefComplaint" class="table-subtext">{{ row.chiefComplaint }}</span>
          </template>
        </el-table-column>
        <el-table-column label="类型" width="110">
          <template #default="{ row }">
            <el-tag>{{ caseTypeLabel(row.caseType) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column :label="canManageInstitution ? '机构/科室' : '科室'" min-width="180">
          <template #default="{ row }">
            <template v-if="canManageInstitution">
              <span>{{ row.institutionName || row.institutionId || '-' }}</span>
              <span class="table-subtext">{{ row.departmentName || row.departmentId || '未关联科室' }}</span>
            </template>
            <span v-else>{{ row.departmentName || row.departmentId || '未关联科室' }}</span>
          </template>
        </el-table-column>
        <el-table-column label="难度" width="90">
          <template #default="{ row }">
            <el-tag :type="difficultyTagType(row.difficulty)">{{ row.difficulty || '-' }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="标签/ICD" min-width="180">
          <template #default="{ row }">
            <div class="case-tag-list">
              <el-tag v-for="tag in row.tags.slice(0, 2)" :key="tag" size="small" type="info">{{ tag }}</el-tag>
              <el-tag v-for="code in row.icdCodes.slice(0, 2)" :key="code" size="small">{{ code }}</el-tag>
              <span v-if="row.tags.length + row.icdCodes.length > 4" class="table-subtext">+{{ row.tags.length + row.icdCodes.length - 4 }}</span>
              <span v-if="!row.tags.length && !row.icdCodes.length">-</span>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="时长" width="90">
          <template #default="{ row }">
            {{ row.estimatedMinutes ? `${row.estimatedMinutes} 分钟` : '-' }}
          </template>
        </el-table-column>
        <el-table-column label="更新时间" width="170">
          <template #default="{ row }">
            {{ formatDateTime(row.updatedAt || row.createdAt) }}
          </template>
        </el-table-column>
        <el-table-column label="状态" width="100">
          <template #default="{ row }">
            <el-tag :type="publishStatusTagType(row.publishStatus)">{{ publishStatusLabel(row.publishStatus) }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="250" fixed="right">
          <template #default="{ row }">
            <el-button link type="primary" @click="openDetailDrawer(row)">查看</el-button>
            <el-button link type="primary" @click="openRelationsDialog(row)">关联</el-button>
            <el-button link type="primary" :disabled="row.publishStatus !== 0" @click="confirmSubmitCase(row)">提交</el-button>
            <el-button link type="danger" @click="confirmDisableCase(row)">停用/重录</el-button>
          </template>
        </el-table-column>
      </el-table>
      <div class="table-pagination">
        <el-pagination
          v-model:current-page="pagination.page"
          v-model:page-size="pagination.size"
          :page-sizes="[10, 20, 50, 100]"
          :total="pagination.total"
          background
          layout="total, sizes, prev, pager, next, jumper"
          @current-change="loadCases"
          @size-change="handleSizeChange"
        />
      </div>
    </section>

    <el-dialog v-model="caseDialogVisible" title="新增病例草稿" width="960px" @closed="resetCaseForm">
      <el-form ref="caseFormRef" class="case-create-form" :model="caseForm" :rules="caseRules" label-position="top">
        <div class="case-form-section">
          <h3>基础信息</h3>
          <el-row :gutter="14">
            <el-col :span="12">
              <el-form-item label="病例标题" prop="title">
                <el-input v-model="caseForm.title" placeholder="请输入病例标题" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="病例类型" prop="case_type">
                <el-select v-model="caseForm.case_type" placeholder="请选择病例类型">
                  <el-option label="传统病例" value="traditional" />
                  <el-option label="教学病例" value="teaching" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col v-if="canManageInstitution" :span="8">
              <el-form-item label="机构">
                <el-select
                  v-model="caseForm.institution_id"
                  :loading="loadingInstitutions"
                  clearable
                  filterable
                  placeholder="请选择机构"
                  @change="handleCaseInstitutionChange"
                  @visible-change="handleInstitutionVisibleChange"
                >
                  <el-option
                    v-for="item in institutionOptions"
                    :key="item.id"
                    :label="institutionOptionLabel(item)"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="科室">
                <el-select
                  v-model="caseForm.department_id"
                  :disabled="canManageInstitution && !caseForm.institution_id"
                  :loading="loadingDepartments"
                  clearable
                  filterable
                  placeholder="请选择科室"
                  @change="handleCaseDepartmentChange"
                  @visible-change="handleDepartmentVisibleChange"
                >
                  <el-option
                    v-for="item in departmentOptions"
                    :key="item.id"
                    :label="item.name"
                    :value="item.id"
                  />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="难度">
                <el-select v-model="caseForm.difficulty" allow-create clearable filterable default-first-option placeholder="请选择或输入难度">
                  <el-option label="低" value="低" />
                  <el-option label="中" value="中" />
                  <el-option label="高" value="高" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="主诉">
                <el-input v-model="caseForm.chief_complaint" placeholder="请输入主诉" />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="患者年龄">
                <el-input-number v-model="caseForm.patient_age" :min="0" :max="130" :precision="0" :controls="false" placeholder="年龄" />
              </el-form-item>
            </el-col>
            <el-col :span="6">
              <el-form-item label="患者性别">
                <el-select v-model="caseForm.patient_gender" clearable placeholder="请选择">
                  <el-option label="男" value="male" />
                  <el-option label="女" value="female" />
                  <el-option label="未知" value="unknown" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="标签">
                <el-input v-model="caseForm.tags" placeholder="多个用逗号分隔" />
              </el-form-item>
            </el-col>
            <el-col :span="8">
              <el-form-item label="ICD 编码">
                <el-input v-model="caseForm.icd_codes" placeholder="多个用逗号分隔" />
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="预计分钟">
                <el-input-number v-model="caseForm.estimated_minutes" :min="1" :precision="0" :controls="false" />
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="OSCE">
                <el-switch v-model="caseForm.osce_enabled" active-text="开启" inactive-text="关闭" />
              </el-form-item>
            </el-col>
            <el-col :span="24">
              <el-form-item label="描述">
                <el-input v-model="caseForm.description" type="textarea" :rows="3" placeholder="请输入病例背景或教学说明" />
              </el-form-item>
            </el-col>
          </el-row>
        </div>

        <div class="case-form-section">
          <h3>{{ caseTypeLabel(caseForm.case_type) }}内容</h3>
          <template v-if="caseForm.case_type === 'traditional'">
            <el-row :gutter="14">
              <el-col :span="8">
                <el-form-item label="标准诊断" prop="traditional_standard_diagnosis">
                  <el-input v-model="caseForm.traditional_standard_diagnosis" placeholder="如：上呼吸道感染" />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="标准治疗">
                  <el-input v-model="caseForm.traditional_standard_treatment" placeholder="如：对症治疗，退热处理" />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="指南依据">
                  <el-input v-model="caseForm.traditional_guideline_reference" placeholder="如：《儿科学》第 9 版" />
                </el-form-item>
              </el-col>
            </el-row>
          </template>
          <template v-else>
            <el-row :gutter="14">
              <el-col :span="8">
                <el-form-item label="教学目标" prop="teaching_learning_objectives">
                  <el-input v-model="caseForm.teaching_learning_objectives" placeholder="请输入教学目标" />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="教学重点">
                  <el-input v-model="caseForm.teaching_key_points" placeholder="请输入教学重点" />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="参考答案">
                  <el-input v-model="caseForm.teaching_reference_answer" placeholder="请输入参考答案" />
                </el-form-item>
              </el-col>
            </el-row>
          </template>
        </div>

        <div class="case-form-section">
          <div class="case-section-title">
            <h3>检查/检验项目</h3>
            <el-button :icon="Plus" @click="addExamItem">添加项目</el-button>
          </div>
          <div v-if="!caseForm.exam_items.length" class="case-empty-line">未添加项目，可直接保存草稿。</div>
          <div v-for="(item, index) in caseForm.exam_items" :key="index" class="exam-item-row">
            <el-input v-model="item.item_code" placeholder="项目编码，必须唯一" />
            <el-input v-model="item.item_name" placeholder="项目名称" />
            <el-input v-model="item.item_type" placeholder="项目类型" />
            <el-input v-model="item.result_text" placeholder="结果文本" />
            <el-button :icon="Delete" circle @click="removeExamItem(index)" />
          </div>
        </div>
      </el-form>
      <template #footer>
        <el-button @click="caseDialogVisible = false">取消</el-button>
        <el-button :loading="savingCase" type="primary" @click="submitCaseForm">保存草稿</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="importDialogVisible" title="PDF 导入病例" width="560px" @closed="resetImportFile">
      <el-form class="case-import-form" label-position="top">
        <el-form-item label="病例类型">
          <el-select v-model="importCaseType" placeholder="请选择病例类型">
            <el-option label="传统病例" value="traditional" />
            <el-option label="教学互动病例" value="teaching" />
          </el-select>
        </el-form-item>
      </el-form>
      <el-upload
        ref="importUploadRef"
        v-model:file-list="importFileList"
        drag
        :auto-upload="false"
        :limit="1"
        :on-change="handleImportFileChange"
        :on-exceed="handleImportExceed"
        :on-remove="handleImportFileRemove"
        accept=".pdf,application/pdf"
      >
        <el-icon class="el-icon--upload"><UploadFilled /></el-icon>
        <div class="el-upload__text">拖拽 PDF 到此处，或点击选择</div>
        <template #tip>
          <div class="el-upload__tip">选择一个 PDF 文件后即可上传导入。</div>
        </template>
      </el-upload>
      <template #footer>
        <el-button @click="importDialogVisible = false">取消</el-button>
        <el-button :disabled="!importFile" :loading="importing" type="primary" @click="submitImportPdf">上传</el-button>
      </template>
    </el-dialog>

    <el-dialog v-model="relationsDialogVisible" title="编辑病例关联" width="620px" @closed="resetRelationsForm">
      <el-form class="case-relations-form" label-position="top">
        <el-alert
          v-if="relationsCase"
          :title="relationsCurrentTitle"
          type="info"
          :closable="false"
        />
        <el-form-item v-if="canManageInstitution" label="机构关联">
          <el-radio-group v-model="relationsForm.institutionMode">
            <el-radio-button label="keep">不修改</el-radio-button>
            <el-radio-button label="set">设置ID</el-radio-button>
            <el-radio-button label="clear">清空</el-radio-button>
          </el-radio-group>
          <el-input-number
            v-if="relationsForm.institutionMode === 'set'"
            v-model="relationsForm.institution_id"
            class="relation-input"
            :min="1"
            :precision="0"
            :controls="false"
            placeholder="请输入机构ID"
          />
        </el-form-item>
        <el-form-item label="科室关联">
          <el-radio-group v-model="relationsForm.departmentMode">
            <el-radio-button label="keep">不修改</el-radio-button>
            <el-radio-button label="id">设置ID</el-radio-button>
            <el-radio-button label="name">按名称</el-radio-button>
            <el-radio-button label="clear">清空</el-radio-button>
          </el-radio-group>
          <el-input-number
            v-if="relationsForm.departmentMode === 'id'"
            v-model="relationsForm.department_id"
            class="relation-input"
            :min="1"
            :precision="0"
            :controls="false"
            placeholder="请输入科室ID"
          />
          <el-input
            v-if="relationsForm.departmentMode === 'name'"
            v-model="relationsForm.department_name"
            class="relation-input"
            placeholder="请输入科室名称"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="relationsDialogVisible = false">取消</el-button>
        <el-button :loading="savingRelations" type="primary" @click="submitRelationsForm">保存关联</el-button>
      </template>
    </el-dialog>

    <el-drawer v-model="detailDrawerVisible" :title="detailDrawerTitle" size="72%" destroy-on-close @closed="resetDetailForm">
      <div v-loading="detailLoading" class="case-detail-drawer">
        <el-form
          v-if="detailCase"
          ref="detailFormRef"
          class="case-create-form case-detail-form"
          :model="detailForm"
          :rules="caseRules"
          :disabled="!canEditDetailCase"
          label-position="top"
        >
          <div class="case-form-section">
            <div class="case-section-title">
              <h3>基础信息</h3>
              <el-tag :type="publishStatusTagType(detailCase.publishStatus)">ID {{ detailCase.id }} / {{ publishStatusLabel(detailCase.publishStatus) }}</el-tag>
            </div>
            <el-row :gutter="14">
              <el-col :span="12">
                <el-form-item label="病例标题" prop="title">
                  <el-input v-model="detailForm.title" placeholder="请输入病例标题" />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="病例类型" prop="case_type">
                  <el-select v-model="detailForm.case_type" disabled placeholder="请选择病例类型">
                    <el-option label="传统病例" value="traditional" />
                    <el-option label="教学病例" value="teaching" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col v-if="canManageInstitution" :span="8">
                <el-form-item label="机构">
                  <el-select
                    v-model="detailForm.institution_id"
                    :loading="loadingInstitutions"
                    clearable
                    filterable
                    placeholder="请选择机构"
                    @change="handleDetailInstitutionChange"
                    @visible-change="handleInstitutionVisibleChange"
                  >
                    <el-option
                      v-for="item in institutionOptions"
                      :key="item.id"
                      :label="institutionOptionLabel(item)"
                      :value="item.id"
                    />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="科室">
                  <el-select
                    v-model="detailForm.department_id"
                    :disabled="canManageInstitution && !detailForm.institution_id"
                    :loading="loadingDepartments"
                    clearable
                    filterable
                    placeholder="请选择科室"
                    @change="handleDetailDepartmentChange"
                    @visible-change="handleDepartmentVisibleChange"
                  >
                    <el-option
                      v-for="item in departmentOptions"
                      :key="item.id"
                      :label="item.name"
                      :value="item.id"
                    />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="难度">
                  <el-select v-model="detailForm.difficulty" allow-create clearable filterable default-first-option placeholder="请选择或输入难度">
                    <el-option label="低" value="低" />
                    <el-option label="中" value="中" />
                    <el-option label="高" value="高" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="主诉">
                  <el-input v-model="detailForm.chief_complaint" placeholder="请输入主诉" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="患者年龄">
                  <el-input-number v-model="detailForm.patient_age" :min="0" :max="130" :precision="0" :controls="false" placeholder="年龄" />
                </el-form-item>
              </el-col>
              <el-col :span="6">
                <el-form-item label="患者性别">
                  <el-select v-model="detailForm.patient_gender" clearable placeholder="请选择">
                    <el-option label="男" value="male" />
                    <el-option label="女" value="female" />
                    <el-option label="未知" value="unknown" />
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="标签">
                  <el-input v-model="detailForm.tags" placeholder="多个用逗号分隔" />
                </el-form-item>
              </el-col>
              <el-col :span="8">
                <el-form-item label="ICD 编码">
                  <el-input v-model="detailForm.icd_codes" placeholder="多个用逗号分隔" />
                </el-form-item>
              </el-col>
              <el-col :span="4">
                <el-form-item label="预计分钟">
                  <el-input-number v-model="detailForm.estimated_minutes" :min="1" :precision="0" :controls="false" />
                </el-form-item>
              </el-col>
              <el-col :span="4">
                <el-form-item label="OSCE">
                  <el-switch v-model="detailForm.osce_enabled" active-text="开启" inactive-text="关闭" />
                </el-form-item>
              </el-col>
              <el-col :span="24">
                <el-form-item label="描述">
                  <el-input v-model="detailForm.description" type="textarea" :rows="3" placeholder="请输入病例背景或教学说明" />
                </el-form-item>
              </el-col>
            </el-row>
          </div>

          <div class="case-form-section">
            <h3>{{ caseTypeLabel(detailForm.case_type) }}内容</h3>
            <template v-if="detailForm.case_type === 'traditional'">
              <el-row :gutter="14">
                <el-col :span="8">
                  <el-form-item label="标准诊断" prop="traditional_standard_diagnosis">
                    <el-input v-model="detailForm.traditional_standard_diagnosis" placeholder="如：上呼吸道感染" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="标准治疗">
                    <el-input v-model="detailForm.traditional_standard_treatment" placeholder="如：对症治疗，退热处理" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="指南依据">
                    <el-input v-model="detailForm.traditional_guideline_reference" placeholder="如：《儿科学》第 9 版" />
                  </el-form-item>
                </el-col>
              </el-row>
            </template>
            <template v-else>
              <el-row :gutter="14">
                <el-col :span="8">
                  <el-form-item label="教学目标" prop="teaching_learning_objectives">
                    <el-input v-model="detailForm.teaching_learning_objectives" placeholder="请输入教学目标" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="教学重点">
                    <el-input v-model="detailForm.teaching_key_points" placeholder="请输入教学重点" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="参考答案">
                    <el-input v-model="detailForm.teaching_reference_answer" placeholder="请输入参考答案" />
                  </el-form-item>
                </el-col>
              </el-row>
            </template>
          </div>

          <div v-if="showPublishedScoringRules" class="case-form-section">
            <div class="case-section-title">
              <h3>评分规则</h3>
            </div>
            <el-table :data="visibleScoringRules" border size="small" empty-text="暂无评分规则">
              <el-table-column prop="dimension" label="维度" min-width="160" />
              <el-table-column label="权重" width="100">
                <template #default="{ row }">
                  {{ formatScoreWeight(row.score_weight) }}
                </template>
              </el-table-column>
              <el-table-column prop="scoring_standard" label="评分标准" min-width="260" show-overflow-tooltip />
            </el-table>
          </div>

          <div class="case-form-section">
            <div class="case-section-title">
              <h3>检查/检验项目</h3>
              <el-button :icon="Plus" :disabled="!canEditDetailCase" @click="addDetailExamItem">添加项目</el-button>
            </div>
            <div v-if="!detailForm.exam_items.length" class="case-empty-line">未添加项目，可直接保存草稿。</div>
            <div v-for="(item, index) in detailForm.exam_items" :key="`detail-item-${index}`" class="exam-item-row">
              <el-input v-model="item.item_code" placeholder="项目编码，必须唯一" />
              <el-input v-model="item.item_name" placeholder="项目名称" />
              <el-input v-model="item.item_type" placeholder="项目类型" />
              <el-input v-model="item.result_text" placeholder="结果文本" />
              <el-button :icon="Delete" :disabled="!canEditDetailCase" circle @click="removeDetailExamItem(index)" />
            </div>
          </div>
        </el-form>

        <div class="drawer-form-footer">
          <el-button @click="detailDrawerVisible = false">{{ canEditDetailCase ? '取消' : '关闭' }}</el-button>
          <el-button v-if="canEditDetailCase" :loading="submittingDetail" type="primary" @click="submitDetailForm">保存草稿</el-button>
        </div>
      </div>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { computed, onMounted, reactive, ref } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { FormInstance, FormRules, UploadInstance, UploadProps, UploadRawFile, UploadUserFile } from 'element-plus'
import { Delete, Plus, Refresh, Search, Upload, UploadFilled } from '@element-plus/icons-vue'
import {
  createCaseDraft,
  disableCase,
  fetchCaseFull,
  fetchCases,
  importCasePdf,
  saveCaseDraft,
  submitCase,
  updateCaseRelations,
  type CaseExamItemPayload,
  type ImportCasePdfResult,
  type CaseListItem,
  type CasePublishStatus,
  type CaseScoringRulePayload,
  type CreateCaseDraftPayload,
  type DraftCaseType,
  type SaveCaseDraftPayload,
  type UpdateCaseRelationsPayload
} from '@/api/cases'
import { fetchInstitutionList, fetchMyDepartments, type DepartmentOption, type InstitutionOption } from '@/api/users'
import { useAppStore } from '@/stores/app'

type RelationInstitutionMode = 'keep' | 'set' | 'clear'
type RelationDepartmentMode = 'keep' | 'id' | 'name' | 'clear'

interface ScoringRuleForm {
  dimension: string
  score_weight: number
  ai_auto_score: boolean
  scoring_standard: string
}

interface ExamItemForm {
  item_code: string
  item_name: string
  item_type: string
  result_text: string
}

const examItemFields: Array<{ key: keyof ExamItemForm; label: string }> = [
  { key: 'item_code', label: '项目编码' },
  { key: 'item_name', label: '项目名称' },
  { key: 'item_type', label: '项目类型' },
  { key: 'result_text', label: '结果文本' }
]

interface CaseDraftForm {
  title: string
  case_type: DraftCaseType
  institution_id?: number
  department_id?: number
  department_name: string
  difficulty: string
  chief_complaint: string
  description: string
  patient_age?: number
  patient_gender: string
  tags: string
  icd_codes: string
  estimated_minutes?: number
  osce_enabled: boolean
  traditional_standard_diagnosis: string
  traditional_standard_treatment: string
  traditional_guideline_reference: string
  teaching_learning_objectives: string
  teaching_key_points: string
  teaching_reference_answer: string
  scoring_rules: ScoringRuleForm[]
  exam_items: ExamItemForm[]
}

const appStore = useAppStore()
const loading = ref(false)
const savingCase = ref(false)
const importing = ref(false)
const savingRelations = ref(false)
const detailLoading = ref(false)
const submittingDetail = ref(false)
const loadingInstitutions = ref(false)
const loadingDepartments = ref(false)
const caseDialogVisible = ref(false)
const importDialogVisible = ref(false)
const relationsDialogVisible = ref(false)
const detailDrawerVisible = ref(false)
const caseFormRef = ref<FormInstance>()
const detailFormRef = ref<FormInstance>()
const importUploadRef = ref<UploadInstance>()
const importFile = ref<File | null>(null)
const importCaseType = ref<DraftCaseType>('traditional')
const importFileList = ref<UploadUserFile[]>([])
const cases = ref<CaseListItem[]>([])
const institutionOptions = ref<InstitutionOption[]>([])
const departmentOptions = ref<DepartmentOption[]>([])
const relationsCase = ref<CaseListItem | null>(null)
const detailCase = ref<CaseListItem | null>(null)
const caseDetail = ref<unknown>(null)

const filters = reactive<{
  search: string
  case_type: string
  publish_status: CasePublishStatus | ''
  institution: string
  department: string
  status: string
  osce_enabled: string
  ordering: string
}>({
  search: '',
  case_type: '',
  publish_status: '',
  institution: '',
  department: '',
  status: '',
  osce_enabled: '',
  ordering: ''
})
const pagination = reactive({
  page: 1,
  size: 10,
  total: 0
})

const caseForm = reactive<CaseDraftForm>({
  title: '',
  case_type: 'traditional',
  institution_id: undefined,
  department_id: undefined,
  department_name: '',
  difficulty: '',
  chief_complaint: '',
  description: '',
  patient_age: undefined,
  patient_gender: '',
  tags: '',
  icd_codes: '',
  estimated_minutes: undefined,
  osce_enabled: false,
  traditional_standard_diagnosis: '',
  traditional_standard_treatment: '',
  traditional_guideline_reference: '',
  teaching_learning_objectives: '',
  teaching_key_points: '',
  teaching_reference_answer: '',
  scoring_rules: [{ dimension: '', score_weight: 1, ai_auto_score: true, scoring_standard: '' }],
  exam_items: []
})

const detailForm = reactive<CaseDraftForm>({
  title: '',
  case_type: 'traditional',
  institution_id: undefined,
  department_id: undefined,
  department_name: '',
  difficulty: '',
  chief_complaint: '',
  description: '',
  patient_age: undefined,
  patient_gender: '',
  tags: '',
  icd_codes: '',
  estimated_minutes: undefined,
  osce_enabled: false,
  traditional_standard_diagnosis: '',
  traditional_standard_treatment: '',
  traditional_guideline_reference: '',
  teaching_learning_objectives: '',
  teaching_key_points: '',
  teaching_reference_answer: '',
  scoring_rules: [{ dimension: '', score_weight: 1, ai_auto_score: true, scoring_standard: '' }],
  exam_items: []
})

const relationsForm = reactive<{
  institutionMode: RelationInstitutionMode
  institution_id?: number
  departmentMode: RelationDepartmentMode
  department_id?: number
  department_name: string
}>({
  institutionMode: 'keep',
  institution_id: undefined,
  departmentMode: 'keep',
  department_id: undefined,
  department_name: ''
})

const caseRules: FormRules = {
  title: [{ required: true, message: '请输入病例标题', trigger: 'blur' }],
  case_type: [{ required: true, message: '请选择病例类型', trigger: 'change' }],
  traditional_standard_diagnosis: [{ required: true, message: '请输入标准诊断', trigger: 'blur' }],
  teaching_learning_objectives: [{ required: true, message: '请输入教学目标', trigger: 'blur' }]
}

const isContentAdmin = computed(() => appStore.user.role === 'content-admin')
const canManageInstitution = computed(() => !isContentAdmin.value)
const pageDescription = computed(() =>
  isContentAdmin.value
    ? '维护内容管理员病例资产，支持科室筛选、PDF 导入、草稿创建、关联编辑和状态流转。'
    : '维护超级管理员病例资产，支持检索、PDF 导入、草稿创建、关联编辑和状态流转。'
)
const searchPlaceholder = computed(() => (isContentAdmin.value ? '搜索病例' : '搜索标题/主诉/标签/ICD'))
const detailDrawerTitle = computed(() => (detailCase.value ? `病例详情：${detailCase.value.title}` : '病例详情'))
const detailDisplay = computed(() => createDetailDisplay(detailCase.value, caseDetail.value))
const canEditDetailCase = computed(() => detailCase.value?.publishStatus === 0)
const showPublishedScoringRules = computed(() => detailCase.value?.publishStatus === 2)
const visibleScoringRules = computed(() =>
  showPublishedScoringRules.value
    ? detailForm.scoring_rules.filter(rule => rule.dimension.trim() || rule.scoring_standard.trim())
    : []
)
const relationsCurrentTitle = computed(() => {
  if (!relationsCase.value) {
    return ''
  }

  const department = relationsCase.value.departmentName || relationsCase.value.departmentId || '未关联'
  if (canManageInstitution.value) {
    const institution = relationsCase.value.institutionName || relationsCase.value.institutionId || '未关联'
    return `当前：机构 ${institution} / 科室 ${department}`
  }

  return `当前科室：${department}`
})

async function loadCases() {
  if (!appStore.token) {
    ElMessage.warning('缺少登录信息，请重新登录')
    return
  }

  try {
    loading.value = true
    const result = await fetchCases({
      token: appStore.token,
      search: filters.search,
      case_type: filters.case_type,
      publish_status: filters.publish_status,
      ...(canManageInstitution.value
        ? { institution: filters.institution }
        : {
            department: filters.department,
            status: filters.status,
            osce_enabled: filters.osce_enabled,
            ordering: filters.ordering
          }),
      page: pagination.page
    })
    cases.value = result.cases
    pagination.total = result.total
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '获取病例列表失败')
  } finally {
    loading.value = false
  }
}

function handleSearch() {
  pagination.page = 1
  loadCases()
}

function resetFilters() {
  filters.search = ''
  filters.case_type = ''
  filters.publish_status = ''
  filters.institution = ''
  filters.department = ''
  filters.status = ''
  filters.osce_enabled = ''
  filters.ordering = ''
  pagination.page = 1
  loadCases()
}

function handleSizeChange() {
  pagination.page = 1
  loadCases()
}

function openCreateDialog() {
  caseDialogVisible.value = true
  loadInstitutionOptions()
  loadDepartmentOptions(caseForm.institution_id)
}

function resetCaseForm() {
  resetDraftForm(caseForm)
  caseFormRef.value?.clearValidate()
}

function resetDetailForm() {
  detailCase.value = null
  caseDetail.value = null
  resetDraftForm(detailForm)
  detailFormRef.value?.clearValidate()
}

function resetDraftForm(form: CaseDraftForm) {
  form.title = ''
  form.case_type = 'traditional'
  form.institution_id = undefined
  form.department_id = undefined
  form.department_name = ''
  form.difficulty = ''
  form.chief_complaint = ''
  form.description = ''
  form.patient_age = undefined
  form.patient_gender = ''
  form.tags = ''
  form.icd_codes = ''
  form.estimated_minutes = undefined
  form.osce_enabled = false
  form.traditional_standard_diagnosis = ''
  form.traditional_standard_treatment = ''
  form.traditional_guideline_reference = ''
  form.teaching_learning_objectives = ''
  form.teaching_key_points = ''
  form.teaching_reference_answer = ''
  form.scoring_rules = [{ dimension: '', score_weight: 1, ai_auto_score: true, scoring_standard: '' }]
  form.exam_items = []
}

function addExamItem() {
  caseForm.exam_items.push({ item_code: '', item_name: '', item_type: '', result_text: '' })
}

function removeExamItem(index: number) {
  caseForm.exam_items.splice(index, 1)
}

function addDetailExamItem() {
  if (!canEditDetailCase.value) {
    return
  }

  detailForm.exam_items.push({ item_code: '', item_name: '', item_type: '', result_text: '' })
}

function removeDetailExamItem(index: number) {
  if (!canEditDetailCase.value) {
    return
  }

  detailForm.exam_items.splice(index, 1)
}

async function loadInstitutionOptions() {
  if (!appStore.token || !canManageInstitution.value || loadingInstitutions.value || institutionOptions.value.length) {
    return
  }

  try {
    loadingInstitutions.value = true
    institutionOptions.value = await fetchInstitutionList(appStore.token)
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '获取机构列表失败')
  } finally {
    loadingInstitutions.value = false
  }
}

async function loadDepartmentOptions(institutionId?: number) {
  if (!appStore.token || loadingDepartments.value) {
    return
  }
  if (canManageInstitution.value && !institutionId) {
    departmentOptions.value = []
    return
  }

  try {
    loadingDepartments.value = true
    departmentOptions.value = await fetchMyDepartments(appStore.token, institutionId)
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '获取科室列表失败')
  } finally {
    loadingDepartments.value = false
  }
}

function handleInstitutionVisibleChange(visible: boolean) {
  if (visible) {
    loadInstitutionOptions()
  }
}

function handleDepartmentVisibleChange(visible: boolean) {
  if (visible) {
    loadDepartmentOptions(activeCaseForm().institution_id)
  }
}

function handleCaseInstitutionChange() {
  caseForm.department_id = undefined
  caseForm.department_name = ''
  loadDepartmentOptions(caseForm.institution_id)
}

function handleDetailInstitutionChange() {
  detailForm.department_id = undefined
  detailForm.department_name = ''
  loadDepartmentOptions(detailForm.institution_id)
}

function handleCaseDepartmentChange(value?: number) {
  caseForm.department_name = getDepartmentName(value)
}

function handleDetailDepartmentChange(value?: number) {
  detailForm.department_name = getDepartmentName(value)
}

function activeCaseForm() {
  return detailDrawerVisible.value ? detailForm : caseForm
}

function getDepartmentName(value?: number) {
  if (!value) {
    return ''
  }

  return departmentOptions.value.find(item => item.id === value)?.name || ''
}

function institutionOptionLabel(item: InstitutionOption) {
  return item.code ? `${item.name} (${item.code})` : item.name
}

async function submitCaseForm() {
  if (!appStore.token) {
    ElMessage.warning('缺少登录信息，请重新登录')
    return
  }

  const isValid = await caseFormRef.value?.validate().catch(() => false)
  if (!isValid) {
    return
  }

  let payload: CreateCaseDraftPayload
  try {
    payload = buildCreatePayload()
  } catch (error) {
    ElMessage.warning(error instanceof Error ? error.message : '请检查病例表单')
    return
  }

  try {
    savingCase.value = true
    await createCaseDraft({
      token: appStore.token,
      payload
    })
    ElMessage.success('病例草稿已新增')
    caseDialogVisible.value = false
    pagination.page = 1
    await loadCases()
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '新增病例草稿失败')
  } finally {
    savingCase.value = false
  }
}

function buildCreatePayload(): CreateCaseDraftPayload {
  return buildDraftPayload(caseForm)
}

function buildDraftPayload(form: CaseDraftForm): CreateCaseDraftPayload {
  const structure = buildCaseStructure(form)
  const scoringRules = normalizeScoringRules(form)
  const examItems = normalizeExamItems(form)
  const payload: CreateCaseDraftPayload = {
    title: form.title.trim(),
    case_type: form.case_type,
    scoring_rules: scoringRules
  }

  payload[form.case_type] = structure
  if (canManageInstitution.value && form.institution_id) payload.institution_id = form.institution_id
  if (form.department_id) payload.department_id = form.department_id
  if (form.department_name.trim()) payload.department_name = form.department_name.trim()
  if (form.difficulty.trim()) payload.difficulty = form.difficulty.trim()
  if (form.chief_complaint.trim()) payload.chief_complaint = form.chief_complaint.trim()
  if (form.description.trim()) payload.description = form.description.trim()
  if (form.patient_age !== undefined) payload.patient_age = form.patient_age
  if (form.patient_gender) payload.patient_gender = form.patient_gender
  if (form.tags.trim()) {
    payload.tags = isContentAdmin.value ? form.tags.trim() : parseTextList(form.tags)
  }
  if (parseTextList(form.icd_codes).length) payload.icd_codes = parseTextList(form.icd_codes)
  if (form.estimated_minutes !== undefined) payload.estimated_minutes = form.estimated_minutes
  if (form.osce_enabled) payload.osce_enabled = form.osce_enabled
  if (examItems.length) payload.exam_items = examItems

  return payload
}

function buildSaveDraftPayload(form: CaseDraftForm): SaveCaseDraftPayload {
  const structure = buildEditableCaseStructure(form)
  const scoringRules = normalizeScoringRules(form)
  const examItems = normalizeExamItems(form)
  const payload: SaveCaseDraftPayload = {
    title: form.title.trim(),
    department_name: form.department_name.trim(),
    difficulty: form.difficulty.trim(),
    chief_complaint: form.chief_complaint.trim(),
    description: form.description.trim(),
    patient_gender: form.patient_gender,
    tags: isContentAdmin.value ? form.tags.trim() : parseTextList(form.tags),
    icd_codes: parseTextList(form.icd_codes),
    osce_enabled: form.osce_enabled,
    scoring_rules: scoringRules,
    exam_items: examItems
  }

  payload[form.case_type] = structure
  if (canManageInstitution.value && form.institution_id) payload.institution_id = form.institution_id
  if (form.department_id) payload.department_id = form.department_id
  if (form.patient_age !== undefined) payload.patient_age = form.patient_age
  if (form.estimated_minutes !== undefined) payload.estimated_minutes = form.estimated_minutes

  return payload
}

function buildCaseStructure(form: CaseDraftForm): Record<string, unknown> {
  if (form.case_type === 'teaching') {
    if (!form.teaching_learning_objectives.trim()) {
      throw new Error('请输入教学目标')
    }

    return {
      learning_objectives: form.teaching_learning_objectives.trim(),
      ...(form.teaching_key_points.trim() ? { key_points: form.teaching_key_points.trim() } : {}),
      ...(form.teaching_reference_answer.trim() ? { reference_answer: form.teaching_reference_answer.trim() } : {})
    }
  }

  if (!form.traditional_standard_diagnosis.trim()) {
    throw new Error('请输入标准诊断')
  }

  return {
    standard_diagnosis: form.traditional_standard_diagnosis.trim(),
    ...(form.traditional_standard_treatment.trim() ? { standard_treatment: form.traditional_standard_treatment.trim() } : {}),
    ...(form.traditional_guideline_reference.trim() ? { guideline_reference: form.traditional_guideline_reference.trim() } : {})
  }
}

function buildEditableCaseStructure(form: CaseDraftForm): Record<string, unknown> {
  if (form.case_type === 'teaching') {
    if (!form.teaching_learning_objectives.trim()) {
      throw new Error('请输入教学目标')
    }

    return {
      learning_objectives: form.teaching_learning_objectives.trim(),
      key_points: form.teaching_key_points.trim(),
      reference_answer: form.teaching_reference_answer.trim()
    }
  }

  if (!form.traditional_standard_diagnosis.trim()) {
    throw new Error('请输入标准诊断')
  }

  return {
    standard_diagnosis: form.traditional_standard_diagnosis.trim(),
    standard_treatment: form.traditional_standard_treatment.trim(),
    guideline_reference: form.traditional_guideline_reference.trim()
  }
}

function normalizeScoringRules(form: CaseDraftForm): CaseScoringRulePayload[] {
  const rules = form.scoring_rules
    .map((rule, index) => {
      const scoreWeight = Number(rule.score_weight)
      return {
        dimension: rule.dimension.trim() || (rule.scoring_standard.trim() ? `评分维度${index + 1}` : ''),
        score_weight: Number.isFinite(scoreWeight) && scoreWeight > 0 && scoreWeight <= 1 ? scoreWeight : 1,
        ai_auto_score: rule.ai_auto_score,
        scoring_standard: rule.scoring_standard.trim()
      }
    })
    .filter(rule => rule.dimension || rule.scoring_standard)

  if (!rules.length) {
    return [createDefaultScoringRule(form)]
  }

  for (const rule of rules) {
    rule.ai_auto_score = true
  }

  return rules.map(rule => ({
    dimension: rule.dimension,
    score_weight: rule.score_weight,
    ai_auto_score: rule.ai_auto_score,
    ...(rule.scoring_standard ? { scoring_standard: rule.scoring_standard } : {})
  }))
}

function createDefaultScoringRule(form: CaseDraftForm): CaseScoringRulePayload {
  return {
    dimension: form.case_type === 'teaching' ? '教学目标达成' : '诊断与处置',
    score_weight: 1,
    ai_auto_score: true,
    scoring_standard: '由AI根据病例内容生成评分标准'
  }
}

function normalizeExamItems(form: CaseDraftForm): CaseExamItemPayload[] {
  const items = form.exam_items
    .map((item, index) => ({
      index,
      item_code: item.item_code.trim(),
      item_name: item.item_name.trim(),
      item_type: item.item_type.trim(),
      result_text: item.result_text.trim()
    }))
    .filter(item => examItemFields.some(({ key }) => item[key]))

  const codes = new Set<string>()
  for (const item of items) {
    const missingLabels = examItemFields.filter(({ key }) => !item[key]).map(({ label }) => label)
    if (missingLabels.length) {
      throw new Error(`第${item.index + 1}个检查/检验项目需完整填写，缺少：${missingLabels.join('、')}`)
    }
    if (codes.has(item.item_code)) {
      throw new Error(`检查/检验项目编码重复：${item.item_code}`)
    }
    codes.add(item.item_code)
  }

  return items.map(item => ({
    item_code: item.item_code,
    item_name: item.item_name,
    item_type: item.item_type,
    result_text: item.result_text
  }))
}

function openImportDialog() {
  importDialogVisible.value = true
}

function resetImportFile() {
  importFile.value = null
  importCaseType.value = 'traditional'
  importFileList.value = []
  importUploadRef.value?.clearFiles()
}

const handleImportFileChange: UploadProps['onChange'] = uploadFile => {
  importFile.value = uploadFile.raw || null
}

const handleImportFileRemove: UploadProps['onRemove'] = () => {
  importFile.value = null
}

const handleImportExceed: UploadProps['onExceed'] = files => {
  const file = files[0] as UploadRawFile | undefined
  if (!file) {
    return
  }

  importUploadRef.value?.clearFiles()
  importUploadRef.value?.handleStart(file)
  importFile.value = file
}

async function submitImportPdf() {
  if (!appStore.token) {
    ElMessage.warning('缺少登录信息，请重新登录')
    return
  }
  if (!importFile.value) {
    ElMessage.warning('请先选择 PDF 文件')
    return
  }

  try {
    importing.value = true
    const result = await importCasePdf({
      token: appStore.token,
      file: importFile.value,
      case_type: importCaseType.value
    })
    fillCaseFormFromImportedPdf(result)
    importDialogVisible.value = false
    caseDialogVisible.value = true
    ElMessage.success('PDF 病例导入完成，请确认后保存草稿')
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '导入 PDF 病例失败')
  } finally {
    importing.value = false
  }
}

function openRelationsDialog(row: CaseListItem) {
  relationsCase.value = row
  relationsDialogVisible.value = true
}

function resetRelationsForm() {
  relationsCase.value = null
  relationsForm.institutionMode = 'keep'
  relationsForm.institution_id = undefined
  relationsForm.departmentMode = 'keep'
  relationsForm.department_id = undefined
  relationsForm.department_name = ''
}

async function submitRelationsForm() {
  if (!appStore.token || !relationsCase.value) {
    ElMessage.warning('缺少登录信息，请重新登录')
    return
  }

  let payload: UpdateCaseRelationsPayload
  try {
    payload = buildRelationsPayload()
  } catch (error) {
    ElMessage.warning(error instanceof Error ? error.message : '请检查关联信息')
    return
  }

  try {
    savingRelations.value = true
    await updateCaseRelations({
      token: appStore.token,
      id: relationsCase.value.id,
      payload
    })
    ElMessage.success('病例关联已更新')
    relationsDialogVisible.value = false
    await loadCases()
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '编辑病例关联失败')
  } finally {
    savingRelations.value = false
  }
}

function buildRelationsPayload(): UpdateCaseRelationsPayload {
  const payload: UpdateCaseRelationsPayload = {}

  if (canManageInstitution.value && relationsForm.institutionMode === 'set') {
    if (!relationsForm.institution_id) {
      throw new Error('请输入机构ID')
    }
    payload.institution_id = relationsForm.institution_id
  } else if (canManageInstitution.value && relationsForm.institutionMode === 'clear') {
    payload.institution_id = null
  }

  if (relationsForm.departmentMode === 'id') {
    if (!relationsForm.department_id) {
      throw new Error('请输入科室ID')
    }
    payload.department_id = relationsForm.department_id
  } else if (relationsForm.departmentMode === 'name') {
    if (!relationsForm.department_name.trim()) {
      throw new Error('请输入科室名称')
    }
    payload.department_name = relationsForm.department_name.trim()
  } else if (relationsForm.departmentMode === 'clear') {
    payload.department_id = null
  }

  if (!Object.keys(payload).length) {
    throw new Error(canManageInstitution.value ? '请至少修改机构或科室中的一项' : '请至少修改科室关联')
  }

  return payload
}

async function confirmSubmitCase(row: CaseListItem) {
  if (!appStore.token) {
    ElMessage.warning('缺少登录信息，请重新登录')
    return
  }

  try {
    await ElMessageBox.confirm(`确认提交「${row.title}」为正常状态吗？`, '提交病例', {
      confirmButtonText: '提交',
      cancelButtonText: '取消',
      type: 'warning'
    })
    await submitCase({
      token: appStore.token,
      id: row.id
    })
    ElMessage.success('病例已提交')
    await loadCases()
  } catch (error) {
    if (error !== 'cancel' && error !== 'close') {
      ElMessage.error(error instanceof Error ? error.message : '提交病例失败')
    }
  }
}

async function confirmDisableCase(row: CaseListItem) {
  if (!appStore.token) {
    ElMessage.warning('缺少登录信息，请重新登录')
    return
  }

  try {
    await ElMessageBox.confirm(`确认停用/重录「${row.title}」吗？`, '停用/重录病例', {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    })
    await disableCase({
      token: appStore.token,
      id: row.id
    })
    ElMessage.success('病例已停用/重录')
    await loadCases()
  } catch (error) {
    if (error !== 'cancel' && error !== 'close') {
      ElMessage.error(error instanceof Error ? error.message : '停用/重录病例失败')
    }
  }
}

async function openDetailDrawer(row: CaseListItem) {
  if (!appStore.token) {
    ElMessage.warning('缺少登录信息，请重新登录')
    return
  }

  detailCase.value = row
  detailDrawerVisible.value = true
  caseDetail.value = null
  loadInstitutionOptions()

  try {
    detailLoading.value = true
    caseDetail.value = await fetchCaseFull({
      token: appStore.token,
      id: row.id
    })
    fillDetailForm(row, caseDetail.value)
    loadDepartmentOptions(detailForm.institution_id)
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '获取病例详情失败')
  } finally {
    detailLoading.value = false
  }
}

async function submitDetailForm() {
  if (!appStore.token || !detailCase.value) {
    ElMessage.warning('缺少登录信息，请重新登录')
    return
  }
  if (!canEditDetailCase.value) {
    ElMessage.warning('只有草稿病例可以保存草稿')
    return
  }

  const isValid = await detailFormRef.value?.validate().catch(() => false)
  if (!isValid) {
    return
  }

  let payload: SaveCaseDraftPayload
  try {
    payload = buildSaveDraftPayload(detailForm)
  } catch (error) {
    ElMessage.warning(error instanceof Error ? error.message : '请检查病例表单')
    return
  }

  try {
    submittingDetail.value = true
    await saveCaseDraft({
      token: appStore.token,
      id: detailCase.value.id,
      payload
    })
    ElMessage.success('病例草稿已保存')
    detailDrawerVisible.value = false
    await loadCases()
  } catch (error) {
    ElMessage.error(error instanceof Error ? error.message : '保存病例草稿失败')
  } finally {
    submittingDetail.value = false
  }
}

function parseTextList(value: string): string[] {
  return value
    .split(/[,\n，；;]/)
    .map(item => item.trim())
    .filter(Boolean)
}

function fillCaseFormFromImportedPdf(result: ImportCasePdfResult) {
  resetDraftForm(caseForm)

  const record = getImportRecord(result.data)
  const caseType = normalizeImportCaseType(getImportString(record, ['case_type', 'caseType']), result.caseType)
  const traditional = getImportRecord(getImportFirst(record, ['traditional']))
  const teaching = getImportRecord(getImportFirst(record, ['teaching']))
  const scoringRules = getImportScoringRules(record)
  const examItems = getImportExamItems(record)

  caseForm.case_type = caseType
  caseForm.title = getImportString(record, ['title', 'name', 'case_title', 'caseTitle'])
  caseForm.department_name = getImportString(record, ['department_name', 'departmentName'])
  caseForm.department_id = getImportNumber(record, ['department_id', 'departmentId']) ?? undefined
  caseForm.difficulty = getImportString(record, ['difficulty'])
  caseForm.chief_complaint = getImportString(record, ['chief_complaint', 'chiefComplaint'])
  caseForm.description = getImportString(record, ['description', 'summary', 'content'])
  caseForm.patient_age = getImportNumber(record, ['patient_age', 'patientAge']) ?? undefined
  caseForm.patient_gender = normalizeImportGender(getImportString(record, ['patient_gender', 'patientGender']))
  caseForm.tags = getImportStringList(record, ['tags', 'tag_list', 'tagList']).join(', ')
  caseForm.icd_codes = getImportStringList(record, ['icd_codes', 'icdCodes', 'icd_list', 'icdList']).join(', ')
  caseForm.estimated_minutes = getImportNumber(record, ['estimated_minutes', 'estimatedMinutes']) ?? undefined
  caseForm.osce_enabled = getImportBoolean(record, ['osce_enabled', 'osceEnabled'])

  caseForm.traditional_standard_diagnosis = getImportString(traditional, ['standard_diagnosis', 'standardDiagnosis'])
  caseForm.traditional_standard_treatment = getImportString(traditional, ['standard_treatment', 'standardTreatment'])
  caseForm.traditional_guideline_reference = getImportString(traditional, ['guideline_reference', 'guidelineReference'])
  caseForm.teaching_learning_objectives = getImportString(teaching, ['learning_objectives', 'learningObjectives'])
  caseForm.teaching_key_points = getImportString(teaching, ['key_points', 'keyPoints'])
  caseForm.teaching_reference_answer = getImportString(teaching, ['reference_answer', 'referenceAnswer'])
  caseForm.scoring_rules = scoringRules.length
    ? scoringRules
    : [{ dimension: '', score_weight: 1, ai_auto_score: true, scoring_standard: '' }]
  caseForm.exam_items = examItems
  caseFormRef.value?.clearValidate()
}

function fillDetailForm(row: CaseListItem, fullData: unknown) {
  resetDraftForm(detailForm)

  const record = getDetailRecord(fullData)
  const traditional = getImportRecord(getImportFirst(record, ['traditional']))
  const teaching = getImportRecord(getImportFirst(record, ['teaching']))
  const scoringRules = getImportScoringRules(record)
  const examItems = getImportExamItems(record)

  detailForm.title = getImportString(record, ['title', 'name', 'case_title', 'caseTitle'], row.title)
  detailForm.case_type = normalizeImportCaseType(getImportString(record, ['case_type', 'caseType'], row.caseType), normalizeImportCaseType(row.caseType, 'traditional'))
  detailForm.institution_id = getImportNumber(record, ['institution_id', 'institutionId']) ?? undefined
  detailForm.department_id = getImportNumber(record, ['department_id', 'departmentId']) ?? undefined
  detailForm.department_name = getImportString(record, ['department_name', 'departmentName'], row.departmentName)
  detailForm.difficulty = getImportString(record, ['difficulty'], row.difficulty)
  detailForm.chief_complaint = getImportString(record, ['chief_complaint', 'chiefComplaint'], row.chiefComplaint)
  detailForm.description = getImportString(record, ['description', 'summary', 'content'])
  detailForm.patient_age = getImportNumber(record, ['patient_age', 'patientAge']) ?? undefined
  detailForm.patient_gender = normalizeImportGender(getImportString(record, ['patient_gender', 'patientGender']))
  detailForm.tags = getImportStringList(record, ['tags', 'tag_list', 'tagList']).join(', ')
  detailForm.icd_codes = getImportStringList(record, ['icd_codes', 'icdCodes', 'icd_list', 'icdList']).join(', ')
  detailForm.estimated_minutes = getImportNumber(record, ['estimated_minutes', 'estimatedMinutes']) ?? row.estimatedMinutes ?? undefined
  detailForm.osce_enabled = getImportBoolean(record, ['osce_enabled', 'osceEnabled'])
  detailForm.traditional_standard_diagnosis = getImportString(traditional, ['standard_diagnosis', 'standardDiagnosis'])
  detailForm.traditional_standard_treatment = getImportString(traditional, ['standard_treatment', 'standardTreatment'])
  detailForm.traditional_guideline_reference = getImportString(traditional, ['guideline_reference', 'guidelineReference'])
  detailForm.teaching_learning_objectives = getImportString(teaching, ['learning_objectives', 'learningObjectives'])
  detailForm.teaching_key_points = getImportString(teaching, ['key_points', 'keyPoints'])
  detailForm.teaching_reference_answer = getImportString(teaching, ['reference_answer', 'referenceAnswer'])
  detailForm.scoring_rules = scoringRules.length
    ? scoringRules
    : [{ dimension: '', score_weight: 1, ai_auto_score: true, scoring_standard: '' }]
  detailForm.exam_items = examItems
  detailFormRef.value?.clearValidate()
}

function getImportRecord(value: unknown): Record<string, unknown> {
  return value && typeof value === 'object' && !Array.isArray(value) ? (value as Record<string, unknown>) : {}
}

function getImportFirst(record: Record<string, unknown>, keys: string[]): unknown {
  for (const key of keys) {
    if (record[key] !== undefined && record[key] !== null) {
      return record[key]
    }
  }

  return undefined
}

function getImportString(record: Record<string, unknown>, keys: string[], fallback = ''): string {
  for (const key of keys) {
    const value = record[key]
    if (typeof value === 'string' && value.trim()) {
      return value.trim()
    }
    if (typeof value === 'number') {
      return String(value)
    }
  }

  return fallback
}

function getImportNumber(record: Record<string, unknown>, keys: string[]): number | null {
  const value = getImportFirst(record, keys)
  if (typeof value === 'number' && Number.isFinite(value)) {
    return value
  }
  if (typeof value === 'string' && value.trim() && Number.isFinite(Number(value))) {
    return Number(value)
  }

  return null
}

function getImportBoolean(record: Record<string, unknown>, keys: string[]) {
  const value = getImportFirst(record, keys)
  if (typeof value === 'boolean') {
    return value
  }
  if (typeof value === 'number') {
    return value === 1
  }
  if (typeof value === 'string') {
    const normalized = value.trim().toLowerCase()
    return ['true', '1', 'yes', 'y', 'on', '开启', '启用', '是'].includes(normalized)
  }

  return false
}

function getImportStringList(record: Record<string, unknown>, keys: string[]): string[] {
  const value = getImportFirst(record, keys)
  if (Array.isArray(value)) {
    return value
      .map(item => {
        if (typeof item === 'string' || typeof item === 'number') {
          return String(item).trim()
        }
        const itemRecord = getImportRecord(item)
        return getImportString(itemRecord, ['name', 'title', 'code', 'value'])
      })
      .filter(Boolean)
  }

  if (typeof value === 'string') {
    return parseTextList(value)
  }

  return []
}

function getImportScoringRules(record: Record<string, unknown>): ScoringRuleForm[] {
  const raw = getImportFirst(record, ['scoring_rules', 'scoringRules'])
  if (!Array.isArray(raw)) {
    return []
  }

  return raw
    .map(item => {
      const itemRecord = getImportRecord(item)
      const scoreWeight = getImportNumber(itemRecord, ['score_weight', 'scoreWeight', 'weight'])
      const rawAutoScore = getImportFirst(itemRecord, ['ai_auto_score', 'aiAutoScore'])
      return {
        dimension: getImportString(itemRecord, ['dimension', 'name']),
        score_weight: scoreWeight ?? 1,
        ai_auto_score: rawAutoScore === undefined ? true : getImportBoolean(itemRecord, ['ai_auto_score', 'aiAutoScore']),
        scoring_standard: getImportString(itemRecord, ['scoring_standard', 'scoringStandard', 'description'])
      }
    })
    .filter(item => item.dimension || item.scoring_standard)
}

function getImportExamItems(record: Record<string, unknown>): ExamItemForm[] {
  const raw = getImportFirst(record, ['exam_items', 'examItems'])
  if (!Array.isArray(raw)) {
    return []
  }

  return raw
    .map(item => {
      const itemRecord = getImportRecord(item)
      return {
        item_code: getImportString(itemRecord, ['item_code', 'itemCode', 'code']),
        item_name: getImportString(itemRecord, ['item_name', 'itemName', 'name']),
        item_type: getImportString(itemRecord, ['item_type', 'itemType', 'type']),
        result_text: getImportString(itemRecord, ['result_text', 'resultText'])
      }
    })
    .filter(item => item.item_code || item.item_name || item.item_type || item.result_text)
}

function normalizeImportCaseType(value: string, fallback: DraftCaseType): DraftCaseType {
  return value === 'teaching' ? 'teaching' : fallback
}

function normalizeImportGender(value: string) {
  if (value === '男') return 'male'
  if (value === '女') return 'female'
  if (value === '未知') return 'unknown'
  return ['male', 'female', 'unknown'].includes(value) ? value : ''
}

function createDetailDisplay(row: CaseListItem | null, fullData: unknown) {
  const record = getDetailRecord(fullData)
  const title = getDetailString(record, ['title', 'name']) || row?.title || '-'
  const caseType = getDetailString(record, ['case_type', 'caseType']) || row?.caseType || ''
  const difficulty = getDetailString(record, ['difficulty']) || row?.difficulty || '-'
  const institution = getDetailString(record, ['institution_name', 'institutionName']) || row?.institutionName || row?.institutionId || '-'
  const department = getDetailString(record, ['department_name', 'departmentName']) || row?.departmentName || row?.departmentId || '-'
  const chiefComplaint = getDetailString(record, ['chief_complaint', 'chiefComplaint']) || row?.chiefComplaint || '-'
  const description = getDetailString(record, ['description', 'summary', 'content']) || '-'
  const patientAge = getDetailString(record, ['patient_age', 'patientAge'])
  const patientGender = patientGenderLabel(getDetailString(record, ['patient_gender', 'patientGender']))
  const estimatedMinutes = getDetailString(record, ['estimated_minutes', 'estimatedMinutes']) || (row?.estimatedMinutes ? String(row.estimatedMinutes) : '')

  return {
    id: getDetailString(record, ['id']) || row?.id || '-',
    title,
    caseType,
    difficulty,
    institution,
    department,
    chiefComplaint,
    description,
    patient: [patientAge ? `${patientAge}岁` : '', patientGender].filter(Boolean).join(' / ') || '-',
    estimatedMinutes: estimatedMinutes ? `${estimatedMinutes} 分钟` : '-'
  }
}

function getDetailRecord(value: unknown): Record<string, unknown> {
  if (!value || typeof value !== 'object' || Array.isArray(value)) {
    return {}
  }

  const record = value as Record<string, unknown>
  if (record.data && typeof record.data === 'object' && !Array.isArray(record.data)) {
    return record.data as Record<string, unknown>
  }

  return record
}

function getDetailString(record: Record<string, unknown>, keys: string[]) {
  for (const key of keys) {
    const value = record[key]
    if (typeof value === 'string' && value.trim()) return value
    if (typeof value === 'number') return String(value)
  }

  return ''
}

function caseTypeLabel(type: string) {
  const labels: Record<string, string> = {
    traditional: '传统病例',
    teaching: '教学病例'
  }

  return labels[type] || type || '-'
}

function patientGenderLabel(value: string) {
  if (value === 'male' || value === '男') return '男'
  if (value === 'female' || value === '女') return '女'
  if (value === 'unknown') return '未知'
  return value || ''
}

function publishStatusLabel(status: CasePublishStatus | null) {
  if (status === 0) return '草稿'
  if (status === 1) return '正常'
  if (status === 2) return '已发布'
  return '-'
}

function publishStatusTagType(status: CasePublishStatus | null) {
  if (status === 0) return 'info'
  if (status === 1) return 'warning'
  if (status === 2) return 'success'
  return 'info'
}

function difficultyTagType(value: string) {
  if (['高', 'high', 'hard'].includes(value.toLowerCase())) return 'danger'
  if (['中', 'medium', 'middle'].includes(value.toLowerCase())) return 'warning'
  if (['低', 'low', 'easy'].includes(value.toLowerCase())) return 'success'
  return 'info'
}

function formatDateTime(value: string) {
  if (!value) {
    return '-'
  }

  return value.replace('T', ' ').slice(0, 19)
}

function formatScoreWeight(value: number) {
  if (!Number.isFinite(value)) {
    return '-'
  }

  return value <= 1 ? `${Math.round(value * 100)}%` : String(value)
}

onMounted(loadCases)
</script>
