<template>
  <div class="exam-app-container" style="width: 100%; max-width: 1200px;">
    <!-- ====== 顶部卡片：申请单列表 ====== -->
    <div class="top-section">
      <div class="section-header">
        <span class="section-title">检查项目 ({{ applicationList.length }})</span>
        <div class="header-actions">
          <el-button type="primary" @click="handleAdd" icon="Plus">新增</el-button>
          <el-button type="success" @click="handleSave" icon="Finished">保存</el-button>
        </div>
      </div>
      <el-table
        v-loading="loading"
        :data="applicationList"
        :max-height="200"
        highlight-current-row
        @row-click="handleRowClick"
        border
        size="small"
        :header-cell-style="{ background: '#f5f5f5', color: '#303133', fontWeight: '600' }"
      >
        <el-table-column type="selection" width="40" align="center" />
        <el-table-column label="申请ID" prop="id" width="80" align="center" />
        <el-table-column label="申请单号" prop="applyNo" min-width="140" align="center" />
        <el-table-column label="申检部位" prop="inspectionArea" min-width="100" align="center" />
        <el-table-column label="申请医生" prop="applyDocCode" min-width="90" align="center" />
        <el-table-column label="急" prop="isUrgent" width="50" align="center">
          <template #default="{ row }">
            <el-checkbox v-model="row.isUrgent" :true-label="1" :false-label="0" disabled />
          </template>
        </el-table-column>
        <el-table-column label="收费" prop="isCharged" width="50" align="center">
          <template #default="{ row }">
            <el-checkbox v-model="row.isCharged" :true-label="1" :false-label="0" disabled />
          </template>
        </el-table-column>
        <el-table-column label="退费" prop="isRefunded" width="50" align="center">
          <template #default="{ row }">
            <el-checkbox v-model="row.isRefunded" :true-label="1" :false-label="0" disabled />
          </template>
        </el-table-column>
        <el-table-column label="执行" prop="isExecuted" width="50" align="center">
          <template #default="{ row }">
            <el-checkbox v-model="row.isExecuted" :true-label="1" :false-label="0" disabled />
          </template>
        </el-table-column>
        <el-table-column label="金额" prop="totalAmount" width="90" align="right">
          <template #default="{ row }">
            {{ (row.totalAmount || 0).toFixed(2) }}
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80" align="center" fixed="right">
          <template #default="{ row }">
            <el-button link @click.stop="handlePrint(row)" title="打印">
              <el-icon><Printer /></el-icon>
            </el-button>
            <el-button link type="danger" @click.stop="handleDelete(row)" title="删除">
              <el-icon><Delete /></el-icon>
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </div>

    <!-- ====== 底部主区：左表单 + 右分类 ====== -->
    <div class="bottom-section">
      <!-- 左：表单区 -->
      <div class="form-panel">
        <el-tabs v-model="activeDetailTab" class="form-tabs">
          <!-- TAB1：检查申请单 -->
          <el-tab-pane label="检查申请单" name="applyForm">
            <el-form ref="formRef" :model="form" :rules="rules" size="small" class="apply-form">
              <el-row :gutter="12">
                <el-col :span="8">
                  <el-form-item label="申请单号" prop="applyNo">
                    <el-input v-model="form.applyNo" readonly placeholder="自动生成" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="姓名" prop="patientName">
                    <el-input v-model="form.patientName" readonly />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="就诊卡号" prop="medicalrecordNumber">
                    <el-input v-model="form.medicalrecordNumber" readonly />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="12">
                <el-col :span="8">
                  <el-form-item label="费用性质" prop="natureofCost">
                    <el-select v-model="form.natureofCost" style="width:100%">
                      <el-option label="自费医疗" value="自费医疗" />
                      <el-option label="医保报销" value="医保报销" />
                    </el-select>
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="申请日期" prop="applyTime">
                    <el-date-picker v-model="form.applyTime" type="date" style="width:100%"
                      format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="申请科室" prop="applyDeptCode">
                    <el-input v-model="form.applyDeptCode" disabled />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="12">
                <el-col :span="8">
                  <el-form-item label="申请医生" prop="applyDocCode">
                    <el-input v-model="form.applyDocCode" disabled />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="执行科室" prop="performDeptCode">
                    <el-select
                      v-model="form.performDeptCode"
                      style="width: 100%"
                      filterable
                      remote
                      reserve-keyword
                      clearable
                      placeholder="请选择执行科室（支持模糊查询）"
                      :remote-method="handleOrgRemoteSearch"
                      :loading="orgLoading"
                    >
                      <el-option
                        v-for="opt in orgFilteredOptions"
                        :key="opt.value"
                        :label="opt.label"
                        :value="opt.value"
                      />
                      <template #empty>
                        <div style="padding: 10px 0; color: #909399; text-align: center;">
                          {{ orgLoading ? '加载中...' : '暂无匹配科室' }}
                        </div>
                      </template>
                    </el-select>
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="12">
                <el-col :span="24">
                  <el-form-item label="诊断描述" prop="clinicDesc">
                    <el-input v-model="form.clinicDesc" />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="12">
                <el-col :span="8">
                  <el-form-item label="禁忌症" prop="contraindication">
                    <el-input v-model="form.contraindication" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="临床诊断" prop="clinicalDiag">
                    <el-input v-model="form.clinicalDiag" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="病史摘要" prop="medicalHistorySummary">
                    <el-input v-model="form.medicalHistorySummary" />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="12">
                <el-col :span="24">
                  <el-form-item label="检查目的" prop="purposeDesc">
                    <el-input v-model="form.purposeDesc" />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="12">
                <el-col :span="8">
                  <el-form-item label="体格检查">
                    <el-input v-model="form.purposeofInspection" placeholder="T(摄氏度) P次/分 R次/分 BF" />
                  </el-form-item>
                </el-col>
                <el-col :span="8">
                  <el-form-item label="申检部位">
                    <el-input v-model="form.inspectionArea" readonly />
                  </el-form-item>
                </el-col>
                <!-- Bug #384修复: 添加检查方法只读输入框，联动显示选中的检查方法 -->
                <el-col :span="8">
                  <el-form-item label="检查方法">
                    <el-input v-model="form.selectedMethodDisplay" readonly placeholder="请在右侧选择" />
                  </el-form-item>
                </el-col>
              </el-row>
              <el-row :gutter="12">
                <el-col :span="8">
                  <el-form-item label="备注" prop="applyRemark">
                    <el-input v-model="form.applyRemark" />
                  </el-form-item>
                </el-col>
                <el-col :span="16">
                  <el-form-item label="状态">
                    <el-checkbox v-model="form.isUrgent" :true-label="1" :false-label="0">急</el-checkbox>
                    <el-checkbox v-model="form.isCharged" :true-label="1" :false-label="0" disabled>收费</el-checkbox>
                    <el-checkbox v-model="form.isRefunded" :true-label="1" :false-label="0" disabled>退费</el-checkbox>
                    <el-checkbox v-model="form.isExecuted" :true-label="1" :false-label="0" disabled>执行</el-checkbox>
                  </el-form-item>
                </el-col>
              </el-row>
            </el-form>
          </el-tab-pane>

          <!-- TAB2：检查明细 -->
          <el-tab-pane label="检查明细" name="applyDetail">
            <!-- 🔧 BugFix#426: 支持树形展开显示套餐明细 -->
            <el-table
              ref="detailTableRef"
              :data="selectedItems"
              row-key="id"
              border
              size="small"
              style="width:100%"
              :max-height="350"
              :header-cell-style="{ background: '#f5f5f5', color: '#303133' }"
              :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
              :load="loadPackageDetails"
              lazy
            >
              <el-table-column label="行" type="index" width="45" align="center" />
              <el-table-column label="检查项目" prop="name" min-width="120">
                <template #default="scope">
                  <el-tag v-if="scope.row.isPackage" size="small" type="warning" style="margin-right: 4px">套餐</el-tag>
                  <span>{{ scope.row.name }}</span>
                </template>
              </el-table-column>
              <el-table-column label="部位" prop="applyPart" min-width="90">
                <template #default="scope">
                  <el-input v-model="scope.row.applyPart" size="small" />
                </template>
              </el-table-column>
              <el-table-column label="检查方法" min-width="120">
                <template #default="scope">
                  <!-- Bug #384修复: 显示检查方法名称，不显示套餐名称 -->
                  <span v-if="scope.row.selectedMethod">
                    {{ scope.row.selectedMethod.name }}
                  </span>
                  <span v-else-if="scope.row.methods && scope.row.methods.length > 0" style="color: #909399;">
                    未选择
                  </span>
                  <span v-else style="color: #c0c4cc;">-</span>
                </template>
              </el-table-column>
              <el-table-column label="单位" prop="unit" width="55" align="center" />
              <el-table-column label="总量" prop="quantity" width="70" align="center">
                <template #default="scope">
                  <el-input-number v-model="scope.row.quantity" :min="1" size="small" :controls="false" style="width:100%" />
                </template>
              </el-table-column>
              <!-- Bug #384修复: 单价显示套餐价格（如果选中）或部位价格 -->
              <el-table-column label="单价" width="75" align="right">
                <template #default="scope">
                  {{ scope.row.selectedMethod?.packagePrice || scope.row.price }}
                </template>
              </el-table-column>
              <!-- Bug #384修复: 金额使用有效价格计算 -->
              <el-table-column label="金额" width="80" align="right">
                <template #default="scope">
                  {{ ((scope.row.selectedMethod?.packagePrice || scope.row.price || 0) * (scope.row.quantity || 1)).toFixed(2) }}
                </template>
              </el-table-column>
              <el-table-column label="类型" prop="checkType" width="70" align="center" />
              <el-table-column label="国码" prop="nationalCode" width="70" align="center" />
              <el-table-column label="自费" width="50" align="center">
                <template #default>
                  <el-checkbox disabled />
                </template>
              </el-table-column>
            </el-table>
            <div class="total-row">
              合计：<span class="total-amount">{{ totalAmountCalc }}</span>
            </div>
          </el-tab-pane>
        </el-tabs>
      </div>

      <!-- 右：检查项目分类面板 -->
      <div class="category-panel">
        <div class="panel-top">
          <!-- 左侧：分类搜索 + 折叠树 -->
          <div class="category-left">
            <div class="panel-label">检查项目分类</div>
            <el-input
              v-model="dictSearchKey"
              placeholder="搜索检查项目（支持拼音首字母）"
              prefix-icon="Search"
              clearable
              size="small"
              class="search-input"
            />
            <!-- 分类折叠列表 -->
            <div class="collapse-scroll" v-loading="dictLoading">
              <div v-if="filteredCategoryList.length === 0" class="empty-hint">
                {{ dictLoading ? '' : '暂无检查项目，请在"检查项目设置"中配置' }}
              </div>
              <el-collapse v-else v-model="activeNames" @change="(activeNames) => handleCollapseChange(activeNames)">
                <el-collapse-item
                  v-for="cat in filteredCategoryList"
                  :key="cat.typeId"
                  :name="cat.typeId"
                >
                  <template #title>
                    <span class="cat-title">{{ cat.categoryName }}</span>
                  </template>
                  <div
                    v-for="item in cat.items"
                    :key="item.id"
                    class="item-row"
                  >
                    <el-checkbox
                      v-model="item.checked"
                      @change="(val) => handleItemSelect(val, item, cat)"
                      class="item-checkbox"
                    >
                      {{ item.name }}
                    </el-checkbox>
                    <span class="item-price">¥{{ item.price }}/{{ item.unit || "次" }}</span>
                  </div>
                </el-collapse-item>
              </el-collapse>
            </div>
          </div>

          <!-- 右侧：已选择 项目卡片（可展开显示检查方法） -->
          <div class="selected-panel">
            <div class="panel-label">已选择:</div>
            <div class="selected-tags">
              <div v-if="selectedItems.length === 0" class="empty-selected">–</div>
              <div
                v-else
                v-for="(item, idx) in selectedItems"
                :key="idx"
                class="selected-item-card"
              >
                <!-- Bug #384修复: 项目卡片头部，可展开/收起 -->
                <div class="card-header" @click="toggleItemExpand(item)">
                  <span class="card-name">{{ item.name }}</span>
                  <span class="card-price">¥{{ item.price }}</span>
                  <!-- 展开图标 -->
                  <el-icon :class="['expand-icon', { expanded: item.expanded }]">
                    <ArrowDown v-if="!item.expanded" />
                    <ArrowUp v-if="item.expanded" />
                  </el-icon>
                  <!-- 删除按钮 -->
                  <el-button link type="danger" size="small" @click.stop="handleRemoveItem(idx, item)">
                    <el-icon><Close /></el-icon>
                  </el-button>
                </div>
                <!-- Bug #428修复: 展开后显示套餐明细或检查方法 -->
                <div v-if="item.expanded">
                  <!-- 显示套餐明细 -->
                  <div v-if="item.packageDetails && item.packageDetails.length > 0" class="package-details-list">
                    <div class="detail-row" v-for="detail in item.packageDetails" :key="detail.id">
                      <span class="detail-name">{{ detail.name }}</span>
                      <span class="detail-info">数量: {{ detail.quantity }} 单价: ¥{{ detail.price }}</span>
                    </div>
                  </div>
                  <!-- 显示检查方法 -->
                  <div v-else-if="item.methods && item.methods.length > 0" class="method-list">
                    <div v-for="method in item.methods" :key="method.id" class="method-option">
                      <el-checkbox :model-value="item.selectedMethod?.id === method.id" @change="(val) => selectMethodCheckbox(val, item, method)">
                        <span class="method-name">{{ method.name }}</span>
                        <span class="method-price">¥{{ method.packagePrice || item.price }}</span>
                      </el-checkbox>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, computed, watch, onMounted, nextTick } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import { Printer, Delete, ArrowDown, ArrowUp, Close } from '@element-plus/icons-vue';
