<script lang="ts" setup>
/**
 * 患者历史病历抽屉
 * - view：只读查看
 * - cite：选择一条后点「引用此病历」回填到当前接诊病历
 * 右侧预览用 Descriptions 双列，跳过空字段
 */
import { computed, ref } from 'vue';

import { useVbenDrawer } from '@vben/common-ui';
import { Descriptions, Empty, Spin, Tag, message } from 'ant-design-vue';

import { getMedicalRecordListByPatient } from '../api';
import { MEDICAL_RECORD_VIEW_FIELDS } from '../config/constants';

defineOptions({ name: 'PatientMedicalRecordDrawer' });

type DrawerData = {
  userPatientId?: number;
  storeId?: number;
  patientName?: string;
  mode?: 'view' | 'cite';
  excludeRegisterId?: number;
  onCite?: (record: Record<string, any>) => void;
};

/** Descriptions 通栏字段 */
const FULL_SPAN_KEYS = new Set([
  'chief_complaint',
  'present_illness',
  'tcm_case',
  'treatment_advice',
  'doctor_order',
  'auxiliary_exam',
  'physical_exam',
]);

const loading = ref(false);
const list = ref<Record<string, any>[]>([]);
const activeId = ref(0);
const meta = ref<DrawerData>({});

const isCiteMode = computed(() => meta.value.mode === 'cite');

const activeRecord = computed(() => {
  return list.value.find((r) => Number(r.id) === activeId.value) || null;
});

function vitalsText(row: Record<string, any>) {
  const parts: string[] = [];
  if (row.temperature) parts.push(`体温 ${row.temperature}℃`);
  if (row.height) parts.push(`身高 ${row.height}cm`);
  if (row.weight) parts.push(`体重 ${row.weight}KG`);
  if (row.respiratory_rate) parts.push(`呼吸 ${row.respiratory_rate}次/分`);
  if (row.bp_systolic || row.bp_diastolic) {
    parts.push(`血压 ${row.bp_systolic || '-'}/${row.bp_diastolic || '-'}mmHg`);
  }
  return parts.join('；') || '';
}

function fieldDisplay(row: Record<string, any>, key: string) {
  if (key === 'physical_exam') {
    const body = String(row.physical_exam || '').trim();
    const vitals = vitalsText(row);
    if (body && vitals) return `${vitals}\n${body}`;
    return body || vitals || '';
  }
  const v = row[key];
  if (v === null || v === undefined || v === '' || v === 0) return '';
  return String(v).trim();
}

/** 仅有内容的字段，供 Descriptions 渲染 */
const filledViewFields = computed(() => {
  const row = activeRecord.value;
  if (!row) return [];
  return MEDICAL_RECORD_VIEW_FIELDS.map((f) => ({
    label: f.label,
    value: f.value,
    text: fieldDisplay(row, f.value),
    span: FULL_SPAN_KEYS.has(f.value) ? 2 : 1,
  })).filter((f) => !!f.text);
});

function listTitle(row: Record<string, any>) {
  const dx = String(row.diagnosis || '').trim();
  if (dx) return dx.length > 28 ? `${dx.slice(0, 28)}…` : dx;
  return `挂号 #${row.register_id || '-'}`;
}

function isCurrentRegister(row: Record<string, any>) {
  const exclude = Number(meta.value.excludeRegisterId || 0);
  return exclude > 0 && Number(row.register_id) === exclude;
}

function pickDefaultActiveId(rows: Record<string, any>[]) {
  if (!rows.length) return 0;
  const exclude = Number(meta.value.excludeRegisterId || 0);
  if (exclude > 0) {
    const other = rows.find((r) => Number(r.register_id) !== exclude);
    if (other) return Number(other.id);
  }
  return Number(rows[0].id);
}

async function loadList() {
  const uid = Number(meta.value.userPatientId || 0);
  if (!uid) {
    list.value = [];
    activeId.value = 0;
    return;
  }
  loading.value = true;
  try {
    const res = await getMedicalRecordListByPatient({
      user_patient_id: uid,
      store_id: meta.value.storeId || undefined,
      limit: 50,
    });
    list.value = Array.isArray(res) ? res : res?.items || res?.list || [];
    activeId.value = pickDefaultActiveId(list.value);
  } catch (e: any) {
    list.value = [];
    activeId.value = 0;
    message.error(e?.message || '加载病历失败');
  } finally {
    loading.value = false;
  }
}

