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

import { RaceRegistrationOrmEntity } from '../entities/RaceRegistrationOrmEntity';
import { InvalidRaceRegistrationSchemaError } from '../errors/InvalidRaceRegistrationSchemaError';

function isNonEmptyString(value: unknown): value is string {
  return typeof value === 'string' && value.trim().length > 0;
}

export class RaceRegistrationOrmMapper {
  toOrmEntity(domain: RaceRegistration): RaceRegistrationOrmEntity {
    const entity = new RaceRegistrationOrmEntity();
    entity.id = domain.id;
    entity.raceId = domain.raceId.toString();
    entity.driverId = domain.driverId.toString();
    entity.registeredAt = domain.registeredAt.toDate();
    return entity;
  }

  toDomain(entity: RaceRegistrationOrmEntity): RaceRegistration {
    if (!isNonEmptyString(entity.id)) {
      throw new InvalidRaceRegistrationSchemaError('Invalid id');
    }
    if (!isNonEmptyString(entity.raceId)) {
      throw new InvalidRaceRegistrationSchemaError('Invalid raceId');
    }
    if (!isNonEmptyString(entity.driverId)) {
      throw new InvalidRaceRegistrationSchemaError('Invalid driverId');
    }
    if (!(entity.registeredAt instanceof Date) || Number.isNaN(entity.registeredAt.getTime())) {
      throw new InvalidRaceRegistrationSchemaError('Invalid registeredAt');
    }

    return RaceRegistration.rehydrate({
      id: entity.id,
      raceId: entity.raceId,
      driverId: entity.driverId,
      registeredAt: entity.registeredAt,
    });
  }
}