import useUserStore from '@/store/modules/user';
import request from '@/utils/request';
import { listCheckMethod, searchCheckMethod } from '@/api/system/checkType';
import { getEncounterDiagnosis } from '../api.js';

const props = defineProps({
  patientInfo: { type: Object, default: () => ({}) },
  activeTab: { type: String, default: '' }
});

// 保存成功后通知父组件刷新医嘱列表
const emit = defineEmits(['saved']);

const userStore = useUserStore();
const loading = ref(false);
const dictLoading = ref(false);
const activeDetailTab = ref('applyForm');
const applicationList = ref([]);
const selectedItems = ref([]);

// 🔧 BugFix#426: 懒加载套餐明细
async function loadPackageDetails(row, treeNode, resolve) {
  if (!row.isPackage || !row.packageId) {
    resolve([]);
    return;
  }
  try {
    const res = await request({
      url: `/exam/package/${row.packageId}/details`,
      method: 'get'
    });
    if (res.code === 200 && res.data) {
      const children = res.data.map(item => ({
        ...item,
        name: item.name || item.itemName,
        unit: item.unit || '次',
        price: item.price || item.itemPrice || 0,
        quantity: row.quantity || 1,
        isPackageDetail: true
      }));
      resolve(children);
    } else {
      resolve([]);
    }
  } catch (err) {
    console.error('加载套餐明细失败:', err);
    resolve([]);
  }
}

