import { type ClinicalSignal, diagnosisCodeNameZh, treatmentCategoryNameZh } from '@pac/types';
import type { AdaptedFact } from './adapt-data';

/**
 * 一条 fact 的紧凑展示形态:徽标 + 一行文本。
 *
 * 原本只长在 tooth-timeline.tsx 里、只覆盖临床四类(诊断/治疗/建议/影像);
 * 画像「依据」区要展示任意类型的证据 fact(结算、预约、就诊、病历都会出现),
 * 落到 default 分支会直接把 `payment_record` 这种表名甩给客服。故抽出来共用并补齐常见类型。
 */
export interface FactLabel {
  badge: string;
  badgeTone: string;
  text: string;
  /** 悬停补充(医生原话全文等);缺省时调用方用 text 兜底 */
  hover?: string;
}

const MODALITY_ZH: Record<string, string> = {
  pa: '根尖片',
  bw: '咬翼片',
  pano: '曲面断层',
  cbct: 'CBCT',
  intraoral_photo: '口内照片',
};

const yuan = (cents: unknown): string => {
  const n = Number(cents ?? 0);
  return Number.isFinite(n) ? `¥${Math.round(n / 100).toLocaleString('zh-CN')}` : '';
};

export function factLabel(f: AdaptedFact): FactLabel {
  const c = (f.content ?? {}) as Record<string, unknown>;
  switch (f.type) {
    case 'diagnosis_record': {
      const code = String(c.code ?? '');
      const name = String(c.name_zh ?? c.name ?? '');
      const std = code ? diagnosisCodeNameZh(code) : '';
      const text = std && name && std !== name ? `${std} · ${name}` : std || name || '诊断';
      return { badge: '诊断', badgeTone: 'bg-rose-50 text-rose-700', text };
    }
    case 'treatment_record': {
      const cat = String(c.category ?? '');
      const sub = String(c.subtype ?? '');
      const catZh = cat ? treatmentCategoryNameZh(cat) : '';
      const text = sub || catZh || '治疗';
      const isPlanned = f.kind === 'planned';
      return {
        badge: isPlanned ? '计划' : catZh || '治疗',
        badgeTone: isPlanned ? 'bg-slate-100 text-slate-500' : 'bg-brand-50 text-brand-700',
        text,
      };
    }
    case 'recommendation_record': {
      const name = String(c.name ?? '');
      const code = String(c.code ?? '');
      return {
        badge: '建议',
        badgeTone: 'bg-amber-50 text-amber-700',
        text: name || (code ? diagnosisCodeNameZh(code) : '') || '医生建议',
      };
    }
    case 'image_record': {
      const mod = String(c.modality ?? '');
      return {
        badge: '影像',
        badgeTone: 'bg-slate-100 text-slate-500',
        text: MODALITY_ZH[mod] ?? mod ?? '影像',
      };
    }
    // ── 以下为画像证据链补齐(临床时间轴用不到,但画像标签大量引用)──
    case 'payment_record': {
      // 折扣锚点 / 权益身份的证据:金额 + 卡券或项目名才说明得了问题
      const project = String(c.settlement_project ?? '').trim();
      const card = String(c.card_name ?? c.card_type_name ?? c.insurance_name ?? '').trim();
      const parts = [yuan(c.amount_cents), card, project].filter(Boolean);
      return { badge: '结算', badgeTone: 'bg-indigo-50 text-indigo-700', text: parts.join(' · ') || '结算' };
    }
    case 'recharge_record':
      return { badge: '充值', badgeTone: 'bg-indigo-50 text-indigo-700', text: yuan(c.amount_cents) || '充值' };
    case 'refund_record':
      return { badge: '退费', badgeTone: 'bg-rose-50 text-rose-700', text: yuan(c.amount_cents) || '退费' };
    case 'appointment_record': {
      // 特别关注(爽约/迟到)的证据:履约状态才是重点
      const st = String(c.status ?? f.status ?? '');
      const ST_ZH: Record<string, string> = {
        no_show: '爽约',
        cancelled: '已取消',
        completed: '已到诊',
        arrived: '已到诊',
        booked: '已预约',
      };
      return { badge: '预约', badgeTone: 'bg-sky-50 text-sky-700', text: ST_ZH[st] ?? st ?? '预约' };
    }
    // ⚠️ 下面三类的 f.title 都是 `<中文> <externalId>`(接诊 16432552 / 挂号 xxx / 前台接待 xxx)——
    //    直接显示等于把宿主内部 ID 甩给客服。一律改取 content 里有语义的字段,取不到就只留中文词。
    case 'encounter_record': {
      const tone = { badge: '就诊', badgeTone: 'bg-brand-50 text-brand-700' };
      const cc = String(c.chief_complaint ?? '').trim() || String(f.summary ?? '').trim();
      const doc = String(c.doctor_name ?? '').trim();
      if (cc) return { ...tone, text: cc, hover: doc ? `${cc}(${doc}医生)` : cc };
      return { ...tone, text: doc ? `${doc}医生接诊` : '到诊' };
    }
    case 'visit_registration_record': {
      const doc = String(c.doctor_name ?? '').trim();
      const dept = String(c.department ?? c.department_name ?? '').trim();
      const text = [dept, doc ? `${doc}医生` : ''].filter(Boolean).join(' · ') || '挂号';
      return { badge: '挂号', badgeTone: 'bg-brand-50 text-brand-700', text };
    }
    case 'visit_reception_record':
      return { badge: '接待', badgeTone: 'bg-brand-50 text-brand-700', text: '前台接待' };
    case 'emr_record': {
      const tone = { badge: '病历', badgeTone: 'bg-slate-100 text-slate-600' };
      // ⚠️ **不能用 f.summary** —— emr parser 写进去的是 `关联接诊:<encounter_id>`(内部 ID),
      //    客服在画像「依据」里看到「关联接诊:15514」完全无从理解。
      //    (旧注释说"summary 是命中的那段",与 emr.parser.ts 实际写入不符,是错的。)

      // ① 优先:摄入时抽出的临床信号 —— 这条病历到底"命中了什么"
      const sigs = Array.isArray(c.clinical_signals) ? (c.clinical_signals as ClinicalSignal[]) : [];
      const positive = sigs.filter((s) => s?.negated === false);
      if (positive.length > 0) {
        return {
          ...tone,
          text: [...new Set(positive.map((s) => s.label))].join('、'),
          // 悬停给医生原话 —— 标签是 PAC 的归纳,原话才是事实本身
          hover: [...new Set(positive.map((s) => s.phrase).filter(Boolean))].join('\n'),
        };
      }

      // ② 退一步:病历里真正有内容的那段(SOAP 按信息量排序),而不是内部 ID
      const snippet = [c.past_history, c.illness_desc, c.general_condition, c.doctor_advice]
        .map((x) => String(x ?? '').trim())
        .find((x) => x.length > 0);
      if (snippet) return { ...tone, text: snippet.slice(0, 40), hover: snippet };

      return { ...tone, text: f.title ?? '病历' };
    }
    case 'consultation_record':
      return { badge: '咨询', badgeTone: 'bg-amber-50 text-amber-700', text: f.title ?? '咨询' };
    default:
      return { badge: '事实', badgeTone: 'bg-slate-100 text-slate-500', text: f.title ?? f.type };
  }
}
