import { describe, expect, it, vi } from 'vitest';

import { RaceRegistration } from '@core/racing/domain/entities/RaceRegistration';

import { RaceRegistrationOrmEntity } from '../entities/RaceRegistrationOrmEntity';
import { RaceRegistrationOrmMapper } from './RaceRegistrationOrmMapper';

describe('RaceRegistrationOrmMapper', () => {
  it('toDomain preserves persisted identity and uses rehydrate semantics (does not call create)', () => {
    const mapper = new RaceRegistrationOrmMapper();

    const entity = new RaceRegistrationOrmEntity();
    entity.id = 'race-1:driver-1';
    entity.raceId = 'race-1';
    entity.driverId = 'driver-1';
    entity.registeredAt = new Date('2025-01-01T00:00:00.000Z');

    if (typeof (RaceRegistration as unknown as { rehydrate?: unknown }).rehydrate !== 'function') {
      throw new Error('rehydrate-missing');
    }

    const rehydrateSpy = vi.spyOn(
      RaceRegistration as unknown as { rehydrate: (...args: unknown[]) => unknown },
      'rehydrate',
    );
    const createSpy = vi.spyOn(RaceRegistration, 'create').mockImplementation(() => {
      throw new Error('create-called');
    });

    const domain = mapper.toDomain(entity);

    expect(domain.id).toBe(entity.id);
    expect(domain.raceId.toString()).toBe(entity.raceId);
    expect(domain.driverId.toString()).toBe(entity.driverId);
    expect(createSpy).not.toHaveBeenCalled();
    expect(rehydrateSpy).toHaveBeenCalled();
  });

  it('toDomain validates persisted shape and throws adapter-scoped error type', () => {
    const mapper = new RaceRegistrationOrmMapper();

    const entity = new RaceRegistrationOrmEntity();
    entity.id = 'race-1:driver-1';
    entity.raceId = 123 as unknown as string;
    entity.driverId = 'driver-1';
    entity.registeredAt = new Date('2025-01-01T00:00:00.000Z');

    try {
      mapper.toDomain(entity);
      throw new Error('expected-to-throw');
    } catch (error) {
      expect(error).toMatchObject({ name: 'InvalidRaceRegistrationSchemaError' });
    }
  });
});