// #428: 为已选择项目加载套餐明细
async function loadPackageDetailsForItem(item) {
  if (!item.isPackage || !item.packageId) {
    return;
  }
  try {
    const res = await request({
      url: `/exam/package/${item.packageId}/details`,
      method: 'get'
    });
    if (res.code === 200 && res.data) {
      item.packageDetails = res.data.map(detail => ({
        ...detail,
        name: detail.name || detail.itemName,
        unit: detail.unit || '次',
        price: detail.price || detail.itemPrice || 0,
        quantity: detail.quantity || 1
      }));
    } else {
      item.packageDetails = [];
    }
  } catch (err) {
    console.error('加载套餐明细失败:', err);
    item.packageDetails = [];
  }
}
const detailTableRef = ref(null);
const formRef = ref(null);

// ====== 表单数据 ======
const form = reactive({
  applyNo: '',
  patientName: '',
  patientId: '',
  visitNo: '',
  applyDeptCode: '',
  performDeptCode: '',
  applyDocCode: '',
  applyTime: '',
  medicalrecordNumber: '',
  natureofCost: '自费医疗',
  clinicDesc: '',
  contraindication: '',
  medicalHistorySummary: '',
  purposeofInspection: '',
  inspectionArea: '',
  inspectionMethod: '',
  applyRemark: '',
  clinicalDiag: '',
  purposeDesc: '',
  isUrgent: 0,
  pregnancyState: 0,
  allergyDesc: '',
  applyStatus: 0,
  isCharged: 0,
  isRefunded: 0,
  isExecuted: 0,
  examTypeCode: '',   // 检查类型编码，必填字段，保存时从已选项目自动推导
  selectedMethodDisplay: ''  // Bug #384修复: 检查方法显示字段（联动）
});

