/**
 * PipelineDispatcher emitsResolver 契约单元测试(W3 末 4 入口统一管道)
 *
 * 验证:
 *   - emitsResolver 返回 undefined → 跳过该行(主档 patients 走 upsert,不进 transaction)
 *   - emitsResolver 返回有效 emits → synthesizer 拿到 action/subjectType
 *   - 同 batch 不同 row 可以有不同 emits(push 场景:event.action 不同)
 *
 * 测试只覆盖契约层面(resolver 签名 + 调用次数),不跑真 DB / 真 synthesizer。
 */
import type { EmitsResolver } from '../src/modules/sync/pipeline/pipeline-dispatcher.service';
import type { EmitsConfig } from '../src/modules/sync/assembler/assembler.schema';

describe('dispatcher | emitsResolver 契约', () => {
  test('patient 行返回 undefined,其他资源返回 emits', () => {
    const resolver: EmitsResolver = (resource, row) => {
      if (resource === 'patients') return undefined;
      return {
        action: (row._action as string) ?? 'unknown',
        subjectType: (row._subjectType as string) ?? resource,
        occurredAtField: 'occurredAt',
      } as EmitsConfig;
    };

    expect(resolver('patients', { externalId: 'p1' })).toBeUndefined();
    const apt = resolver('appointments', {
      _action: 'appointment_created',
      _subjectType: 'appointment',
    });
    expect(apt?.action).toBe('appointment_created');
    expect(apt?.subjectType).toBe('appointment');
  });

  test('同一 batch 不同 row 可以有不同 action(push 场景)', () => {
    const resolver: EmitsResolver = (resource, row) => {
      if (resource === 'patients') return undefined;
      return {
        action: (row._action as string) ?? 'unknown',
        subjectType: resource,
        occurredAtField: 'occurredAt',
      } as EmitsConfig;
    };

    const row1 = { _action: 'appointment_created' };
    const row2 = { _action: 'appointment_changed' };
    expect(resolver('appointments', row1)?.action).toBe('appointment_created');
    expect(resolver('appointments', row2)?.action).toBe('appointment_changed');
  });

  test('emits 缺元字段时 resolver 可返回 undefined(行被丢)', () => {
    const resolver: EmitsResolver = (_resource, row) => {
      if (!row._action) return undefined;
      return {
        action: row._action as string,
        subjectType: 'appointment',
        occurredAtField: 'occurredAt',
      } as EmitsConfig;
    };

    expect(resolver('appointments', {})).toBeUndefined();
    expect(resolver('appointments', { _action: 'appointment_created' })).toBeDefined();
  });

  test('yaml 路径:emitsResolver 静态查注册表', () => {
    const registry: Record<string, EmitsConfig> = {
      appointments: {
        action: 'appointment_created' as never,
        subjectType: 'appointment' as never,
        occurredAtField: 'occurredAt',
      },
      encounters: {
        action: 'doctor_encounter_started' as never,
        subjectType: 'clinical_encounter' as never,
        occurredAtField: 'startedAt',
      },
    };
    const resolver: EmitsResolver = (resource) => registry[resource];

    expect(resolver('appointments', {})?.action).toBe('appointment_created');
    expect(resolver('encounters', {})?.occurredAtField).toBe('startedAt');
    expect(resolver('unknown', {})).toBeUndefined();
  });
});