const [Drawer, drawerApi] = useVbenDrawer({
  class: 'w-[900px]',
  title: '查看患者病历',
  cancelText: '关闭',
  confirmText: '引用此病历',
  showConfirmButton: false,
  onConfirm() {
    if (!isCiteMode.value) {
      drawerApi.close();
      return;
    }
    const row = activeRecord.value;
    if (!row) {
      message.warning('请先选择要引用的病历');
      return;
    }
    meta.value.onCite?.(row);
    drawerApi.close();
  },
  onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      list.value = [];
      activeId.value = 0;
      meta.value = {};
      return;
    }
    const data = drawerApi.getData<DrawerData>() || {};
    meta.value = data;
    const cite = data.mode === 'cite';
    const name = data.patientName ? ` - ${data.patientName}` : '';
    drawerApi.setState({
      title: cite ? `引用历史病历${name}` : `查看患者病历${name}`,
      showConfirmButton: cite,
      confirmText: '引用此病历',
      cancelText: cite ? '取消' : '关闭',
    });
    loadList();
  },
});
</script>
<template>
  <Drawer>
    <Spin :spinning="loading">
      <div v-if="list.length === 0 && !loading" class="py-10">
        <Empty description="暂无病历记录" />
      </div>
      <div v-else class="mr-view-layout">
        <div class="mr-view-list">
          <div
            v-for="row in list"
            :key="row.id"
            class="mr-view-item"
            :class="{ 'is-active': Number(row.id) === activeId }"
            @click="activeId = Number(row.id)"
          >
            <div class="mr-view-item__title">{{ listTitle(row) }}</div>
            <div class="mr-view-item__meta">
              <Tag>挂号 {{ row.register_id || '-' }}</Tag>
              <Tag v-if="isCurrentRegister(row)" color="blue">本次</Tag>
              <span>{{ row.created_at || row.updated_at || '' }}</span>
            </div>
          </div>
        </div>
        <div class="mr-view-detail">
          <template v-if="activeRecord">
            <Descriptions
              :column="2"
              bordered
              size="small"
              class="mb-3 mr-view-meta-desc"
            >
              <Descriptions.Item label="挂号 ID">
                {{ activeRecord.register_id || '-' }}
              </Descriptions.Item>
              <Descriptions.Item label="创建">
                {{ activeRecord.created_at || '—' }}
              </Descriptions.Item>
              <Descriptions.Item label="更新" :span="2">
                {{ activeRecord.updated_at || '—' }}
              </Descriptions.Item>
            </Descriptions>
            <div
              v-if="isCiteMode && isCurrentRegister(activeRecord)"
              class="mr-view-tip"
            >
              当前选中的是本次挂号病历，引用后会覆盖编辑区内容（仍可继续改）。
            </div>
            <Empty
              v-if="!filledViewFields.length"
              description="该病历暂无填写内容"
              class="py-6"
            />
            <Descriptions
              v-else
              :column="2"
              bordered
              size="small"
              title="病历内容"
              class="mr-view-content-desc"
            >
              <Descriptions.Item
                v-for="f in filledViewFields"
                :key="f.value"
                :label="f.label"
                :span="f.span"
              >
                <div class="mr-view-content-text">{{ f.text }}</div>
              </Descriptions.Item>
            </Descriptions>
          </template>
          <Empty v-else description="请选择左侧病历" />
        </div>
      </div>
    </Spin>
  </Drawer>
</template>
<style scoped>
.mr-view-layout {
  display: grid;
  grid-template-columns: 220px 1fr;
  gap: 12px;
  min-height: 480px;
}
.mr-view-list {
  border-right: 1px solid hsl(var(--border));
  padding-right: 10px;
  max-height: 70vh;
  overflow-y: auto;
}
.mr-view-item {
  padding: 8px 10px;
  border-radius: 8px;
  cursor: pointer;
  border: 1px solid transparent;
  margin-bottom: 6px;
  background: hsl(var(--muted) / 0.35);
  transition: all 0.2s;
}
.mr-view-item:hover {
  border-color: hsl(var(--primary) / 0.35);
}
.mr-view-item.is-active {
  border-color: hsl(var(--primary));
  background: hsl(var(--primary) / 0.08);
}
.mr-view-item__title {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
  word-break: break-all;
}
.mr-view-item__meta {
  margin-top: 4px;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  align-items: center;
  font-size: 11px;
  color: hsl(var(--muted-foreground));
}
.mr-view-detail {
  max-height: 70vh;
  overflow-y: auto;
  padding-right: 2px;
}
.mr-view-tip {
  margin-bottom: 10px;
  padding: 6px 8px;
  font-size: 12px;
  color: #ad6800;
  background: #fff7e6;
  border-radius: 6px;
}
.mr-view-meta-desc :deep(.ant-descriptions-item-label),
.mr-view-content-desc :deep(.ant-descriptions-item-label) {
  width: 88px;
  white-space: nowrap;
}
.mr-view-content-desc :deep(.ant-descriptions-item-content) {
  font-size: 12px;
}
.mr-view-content-text {
  max-height: 88px;
  overflow-y: auto;
  white-space: pre-wrap;
  word-break: break-word;
  line-height: 1.45;
}
</style>