const rules = {
  natureofCost: [{ required: true, message: '请选择费用性质', trigger: 'change' }],
  applyDeptCode: [{ required: true, message: '请输入申请科室', trigger: 'blur' }],
  applyDocCode: [{ required: true, message: '请输入申请医生', trigger: 'blur' }],
  performDeptCode: [{ required: true, message: '请输入执行科室', trigger: 'blur' }],
  clinicDesc: [{ required: true, message: '请输入诊断描述', trigger: 'blur' }],
  clinicalDiag: [{ required: true, message: '请输入临床诊断', trigger: 'blur' }],
  medicalHistorySummary: [{ required: true, message: '请输入病史摘要', trigger: 'blur' }],
  purposeDesc: [{ required: true, message: '请输入检查目的', trigger: 'blur' }]
};

// ====== 检查项目分类 ======
const categoryList = ref([]);   // 原始分类+项目数据
const dictSearchKey = ref('');
const activeNames = ref([]);    // 当前展开的折叠项

const allMethods = ref([]);

// ====== 科室下拉（来源：科室管理）======
const orgLoading = ref(false);
const orgOptions = ref([]); // { label, value }
const orgFilteredOptions = ref([]); // 展示用（截断前200条）

// 加载所有检查方法
async function loadAllMethods() {
  try {
    const res = await listCheckMethod(); // 使用已导入的或者直接利用 request 请求
    let methods = [];
    if (res && res.data) {
      if (Array.isArray(res.data)) {
        methods = res.data;
      } else if (res.data.records) {
        methods = res.data.records;
      } else if (res.data.data && Array.isArray(res.data.data)) {
        methods = res.data.data;
      }
    } else if (Array.isArray(res)) {
      methods = res;
    } else if (res && res.rows) {
      methods = res.rows;
    }
    allMethods.value = methods;
  } catch (err) {
    console.error('加载检查方法失败', err);
  }
}

onMounted(async () => {
  await loadOrgOptions();
  await loadAllMethods();
  await loadCategoryList();
});

async function loadOrgOptions() {
  orgLoading.value = true;
  try {
    const res = await request({
      url: '/base-data-manage/organization/organization',
      method: 'get',
    });
    const records = res?.data?.records || res?.data || [];

    const flat = [];
    const walk = (nodes) => {
      if (!Array.isArray(nodes)) return;
      for (const n of nodes) {
        if (!n) continue;
        // 约定：typeEnum=2 为科室；若没有 typeEnum 也兜底收集
        if (n.name && (n.typeEnum === 2 || n.typeEnum === '2' || n.typeEnum == null)) {
          flat.push({ label: n.name, value: n.name });
        }
        if (Array.isArray(n.children) && n.children.length > 0) walk(n.children);
      }
    };
    walk(records);

    // 去重 + 排序
    const uniq = Array.from(new Map(flat.map(o => [o.value, o])).values())
      .filter(o => o?.value)
      .sort((a, b) => (a.label || '').localeCompare(b.label || '', 'zh-CN'));

    orgOptions.value = uniq;
    orgFilteredOptions.value = uniq.slice(0, 200);
  } catch (e) {
    console.error('加载科室列表失败', e);
    orgOptions.value = [];
    orgFilteredOptions.value = [];
  } finally {
    orgLoading.value = false;
  }
}

function handleOrgRemoteSearch(keyword) {
  const key = (keyword || '').trim().toLowerCase();
  if (!key) {
    orgFilteredOptions.value = orgOptions.value.slice(0, 200);
    return;
  }
  orgFilteredOptions.value = orgOptions.value
    .filter((o) => (o.label || '').toLowerCase().includes(key))
    .slice(0, 200);
}

// 动态可用的检查方法（根据已选部位所属的检查类型进行过滤）
const normalizeTypeValue = value => String(value ?? '').trim().toLowerCase();

const availableMethods = computed(() => {
  // 获取当前已选部位的检查类型（可取第一个选中的部位的 checkType）
  const currentType = form.examTypeCode || (selectedItems.value.length > 0 ? selectedItems.value[0].checkType : '');
  const normalizedCurrentType = normalizeTypeValue(currentType);
  if (normalizedCurrentType) {
    // 兼容脏数据：method 的类型可能落在 checkType/type/typeCode/code/typeName/categoryName 中
    const filtered = allMethods.value.filter(m => {
      const typeCandidates = [
        m.checkType,
        m.type,
        m.typeCode,
        m.code,
        m.typeName,
        m.categoryName
      ].map(normalizeTypeValue).filter(Boolean);
      return typeCandidates.includes(normalizedCurrentType);
    });
    return filtered.length > 0 ? filtered : allMethods.value;
  }
  return allMethods.value;
});

// 当可选方法列表改变时，如果当前选中的方法不在新列表中，则清空
// #428: 分类展开时联动加载检查方法
async function handleCategoryExpand(cat) {
  if (!cat || !cat.typeName) return;
  
  try {
    const res = await searchCheckMethod({ checkType: cat.typeName });
    let data = res?.data?.data || res?.data || res?.rows || res;
    if (!Array.isArray(data) && res?.data && Array.isArray(res.data.data)) {
      data = res.data.data;
    }
    
    if (Array.isArray(data) && data.length > 0) {
      cat.methods = data.map(m => ({
        id: m.id,
        name: m.name,
        code: m.code,
        price: m.price || 0,
        packageName: m.packageName || '',
        packagePrice: m.packagePrice || null,
        serviceFee: m.serviceFee || null
      }));
    }
  } catch (err) {
    console.error('加载分类检查方法失败', err);
  }
}
async function handleCollapseChange(activeNames) {
  // 当折叠面板展开时，加载对应分类的检查方法
  if (Array.isArray(activeNames) && activeNames.length > 0) {
    for (const typeId of activeNames) {
      const cat = filteredCategoryList.value.find(c => c.typeId == typeId);
      if (cat && (!cat.methods || cat.methods.length === 0)) {
        await handleCategoryExpand(cat);
      }
    }
  }
}

