/**
 * fact-block —— 厚输入事实块(标准 / 深度档共用的 user-prompt 素材)。
 *
 * 把"聚焦病历 + 其他 reason + 近期治疗 + 目标 + 称呼/医生/日期"拼成自然语言事实块。
 * 各档的**输出指令**(去模板自由写 / 拆大纲 / 多段)在各自 system(format.md)里,user 只给事实。
 * 病种**只给 canonical 名**(去文案模板),风险/好处/检查内容由 LLM 结合病历自供措辞。
 */
import type { DraftPlanScriptInput, ScriptMedicalRecord } from './input.types';
import { smartDateDisplay, toothFriendly } from './script-facts';
import { resolveDiseaseLabel } from './disease-knowledge';
import { deidentifyDoctor } from './pii';

export function buildRichFactBlock(input: DraftPlanScriptInput): string {
  const { patient, clinicName, plan, clinicalContext } = input;
  const now = new Date();

  const top = plan.reasons[0];
  const salutation = patient.salutation;
  const doctorSurname = deidentifyDoctor(top?.triggerDoctor ?? clinicalContext.primaryDoctorName ?? null);
  // ⭐ 开场"自从…来过之后"锚【最近一次就诊】(可能晚于诊断日);诊断日更早,归病历/告知用,不放开场
  const lastVisitDate =
    clinicalContext.daysSinceLastVisit != null
      ? new Date(now.getTime() - clinicalContext.daysSinceLastVisit * 86400_000)
      : null;
  const lastVisitDisplay =
    smartDateDisplay(lastVisitDate, now) ??
    (top?.triggerDate ? smartDateDisplay(new Date(top.triggerDate), now) : null) ??
    '上次';
  const chiefComplaint = top?.medicalRecord?.chiefComplaint ?? clinicalContext.lastChiefComplaint ?? null;

  const diseaseLabel = resolveDiseaseLabel(top ?? null, plan.primaryScenarioLabel);
  const toothText = top?.toothPositions?.length ? toothFriendly(top.toothPositions) : null;
  const goal = plan.goal?.trim() || null;

  const selfIntro = input.agent?.name
    ? `我是${clinicName}的${input.agent.roleTitle}${input.agent.name}`
    : `我是${clinicName}的客服`;
  const guardianHint = patient.guardian
    ? `本次电话打给${patient.guardian.relationshipLabel}(称呼见{智能称呼}),沟通对象是家长,患者是孩子,话术里称孩子为"宝宝"`
    : null;

  const mrBlock = renderMedicalRecord(top?.medicalRecord ?? null);

  const others = plan.reasons.slice(1).map((r) => {
    const t = r.toothPositions?.length ? `(${toothFriendly(r.toothPositions)})` : '';
    return `${resolveDiseaseLabel(r, r.scenarioLabel)}${t}`;
  });

  // 历史治疗:给结构化要素(类目/术式/医生/时间),口语化交给 LLM —— 别照搬这串,自然带一句即可
  const recent = clinicalContext.recentTreatments.map((t) =>
    [t.date, t.categoryLabel, t.subtype, t.doctorName ? `${t.doctorName}医生` : '']
      .filter(Boolean)
      .join(' / '),
  );

  const g = (patient.gender ?? '').trim().toUpperCase();
  const genderText = g === '男' || g === 'M' ? '男' : g === '女' || g === 'F' ? '女' : '';
  const basics = [genderText, patient.age != null ? `${patient.age}岁` : ''].filter(Boolean).join('，');
  // 熟络度信号(给原始事实,不贴"新/老"二分 —— 召回患者基本都有历史,二分会全判"老客"):
  //   完成治疗次数(关系深浅,辅)+ 距上次就诊天数(还熟不熟,主)。tone 交 LLM 按 recency 判断。
  const relationSignal = `已完成 ${clinicalContext.completedTreatmentCount} 次治疗;距上次就诊 ${
    clinicalContext.daysSinceLastVisit ?? '未知'
  } 天`;
  const noXray = patient.age == null || patient.age <= 18;

  return `# 本次回访患者信息(只能用以下事实,不要编造或推断额外信息)

## 开场用
- {智能称呼}:${salutation}
- {自报家门}:${selfIntro}
- {智能时间显示}(最近一次就诊,用于开场"自从…来过";诊断日见病历/可能更早):${lastVisitDisplay}
- 那次主诉:${chiefComplaint ?? '无记录'}
- {诊断医生}:${doctorSurname}医生${guardianHint ? `\n- 触达说明:${guardianHint}` : ''}

## 本次应治未治(只讲这一个;病种只给名,风险/好处/检查内容你结合下方病历用自己的话说)
- {应治未治项}:${diseaseLabel}${toothText ? `\n- {牙位}:${toothText}(已是患者口语俗称,直接用)` : ''}

## 病历(诊断上下文 — 接地素材,可引用医生原话体现关怀;⚠️ 只引用、不演绎、不报价、不承诺;与本次无关的别提)
${mrBlock || '- (本次诊断无关联病历,按 {应治未治项} + 牙科常识温和提醒)'}

## 本次目标(内部参考 — 指导复查/邀约方向,不要逐字念给患者)
- ${goal ?? '邀约来院复查,让医生评估本次问题'}
${others.length ? `\n## 其他可一并关心的问题(以本次聚焦为主,自然可顺带;不展开)\n- ${others.join('、')}` : ''}${
    recent.length ? `\n\n## 近期做过的治疗(下面是结构化要素,**用你自己的话自然带一句**体现"诊所记得 ta",别照搬格式;不要重复邀约已做过的)\n${recent.map((r) => `- ${r}`).join('\n')}` : ''
  }

