import {
  resolveAgeBranch,
  resolveAgeGroup,
  smartDateDisplay,
  resolveSalutation,
  pickPrimaryMissed,
  canonicalMissedKey,
  lookupKeyPoints,
  lookupReviewDuration,
  missedFromReason,
} from '../src/modules/ai/calls/draft-plan-script/script-facts';

describe('script-facts(确定性逻辑提取,替代 LLM 主观判断)', () => {
  describe('年龄分支', () => {
    test('≤12 → child', () => expect(resolveAgeBranch(8)).toBe('child'));
    test('=12 边界 → child', () => expect(resolveAgeBranch(12)).toBe('child'));
    test('≥13 → adult', () => expect(resolveAgeBranch(13)).toBe('adult'));
    test('未知 → adult(默认成人漏诊模板)', () => expect(resolveAgeBranch(null)).toBe('adult'));
    test('年龄组分档', () => {
      expect(resolveAgeGroup(44)).toBe('中年');
      expect(resolveAgeGroup(25)).toBe('青年');
      expect(resolveAgeGroup(70)).toBe('老年');
      expect(resolveAgeGroup(8)).toBeNull();
    });
  });

  describe('智能日期显示', () => {
    const now = new Date('2026-06-02T00:00:00Z');
    test('今年 → X月X号', () => expect(smartDateDisplay('2026-01-29T00:00:00Z', now)).toBe('1月29号'));
    test('去年 → 去年X月', () => expect(smartDateDisplay('2025-12-10', now)).toBe('去年12月'));
    test('更早 → XXXX年X月', () => expect(smartDateDisplay('2023-03-01', now)).toBe('2023年3月'));
    test('空 → null', () => expect(smartDateDisplay(null, now)).toBeNull());
  });

  describe('智能称呼', () => {
    test('成人男 → 姓+先生', () =>
      expect(resolveSalutation({ nameMasked: '侯*', gender: '男', branch: 'adult' })).toBe('侯先生'));
    test('成人女 → 姓+女士', () =>
      expect(resolveSalutation({ nameMasked: '侯琴', gender: '女', branch: 'adult' })).toBe('侯女士'));
    test('儿童 → 姓+家长', () =>
      expect(resolveSalutation({ nameMasked: '乐*', gender: '男', branch: 'child' })).toBe('乐家长'));
    test('性别未知 → 您好', () =>
      expect(resolveSalutation({ nameMasked: '侯琴', gender: null, branch: 'adult' })).toBe('您好'));
  });

  describe('漏诊项归一 + 优先级', () => {
    test('文本含关键词 → 命中 key', () =>
      expect(canonicalMissedKey('牙位:21,牙槽骨吸收')).toBe('牙槽骨吸收'));
    test('优先级:儿牙早矫 > 牙槽骨吸收', () =>
      expect(pickPrimaryMissed(['牙槽骨吸收', '儿牙早矫'])?.key).toBe('儿牙早矫'));
    test('单条取该条', () =>
      expect(pickPrimaryMissed(['牙位:21,牙槽骨吸收'])?.key).toBe('牙槽骨吸收'));
    test('空 → null', () => expect(pickPrimaryMissed([null, ''])).toBeNull());
  });

  describe('转换层:PAC reason(应治未治)→ 漏诊项', () => {
    test('subKey 映射(带 @tooth 后缀)', () => {
      const m = missedFromReason({ subKey: 'missing_tooth@36', dxCode: 'K08' });
      expect(m.key).toBe('缺失牙');
      expect(m.label).toBe('缺失牙');
    });
    test('牙周 subKey → 牙周炎', () =>
      expect(missedFromReason({ subKey: 'perio_no_srp@whole' }).key).toBe('牙周炎'));
    test('正畸 subKey → 错颌畸形(有 key-points)', () => {
      const m = missedFromReason({ subKey: 'ortho_no_consult' });
      expect(m.key).toBe('错颌畸形');
      expect(lookupKeyPoints(m.key)?.risks.length).toBeGreaterThan(0);
    });
    test('未知 subKey → 文本兜底归一', () =>
      expect(missedFromReason({ subKey: 'xxx', scenarioLabel: '龋齿未做充填' }).key).toBe('龋齿'));
    test('每个 PAC 子场景都有复查时长(非空)', () => {
      for (const sub of ['missing_tooth', 'caries_no_filling', 'endo_no_rct', 'perio_no_srp', 'ortho_no_consult', 'hard_tissue_damage', 'gum_alveolar_lesion', 'impacted_tooth', 'jaw_cyst', 'development_eruption']) {
        const m = missedFromReason({ subKey: sub });
        expect(lookupReviewDuration(m.key).length).toBeGreaterThan(5);
      }
    });
  });

  describe('查表(渐进式只取命中那条)', () => {
    test('key-points 命中', () => {
      const kp = lookupKeyPoints('牙槽骨吸收');
      expect(kp?.risks.length).toBeGreaterThan(0);
      expect(kp?.advantages.length).toBeGreaterThan(0);
    });
    test('复查时长命中', () =>
      expect(lookupReviewDuration('缺失牙')).toContain('复查检查约30分钟'));
    test('复查时长兜底', () =>
      expect(lookupReviewDuration(null)).toContain('复查检查约30分钟'));
  });
});