watch(availableMethods, (newMethods) => {
  if (form.inspectionMethod && !newMethods.find(m => m.name === form.inspectionMethod)) {
    form.inspectionMethod = '';
  }
});

/**
 * 加载检查类型（分类）和检查项目（部位/项目），按类型分组展示
 */
async function loadCategoryList() {
  dictLoading.value = true;
  try {
    // 1. 加载检查类型（分类名称），只取父级
    const typeRes = await request({
      url: '/system/check-type/list',
      method: 'get',
      params: { pageNo: 1, pageSize: 500 }  // 取全量分类数据
    });
    let types = [];
    if (typeRes && typeRes.data) {
      if (Array.isArray(typeRes.data)) {
        types = typeRes.data;
      } else if (typeRes.data.records) {
        types = typeRes.data.records;
      } else if (typeRes.data.data && Array.isArray(typeRes.data.data)) {
        types = typeRes.data.data;
      }
    } else if (Array.isArray(typeRes)) {
      types = typeRes;
    } else if (typeRes && typeRes.rows) {
      types = typeRes.rows;
    }

    // 2. 加载检查项目（检查部位项目）
    const partRes = await request({ url: '/check/part/list', method: 'get' });
    let parts = [];
    if (partRes && partRes.data) {
      if (Array.isArray(partRes.data)) {
        parts = partRes.data;
      } else if (partRes.data.records) {
        parts = partRes.data.records;
      } else if (partRes.data.data && Array.isArray(partRes.data.data)) {
        parts = partRes.data.data;
      }
    } else if (Array.isArray(partRes)) {
      parts = partRes;
    } else if (partRes && partRes.rows) {
      parts = partRes.rows;
    }

    // 3. 按 checkType 归类
    const dict = [];
    for (const t of types) {
      dict.push({
        typeId: t.id,
        typeCode: t.code,        // 保存 code 用于后备匹配
        orgType: t.type,         // 保存 type 用于后备匹配
        typeName: t.name,        // 保存 name
        categoryName: t.name,
        // “检查类型管理”里配置的执行科室（图三）
        performDeptName: t.department || '',
        items: []
      });
    }
    const unclassified = [];
    for (const p of parts) {
      const mapped = {
        id: p.id,
        name: p.name,
        price: p.price || 0,
        serviceFee: p.serviceFee || 0,
        unit: '次',
        checkType: p.checkType || '',
        nationalCode: p.nationalCode || '',
        packageName: p.packageName || '',
        checked: false
      };
      
      // 增强匹配逻辑：部位的 checkType (如 'ECG', 'CT') 优先去匹配大类的 orgType，
      // 如果大类的 type 字段脏了（比如填了中文），则尝试匹配 code，甚至是分类名称
      const target = dict.find(d => 
        d.orgType === p.checkType || 
        d.typeCode === p.checkType ||
        d.typeName === p.checkType
      );
      
      if (target) target.items.push(mapped);
      else unclassified.push(mapped);
    }
    if (unclassified.length > 0) {
      dict.push({ typeId: 'uncls', typeCode: '', categoryName: '其他', items: unclassified });
    }
    categoryList.value = dict.filter(d => d.items.length > 0);

    // 默认展开第一个
    if (categoryList.value.length > 0) {
      activeNames.value = [categoryList.value[0].typeId];
    }
  } catch (err) {
    console.error('加载检查项目分类失败', err);
  } finally {
    dictLoading.value = false;
  }
}

/** 关键词过滤后的分类列表 */
const filteredCategoryList = computed(() => {
  if (!dictSearchKey.value) return categoryList.value;
  const key = dictSearchKey.value.toLowerCase();
  return categoryList.value.map(cat => ({
    ...cat,
    items: cat.items.filter(item => (item.name || '').toLowerCase().includes(key))
  })).filter(cat => cat.items.length > 0);
});

// ====== 合计 ======
// Bug #384修复: 如果选中了检查方法，使用套餐价格；否则使用部位价格
const totalAmountCalc = computed(() => {
  const total = selectedItems.value.reduce((sum, item) => {
    const effectivePrice = item.selectedMethod?.packagePrice || item.price;
    return sum + (effectivePrice * (item.quantity || 1));
  }, 0);
  return total.toFixed(2);
});

// 监听已选项：自动更新申检部位
watch(selectedItems, () => {
  form.inspectionArea = selectedItems.value.map(i => i.name).join('+');
  form.isCharged = selectedItems.value.length > 0 ? 1 : 0;
}, { deep: true });

// 监听患者变化
watch(() => props.patientInfo, (newVal) => {
  if (newVal?.encounterId) {
    initPatientForm(newVal);
    getList();
  }
}, { immediate: true, deep: true });

watch(() => props.activeTab, async (val) => {
  if (val === 'examination') {
    getList();
    // 切换到检查页签时，重新获取临床诊断（确保与诊断页签同步）
    if (props.patientInfo?.encounterId) {
      await loadClinicalDiag();
    }
  }
});

function initPatientForm(patient) {
  form.patientName = patient.patientName || '';
  // 就诊卡号应取值于 identifierNo，而非 busNo（busNo 是病历号）
  form.medicalrecordNumber = patient.identifierNo || patient.visitNo || '';
  form.patientId = patient.patientId || '';
  form.visitNo = patient.visitNo || '';
  form.applyDeptCode = userStore.orgName || patient.organizationName || '';
  form.applyDocCode = userStore.nickName || '';
}