## 患者
- ${basics}
- 熟络度:${relationSignal}
  → tone 你判断:最近来过+有历史→可熟络 warm;很久没来(沉睡,如距上次 >1 年)→ 有历史也别太自来熟、先重新拉近;关系浅→ professional;急性/疼痛→ urgent。${noXray ? '\n\n## 安全(硬约束)\n- 本患者未满 18 岁或年龄未知:**整篇严禁出现"拍片/拍个片/X光/牙片"等任何拍片表述**' : ''}`;
}

/** 聚焦病历 → 接地素材块(SOAP 关键字段;空字段略) */
export function renderMedicalRecord(mr: ScriptMedicalRecord | null): string {
  if (!mr) return '';
  const lines: string[] = [];
  if (mr.date) lines.push(`- 接诊日期:${mr.date}`);
  if (mr.presentIllness) lines.push(`- 现病史:${mr.presentIllness}`);
  if (mr.pastHistory) lines.push(`- 既往史:${mr.pastHistory}`);
  if (mr.examFindings.length) {
    lines.push(
      `- 检查所见:${mr.examFindings
        .map((e) => (e.toothPosition ? `${toothFriendly(e.toothPosition)} ${e.message}` : e.message))
        .join(';')}`,
    );
  }
  if (mr.diagnoses.length) {
    lines.push(
      `- 当次诊断:${mr.diagnoses
        .map((d) => `${d.nameZh ?? d.code ?? ''}${d.toothPosition ? `(${toothFriendly(d.toothPosition)})` : ''}`)
        .filter(Boolean)
        .join('、')}`,
    );
  }
  if (mr.doctorAdvice) lines.push(`- 医嘱(原话):${mr.doctorAdvice}`);
  if (mr.recommendations.length) {
    lines.push(
      `- 医生建议:${mr.recommendations
        .map((r) => (r.toothPosition ? `${r.text}(${toothFriendly(r.toothPosition)})` : r.text))
        .join(';')}`,
    );
  }
  if (mr.treatmentPlanText) lines.push(`- 治疗计划:${mr.treatmentPlanText}`);
  return lines.join('\n');
}
