import { normalizeDatetime } from '../src/modules/sync/assembler/field-mapper';

/**
 * 宿主时间归一的时区语义。
 *
 * 【2026-08-01 实测发现的既有 bug】旧版对**纯日期**('2026-05-10')直通不补 offset,
 * 下游 `new Date('2026-05-10')` 按 ISO 规范解析成 **UTC 零点** —— 而宿主给的是**当地日期**
 * (jvs-dw 的 DW 是 Asia/Shanghai),于是整整偏 8 小时:
 *     DW created_date = 2022-09-30(北京)
 *       旧:2022-09-30T00:00:00Z = 北京 09-30 **08:00**  ❌
 *       新:2022-09-29T16:00:00Z = 北京 09-30 **00:00**  ✅
 * 测试服实测规模:diagnosis_record 有 106,860 条 occurred_at 落在 UTC 零点(占 6%),
 * 正是这条路径来的;落在 UTC 16:00(正确形态)的只有 5 条。
 *
 * 【边界纪律】本函数只作用于 CanonicalResourceMeta.datetimeFields 声明的字段,
 * 那些目标列**全是 timestamptz**。真正的纯日期列(patient_return_visit.taskDate /
 * patient.birthDate)刻意不进该清单 —— 对它们补 offset 会让 PG 取 UTC 日期时**退一天**。
 * 新增 canonical 字段时按"目标列类型"归类,别凭字段名像不像时间。
 */
describe('normalizeDatetime — 时区语义', () => {
  const SH = 'Asia/Shanghai';

  test('⭐ 纯日期 → 当地零点(不是 UTC 零点)', () => {
    const out = normalizeDatetime('2022-09-30', SH);
    expect(out).toBe('2022-09-30T00:00:00+08:00');
    // 落到实际时刻:北京零点 = UTC 前一天 16:00
    expect(new Date(out).toISOString()).toBe('2022-09-29T16:00:00.000Z');
  });

  test('⭐ 回归:旧行为会偏 8 小时 —— 直通字符串被 JS 当成 UTC 零点', () => {
    // 这一行是"如果有人把补 offset 改回直通"会发生什么的固化证据
    expect(new Date('2022-09-30').toISOString()).toBe('2022-09-30T00:00:00.000Z');
    // 与正确值差整 8 小时
    const correct = new Date(normalizeDatetime('2022-09-30', SH)).getTime();
    expect(new Date('2022-09-30').getTime() - correct).toBe(8 * 3600 * 1000);
  });

  test('UTC 宿主不受影响(offset 是 Z,纯日期仍是 UTC 零点)', () => {
    expect(new Date(normalizeDatetime('2022-09-30', 'UTC')).toISOString()).toBe(
      '2022-09-30T00:00:00.000Z',
    );
  });

  test('东京宿主按 +09:00 解释(时区取自 manifest,不写死东八区)', () => {
    expect(new Date(normalizeDatetime('2022-09-30', 'Asia/Tokyo')).toISOString()).toBe(
      '2022-09-29T15:00:00.000Z',
    );
  });

  test('无 tz 的 datetime 照旧补 offset(既有行为不变)', () => {
    expect(normalizeDatetime('2026-05-10 14:00:00', SH)).toBe('2026-05-10T14:00:00+08:00');
    expect(normalizeDatetime('2026-05-10T14:00:00', SH)).toBe('2026-05-10T14:00:00+08:00');
  });

  test('已带 tz 的直通(只把空格换成 T),不重复补 offset', () => {
    expect(normalizeDatetime('2026-05-10 14:00:00+08:00', SH)).toBe('2026-05-10T14:00:00+08:00');
    expect(normalizeDatetime('2026-05-10T06:00:00Z', SH)).toBe('2026-05-10T06:00:00Z');
  });

  test('识别不了的形态原样返回(交给 zod 报错,不猜)', () => {
    expect(normalizeDatetime('not-a-date', SH)).toBe('not-a-date');
    expect(normalizeDatetime('', SH)).toBe('');
  });
});