// 加载临床诊断：获取患者主诊断并填充到临床诊断字段
async function loadClinicalDiag() {
  if (!props.patientInfo?.encounterId) return;
  try {
    const res = await getEncounterDiagnosis(props.patientInfo.encounterId);
    const diagnoses = res.data || res.rows || res;
    if (Array.isArray(diagnoses) && diagnoses.length > 0) {
      // Bug #380, #381 修复: 主诊断字段名为 maindiseFlag (后端 DiagnosisQueryDto 定义)
      const mainDiag = diagnoses.find(d => d.maindiseFlag === 1 || d.maindiseFlag === '1');
      // 如果有主诊断使用主诊断，否则使用第一个诊断
      const targetDiag = mainDiag || diagnoses[0];
      // 优先使用 diagnosisName，其次是 conditionName 或 name
      form.clinicalDiag = targetDiag.diagnosisName || targetDiag.conditionName || targetDiag.name || '';
    } else {
      // 如果没有诊断，清空临床诊断字段
      form.clinicalDiag = '';
    }
  } catch (err) {
    console.error('加载临床诊断失败', err);
    // 获取失败时不阻断用户操作，保持字段为空
  }
}

// ====== 申请单 CRUD ======
function getList() {
  loading.value = true;
  request({
    url: '/exam/apply/list',
    method: 'get',
    // 默认只展示本次就诊（encounterId）产生的检查申请单
    params: { encounterId: props.patientInfo?.encounterId || '' }
  }).then(res => {
    applicationList.value = res.rows || res.data || [];
  }).catch(err => console.error('获取申请单列表失败', err))
    .finally(() => { loading.value = false; });
}

function handleAdd() {
  formRef.value?.resetFields();
  Object.assign(form, {
    applyNo: '',
    patientId: props.patientInfo?.patientId || '',
    visitNo: props.patientInfo?.visitNo || '',
    // 保留患者姓名和就诊卡号，不应重置为空
    patientName: props.patientInfo?.patientName || '',
    medicalrecordNumber: props.patientInfo?.identifierNo || '',
    applyDeptCode: userStore.orgName || '',
    performDeptCode: '',
    applyDocCode: userStore.nickName || '',
    applyTime: new Date().toISOString().split('T')[0] + ' 12:00:00',
    natureofCost: '自费医疗',
    clinicDesc: '', contraindication: '', medicalHistorySummary: '',
    purposeofInspection: '', inspectionArea: '', inspectionMethod: '',
    applyRemark: '', clinicalDiag: '', purposeDesc: '',
    isUrgent: 0, pregnancyState: 0, allergyDesc: '',
    applyStatus: 0, isCharged: 0, isRefunded: 0, isExecuted: 0,
    examTypeCode: '',
    selectedMethodDisplay: ''  // Bug #384修复: 重置检查方法显示
  });
  selectedItems.value = [];
  resetCategoryChecked();
  activeDetailTab.value = 'applyForm';
  // 自动加载临床诊断
  loadClinicalDiag();
}

function handleSave() {
  formRef.value.validate(valid => {
    if (!valid) return;
    if (selectedItems.value.length === 0) {
      ElMessage.warning('请至少选择一个检查明细项目');
      return;
    }
    // 从已选项目推导检查类型编码（取第一个项目的 checkType，如 CT / ECG / GI）
    const firstCheckType = selectedItems.value[0]?.checkType || 'unknown';
    form.examTypeCode = firstCheckType;


    const payload = {
      ...form,
      encounterId: props.patientInfo?.encounterId || null,
      patientIdNum: props.patientInfo?.patientId || null,
      items: selectedItems.value.map((item, index) => ({
        itemCode: String(item.id),
        itemName: item.name,
        bodyPartCode: item.checkType || 'unknown',
        // Bug #384修复: 如果选中了检查方法且有套餐价格，使用套餐价格；否则使用部位价格
        itemFee: item.selectedMethod?.packagePrice || item.price,
        performDeptCode: form.performDeptCode || '',
        itemStatus: 0,
        itemSeq: index + 1,
        // 检查方法信息
        checkMethodId: item.selectedMethod?.id || null,
        checkMethodName: item.selectedMethod?.name || null,
        checkMethodCode: item.selectedMethod?.code || null,
        checkMethodPackageName: item.selectedMethod?.packageName || null  // Bug #384修复: 保存套餐名称
      }))
    };
    request({
      url: '/exam/apply',
      method: payload.applyNo ? 'put' : 'post',
      data: payload
    }).then(res => {
      ElMessage.success('保存成功');
      getList();
      if (res.data) form.applyNo = res.data;
      // 通知父组件刷新医嘱列表
      emit('saved');
    });
  });
}

function handleRowClick(row) {
  Object.assign(form, row);
  form.selectedMethodDisplay = '';  // Bug #384修复: 先清空，后面根据回充数据更新
  selectedItems.value = [];
  activeDetailTab.value = 'applyForm';
  request({ url: `/exam/apply/${row.applyNo}`, method: 'get' }).then(async res => {
    const d = res.data || res;
    if (d.data) Object.assign(form, d.data);
    if (d.items && Array.isArray(d.items)) {
      try {
        // 为每个项目加载检查方法
        const itemsWithMethods = await Promise.all(d.items.map(async m => {
          const item = {
            id: m.itemCode, name: m.itemName,
            price: m.itemFee || 0, quantity: 1,
            serviceFee: 0, unit: '次',
            applyPart: m.itemName,
            checkType: m.bodyPartCode || '',
            nationalCode: '', checked: true,
            methods: [],
            selectedMethod: null,
            expanded: false  // Bug #384修复: 添加展开状态
          };
          // 加载该项目的检查方法
          if (m.bodyPartCode) {
            try {
              const methodRes = await searchCheckMethod({ checkType: m.bodyPartCode });
              // Bug #384修复: 正确解析 API 返回结构
              let methodData = methodRes?.data?.data || methodRes?.data || methodRes?.rows || methodRes;
              if (!Array.isArray(methodData) && methodRes?.data && Array.isArray(methodRes.data.data)) {
                methodData = methodRes.data.data;
              }
              if (Array.isArray(methodData)) {
                item.methods = methodData.map(md => ({
                  id: md.id,
                  name: md.name,
                  code: md.code,
                  price: m.itemFee || 0,  // fallback 到已保存的价格
                  packageName: md.packageName || '',
                  packagePrice: md.packagePrice || null,  // Bug #384修复: 套餐价格
                  serviceFee: md.serviceFee || null
                }));
                // 如果有已保存的检查方法信息，尝试匹配
                if (m.checkMethodId) {
                  item.selectedMethod = item.methods.find(md => md.id === m.checkMethodId) || null;
                }
              }
            } catch (err) {
              console.error('加载检查方法失败', err);
              // 单个项目加载失败不影响其他项目，继续返回 item
            }
          }
          return item;
        }));
        selectedItems.value = itemsWithMethods;
        syncCategoryChecked();
        // Bug #384修复: 回充后更新检查方法显示
        updateMethodDisplay();
        // 修复【#408】：加载申请单详情后自动切换到检查明细页签，确保已加载的明细数据可见
        activeDetailTab.value = 'applyDetail';
      } catch (err) {
        console.error('加载申请单详情失败', err);
        ElMessage.error('加载申请单详情失败');
      }
    }
  }).catch(err => {
    console.error('获取申请单详情失败', err);
    ElMessage.error('获取申请单详情失败');
  });
}

