import { readFileSync } from 'node:fs';
import { join } from 'node:path';

/**
 * 话术的时间锚 —— 必须与初选矩阵**同一个锚点**。
 *
 * 由来:矩阵的温度档按「该标签**最新的未治疗**诊断」算(锚点 = COALESCE(occurred_at, planned_for))。
 * 而话术原来取 `evidence.factIds[0]` —— 数组第一个,由写入顺序决定,既不是最新也不是最早。
 *
 * 实测(2026-08-05 本地库):4,573 条 reason 中 269 条有多份证据,其中 **184 条** `factIds[0]`
 * 不是最新的,**平均差 952 天(2.6 年)**。不改的话会出现:
 *   矩阵说这人「1 年内」→ 客服打开,话术开口"您三年前查出的龋齿…"
 * 主管和客服看到两个时间,而**没有任何报错**,也没人知道该信哪个。
 *
 * 本文件是纯文本扫描 —— 这类"两处口径漂移"不会在类型或运行时暴露,只能这么锁。
 */
const SRC = readFileSync(
  join(__dirname, '../src/modules/ai/orchestrators/plan-script.orchestrator.ts'),
  'utf-8',
);

describe('话术触发锚点与矩阵同源', () => {
  test('⭐⭐ 不再直接取 evidence.factIds[0] 当触发 fact', () => {
    // 老写法:const leadFactId = evidence.factIds?.[0]
    expect(SRC).not.toMatch(/factIds\?\.\[0\]/);
  });

  test('⭐⭐ 只认未治疗的证据 —— 治完是 status=fulfilled,拿它当锚等于念一个已做完的诊断', () => {
    const block = SRC.slice(SRC.indexOf('const resolveReasonTrigger'));
    expect(block).toContain("status === 'active'");
  });

  test('⭐⭐ 按锚点降序取最新(而不是最早/任意)', () => {
    const block = SRC.slice(SRC.indexOf('const resolveReasonTrigger'));
    // 降序:tb - ta
    expect(block).toMatch(/return tb - ta;/);
  });

  test('⭐ 锚点口径 = COALESCE(occurred_at, planned_for) —— 建议类信号只有 plannedFor', () => {
    const block = SRC.slice(SRC.indexOf('const resolveReasonTrigger'));
    // 排序键与取值都要带 plannedFor 回落
    expect(block).toMatch(/occurredAt \?\? .*plannedFor/);
    expect(block).toMatch(/const anchorAt = lead\.occurredAt \?\? lead\.plannedFor;/);
  });
});
