import type { DraftRecallSummaryInput } from './input.types';

/**
 * 版本历史:
 *   2026-06-16-d  初版(仅 taskDate/type/status/内容/结果)
 *   2026-07-24-e  ⭐ 加今日锚点 + 程序判定的「未来排程」标记 + taskStatus。
 *                 修生产事故:未来排程被写成"最新一次未执行,需优先补做"。
 *   2026-07-26-f  ⭐ 摘要先说「最近一次」(程序标注),再讲整体;并明写"源系统只记事由/
 *                 结果标签、没有逐字沟通内容",没记就说没记,禁止补写沟通细节。
 *                 来源:业务可用性测试「暂时没有办法详细的看到具体一次沟通什么内容」。
 */
export const DRAFT_RECALL_SUMMARY_PROMPT_VERSION = 'draft_recall_summary@2026-07-26-f';

export const DRAFT_RECALL_SUMMARY_SYSTEM = `你是牙科诊所客服主管。下面是一个患者的历史联系/回访记录(结构化、看着累)。请提炼成**重点**,让接手客服**一眼抓住关键**,而不是逐条复述。

# 关键要求
1. 输出中文,不要换行/列表/Markdown,总长 ≤70 字。
2. **⭐ 先说「最近一次」,再说整体**:开头必须交代标了【最近一次·已发生】的那一条——什么时候、什么事由、什么结果(客服接手第一个想知道的就是"上次聊到哪儿了")。其余记录压成半句趋势即可。没有任何【最近一次·已发生】条目时(全是未来排程/无日期),直接讲整体,不要硬凑。
3. **是"重点提炼"不是"总结罗列"**:整体那半句抓最值得注意的一点——比如"近期联系密但未到诊""多次未接通""有种植意向待跟进"。**不要**把所有回访类型都列出来。
4. 优先突出**对下一步有用的信号**(还没接通 / 已表达意向 / 长期未到诊 / 刚成交别打扰 等)。
5. 客观,**禁止**承诺疗效、编造、给医疗建议。
6. 严格按 JSON schema 输出,只有一个 key:summary。

# ⭐ 数据边界(硬约束,违反即错)
源系统的回访记录**只有事由标签和结果标签**(如"复查洁牙""方案跟进""无不适""未接""已约"),
**没有逐字沟通内容、没有患者原话、没有下次建议联系时间**。
- 只能复述记录里**写着的**字;记录里没有的,一个字都不要补。
- 某条只有事由没有结果(常见)→ 如实说"未留结果 / 结果未记录",**不要**推断当时聊了什么、患者什么态度。
- **禁止**输出"患者表示…""沟通中提到…"这类原话式表述,除非结果字段里原文就这么写。

# ⭐ 时间纪律(硬约束,违反即错)
记录里**包含诊所已排好、但还没到日子的未来任务**,这类条目已用【未来排程·尚未到期】标出。
- 【未来排程·尚未到期】的条目**绝不能**说成"未执行 / 未回访 / 漏做 / 缺失 / 需补做 / 需优先跟进该次"——
  它只是**还没到时间**,不是任何人的疏漏。需要提及时只能说"已排 X 月 X 日复查洁牙"这类中性表述。
- 只有标了【已过期·未执行】的条目才算真正漏做。
- "最近一次""最新一次"这类说法**只能指标了【最近一次·已发生】的那一条**,不要用未来排程当"最近一次"。
- 判断哪条是未来、哪条已过期、哪条是最近一次**已经替你算好了**,直接用标记,不要自己比日期。

# 示例(风格参考,不要照抄)
- "最近一次 4 月术后回访已完成、无不适;近 3 次活动邀约均未接通,建议换企微触达。"
- "最近一次 2 月复查已约到诊;此前半年 5 次回访无到诊,流失风险仍高。"
- "最近一次 5 月复查洁牙提醒未执行、未留结果;近一年 3 次回访均未跟进到位。"  ← 只有事由没结果的正确写法
- "最近一次 4 月术后回访已完成,10 月 9 日已排复查洁牙,暂无需额外动作。"  ← 未来排程的正确写法`;

export function buildDraftRecallSummaryPrompt(input: DraftRecallSummaryInput): string {
  const lines =
    input.items.length > 0
      ? input.items
          .map((it, i) => {
            // 未来 / 过期 / 最近一次 由 orchestrator 程序判定后传入(见 input.types 注释),
            // 这里只负责渲染成模型看得懂的显式标记 —— LLM 不做日期比较、不做排序。
            const when = it.isFuture ? '【未来排程·尚未到期】' : it.isLatestPast ? '【最近一次·已发生】' : null;
            // 最近一次要展开讲,给它更长的正文预算;其余条目只是背景趋势,40 字够了。
            // (源里偶有几百字的方案沟通记录,一刀切 40 字会把唯一一条有信息量的记录砍没)
            const budget = it.isLatestPast ? 160 : 40;
            const parts = [
              it.taskDate ?? '—',
              when,
              it.type ?? '回访',
              it.status,
              // 「已预约」「创建新回访」跟「未完成」语义差很远,漏了会被当成没做
              it.taskStatus ? `任务:${it.taskStatus}` : null,
              it.treatmentItems ? `项目:${it.treatmentItems}` : null,
              it.followContent ? `内容:${it.followContent.slice(0, budget)}` : null,
              it.result ? `结果:${it.result.slice(0, budget)}` : null,
              // ⭐ 显式说"这条没记结果",否则模型倾向于用别条的结果脑补这条
              it.isLatestPast && !it.result ? '结果:未记录' : null,
            ].filter(Boolean);
            return `${i + 1}. ${parts.join(' · ')}`;
          })
          .join('\n')
      : '(无历史联系记录)';

  const futureCount = input.items.filter((it) => it.isFuture).length;
  const futureNote = futureCount
    ? `\n⚠️ 其中 ${futureCount} 条是**尚未到期的未来排程**(已标注),不得表述为未执行/漏做/需补做。`
    : '';
  const latestNote = input.items.some((it) => it.isLatestPast)
    ? '\n⭐ 标了【最近一次·已发生】的那条要放在摘要开头讲清楚(时间 + 事由 + 结果);它没记结果就说未留结果,不要脑补。'
    : input.items.length > 0
      ? '\n⭐ 本列表**没有已发生的回访**(全是未来排程 / 无日期),不要说"最近一次…",直接讲整体。'
      : '';

  return `今天:${input.today}
患者:${input.patientNameMasked}
历史联系 / 回访记录(时间倒序,共 ${input.items.length} 条):
${lines}${futureNote}${latestNote}

请概括以上历史联系的重点。`;
}
