/**
 * TransactionSynthesizer occurredAt 三级确定性回退单元测试。
 *
 * 坐实:emits.occurredAtField 缺失/不可解析时,回退 updatedAt → createdAt,
 * 仅三者皆缺才落墙钟。否则同一源行(新 sourceEventId、时间字段为空)每次摄入
 * 得到不同 occurredAt,下游 fact 时间锚变更检测会产生伪 supersede 版本。
 */
import { TransactionSynthesizer } from '../src/modules/sync/pipeline/transaction-synthesizer';
import type { EmitsConfig } from '../src/modules/sync/assembler/assembler.schema';

describe('synthesizer | occurredAt 确定性回退', () => {
  const synth = new TransactionSynthesizer();
  const emits: EmitsConfig = {
    action: 'appointment_created',
    subjectType: 'appointment',
    occurredAtField: 'occurredAt',
  };
  const make = (canonicalRow: Record<string, unknown>) => ({
    rawRow: {},
    emits,
    resource: 'appointments',
    hostId: 'h1',
    tenantId: 'grp_001',
    patientIdResolver: () => undefined,
    sourceContext: 'test:occurred-at',
    sourceUnit: '',
    canonicalRow: { externalId: 'apt-1', clinicId: 'C001', ...canonicalRow },
  });

  test('occurredAtField 有值 → 直接用,不看 updatedAt/createdAt', () => {
    const tx = synth.synthesize(
      make({
        occurredAt: '2026-01-01T10:00:00+08:00',
        updatedAt: '2026-02-01T00:00:00+08:00',
        createdAt: '2026-03-01T00:00:00+08:00',
      }),
    );
    expect(tx!.occurredAt).toEqual(new Date('2026-01-01T10:00:00+08:00'));
  });

  test('occurredAtField 缺失 → 回退 updatedAt', () => {
    const tx = synth.synthesize(
      make({
        updatedAt: '2026-02-01T00:00:00+08:00',
        createdAt: '2026-03-01T00:00:00+08:00',
      }),
    );
    expect(tx!.occurredAt).toEqual(new Date('2026-02-01T00:00:00+08:00'));
  });

  test('occurredAtField 不可解析 → 回退 updatedAt', () => {
    const tx = synth.synthesize(
      make({
        occurredAt: 'not-a-date',
        updatedAt: '2026-02-01T00:00:00+08:00',
      }),
    );
    expect(tx!.occurredAt).toEqual(new Date('2026-02-01T00:00:00+08:00'));
  });

  test('occurredAtField/updatedAt 皆缺 → 回退 createdAt', () => {
    const tx = synth.synthesize(make({ createdAt: '2026-03-01T00:00:00+08:00' }));
    expect(tx!.occurredAt).toEqual(new Date('2026-03-01T00:00:00+08:00'));
  });

  test('时间字段有值 → 重复摄入 occurredAt 逐字节一致(确定性,不受墙钟影响)', () => {
    const row = { updatedAt: '2026-02-01T00:00:00+08:00' };
    const a = synth.synthesize(make(row));
    const b = synth.synthesize(make(row));
    expect(a!.occurredAt).toEqual(b!.occurredAt);
  });

  test('三者皆缺 → 落墙钟兜底(列非空,不能是 null)', () => {
    const before = Date.now();
    const tx = synth.synthesize(make({}));
    const after = Date.now();
    expect(tx!.occurredAt).toBeInstanceOf(Date);
    const t = (tx!.occurredAt as Date).getTime();
    expect(t).toBeGreaterThanOrEqual(before);
    expect(t).toBeLessThanOrEqual(after);
  });
});