function handlePrint(row) { ElMessage.info('打印申请单：' + row.applyNo); }

function handleDelete(row) {
  ElMessageBox.confirm('确认删除该检查申请单吗？', '警告', { type: 'warning' }).then(() => {
    request({ url: `/exam/apply/${row.applyNo}`, method: 'delete' }).then(() => {
      ElMessage.success('删除成功');
      getList();
      if (form.applyNo === row.applyNo) handleAdd();
    });
  });
}

// ====== 勾选逻辑 ======
async function handleItemSelect(checked, item, cat) {
  if (checked) {
    // Bug #384修复: 检查方法表的 checkType 字段关联的是检查类型的 name（中文名称，如"心电图")
    const effectiveCheckType = cat?.typeName || cat?.categoryName || '';

    // 查询该检查类型对应的检查方法
    let methods = [];
    try {
      if (effectiveCheckType) {
        const res = await searchCheckMethod({ checkType: effectiveCheckType });
        // Bug #384修复: API 返回结构可能是 {data: {data: Array}} 或 {data: Array}
        let data = res?.data?.data || res?.data || res?.rows || res;
        if (!Array.isArray(data) && res?.data && Array.isArray(res.data.data)) {
          data = res.data.data;
        }
        if (Array.isArray(data)) {
          methods = data.map(m => ({
            id: m.id,
            name: m.name,
            code: m.code,
            price: m.price || item.price,  // fallback 到项目价格
            packageName: m.packageName || '',
            packagePrice: m.packagePrice || null,  // Bug #384修复: 套餐价格
            serviceFee: m.serviceFee || null      // Bug #384修复: 服务费
          }));
        }
      }
    } catch (err) {
      console.error('加载检查方法失败', err);
    }

    if (selectedItems.value.length > 0) {
      const currentCategory = selectedItems.value[0].checkType;
      const newCategory = cat.typeCode || '';
      if (currentCategory !== newCategory) {
        ElMessage.warning('一个检查单不能同时选择多个项目类型的检查项目');
        item.checked = false;
        return;
      }
    }

    selectedItems.value.push({
      id: item.id, name: item.name,
      price: item.price, quantity: 1,
      serviceFee: item.serviceFee || 0,
      unit: item.unit || '次',
      applyPart: item.name,
      checkType: effectiveCheckType,  // Bug #384修复: 使用有效的 checkType
      nationalCode: item.nationalCode || '',
      checked: true,
      methods: methods,
      selectedMethod: null,
      expanded: false  // Bug #384修复: 新增展开状态，默认不展开
    });

    // 自动回填执行科室：按检查项目类型 → 检查类型管理里配置的执行科室
    if (selectedItems.value.length === 1 && cat?.performDeptName) {
      form.performDeptCode = cat.performDeptName;
    } else if (!form.performDeptCode && cat?.performDeptName) {
      form.performDeptCode = cat.performDeptName;
    }

    // 如果有且仅有一个检查方法，自动选中并更新显示
    if (methods.length === 1) {
      const lastIdx = selectedItems.value.length - 1;
      selectedItems.value[lastIdx].selectedMethod = methods[0];
      updateMethodDisplay();  // Bug #384修复: 联动更新显示
    }
  } else {
    const idx = selectedItems.value.findIndex(s => s.id === item.id);
    if (idx > -1) selectedItems.value.splice(idx, 1);
    
    if (selectedItems.value.length === 0) {
      form.performDeptCode = '';
      form.examTypeCode = '';
    }
  }
  // Bug #382 修复：移除自动切换页签逻辑，保持当前页签状态
}

// Bug #384修复: 展开/收起项目卡片
async function toggleItemExpand(item) {
  item.expanded = !item.expanded;
  // 如果是展开且该项目是套餐，加载套餐明细
  if (item.expanded && item.isPackage && (!item.packageDetails || item.packageDetails.length === 0)) {
    await loadPackageDetailsForItem(item);
  }
}

// Bug #384修复: 勾选框选择检查方法（单选逻辑）
function selectMethodCheckbox(checked, item, method) {
  if (checked) {
    item.selectedMethod = method;
  } else {
    item.selectedMethod = null;
  }
  // 联动更新表单检查方法显示字段
  updateMethodDisplay();
  
  // #430: 套餐金额实时同步到申请单
  nextTick(() => {
    form.totalAmount = totalAmountCalc.value;
  });
}

// Bug #384修复: 更新检查方法显示字段（联动）
function updateMethodDisplay() {
  // 找到第一个有选中检查方法的项目
  const itemWithMethod = selectedItems.value.find(item => item.selectedMethod);
  if (itemWithMethod?.selectedMethod) {
    form.selectedMethodDisplay = itemWithMethod.selectedMethod.name;  // 显示检查方法名称，不显示套餐名称
  } else {
    form.selectedMethodDisplay = '';
  }
}

// 选择检查方法
function selectMethod(item, method) {
  if (item.selectedMethod?.id === method.id) {
    item.selectedMethod = null;
  } else {
    item.selectedMethod = method;
  }
  // Bug #384修复: 联动更新表单检查方法显示字段
  updateMethodDisplay();
}

function handleRemoveItem(idx, item) {
  selectedItems.value.splice(idx, 1);
  // 取消对应 category 中的 checkbox
  for (const cat of categoryList.value) {
    const found = cat.items.find(x => x.id === item.id);
    if (found) { found.checked = false; break; }
  }

  if (selectedItems.value.length === 0) {
    form.performDeptCode = '';
    form.examTypeCode = '';
    form.selectedMethodDisplay = '';  // Bug #384修复: 清空检查方法显示
  } else {
    // Bug #384修复: 移除后重新计算检查方法显示
    updateMethodDisplay();
  }
}

function resetCategoryChecked() {
  for (const cat of categoryList.value)
    for (const item of cat.items) item.checked = false;
}

function syncCategoryChecked() {
  resetCategoryChecked();
  const ids = new Set(selectedItems.value.map(s => s.id));
  for (const cat of categoryList.value)
    for (const item of cat.items)
      if (ids.has(item.id)) item.checked = true;
}

defineExpose({ getList });
</script>

<style scoped>
.exam-app-container {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 8px;
  height: 100%;
  background: #f0f2f5;
}

/* 顶部申请单列表 */
.top-section {
  background: #fff;
  border-radius: 4px;
  padding: 10px 12px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
}
.section-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}
.section-title {
  font-size: 14px;
  font-weight: 600;
  color: #303133;
}
.header-actions {
  display: flex;
  gap: 8px;
}

/* 底部区域：左表单 + 右分类 */
.bottom-section {
  display: flex;
  gap: 10px;
  flex: 1;
  min-height: 0;
}

/* 左：表单面板 */
.form-panel {
  flex: 1;
  background: #fff;
  border-radius: 4px;
  padding: 10px 12px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
  overflow-y: auto;
  min-width: 0;
}
.form-tabs :deep(.el-tabs__header) {
  margin-bottom: 10px;
}
.apply-form :deep(.el-form-item) {
  margin-bottom: 10px;
}
.apply-form :deep(.el-form-item__label) {
  font-size: 12px;
}
.total-row {
  margin-top: 8px;
  text-align: right;
  font-size: 13px;
  color: #606266;
}
.total-amount {
  font-size: 15px;
  font-weight: bold;
  color: #f56c6c;
  margin-left: 4px;
}

/* 右：分类面板 */
.category-panel {
  width: 380px;
  flex-shrink: 0;
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.06);
  padding: 10px 12px;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.panel-top {
  display: flex;
  gap: 12px;
  flex: 1;
  min-height: 0;
}
.category-left {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.panel-label {
  font-size: 13px;
  font-weight: 600;
  color: #303133;
  margin-bottom: 6px;
}
.search-input {
  margin-bottom: 8px;
}
.collapse-scroll {
  flex: 1;
  overflow-y: auto;
}
.empty-hint {
  color: #909399;
  font-size: 12px;
  text-align: center;
  padding: 20px 0;
}

/* 检查项目分类折叠 */
.cat-title {
  font-size: 13px;
  font-weight: 500;
  color: #303133;
}
.item-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 3px 4px;
}
.item-row:hover {
  background: #f5f7fa;
}
.item-checkbox {
  flex: 1;
  overflow: hidden;
}
.item-checkbox :deep(.el-checkbox__label) {
  font-size: 12px;
  color: #303133;
}
.item-price {
  font-size: 12px;
  color: #1890FF;
  flex-shrink: 0;
  margin-left: 6px;
}

/* 已选择 tags */
.selected-panel {
  width: 140px;  /* Bug #384修复: 加宽以适应展开内容 */
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
}
.selected-tags {
  flex: 1;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.selected-tag {
  max-width: 100%;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.empty-selected {
  color: #c0c4cc;
  font-size: 12px;
}

/* Bug #384修复: 已选择项目卡片（可展开） */
.selected-item-card {
  display: flex;
  flex-direction: column;
  background: #F5F5F5;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}

.selected-item-card .card-header {
  display: flex;
  align-items: center;
  padding: 8px 10px;
  cursor: pointer;
  gap: 4px;
}

.selected-item-card .card-header:hover {
  background: #E6F7FF;
}

.card-name {
  flex: 1;
  font-size: 12px;
  color: #303133;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.card-price {
  font-size: 12px;
  color: #1890FF;
  font-weight: 500;
}

.expand-icon {
  font-size: 12px;
  color: #909399;
  transition: transform 0.2s;
}

.expand-icon.expanded {
  transform: rotate(180deg);
}

/* Bug #384修复: 检查方法勾选框列表 */
.method-list {
  padding: 6px 10px;
  background: #fff;
  border-top: 1px solid #e4e7ed;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.method-option {
  display: flex;
  align-items: center;
}

.method-option :deep(.el-checkbox__label) {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
}

.method-option .method-name {
  font-size: 11px;
  color: #606266;
}

.method-option .method-price {
  font-size: 11px;
  color: #e6a23c;
  font-weight: 500;
  margin-left: 8px;
}

/* 折叠组件细节 */
:deep(.el-collapse) {
  border: none;
}
:deep(.el-collapse-item__header) {
  font-size: 13px;
  padding: 6px 0;
  height: auto;
  line-height: 1.5;
}
:deep(.el-collapse-item__content) {
  padding-bottom: 4px;
}
:deep(.el-collapse-item__wrap) {
  border: none;
}
</style>
