import type { Prize } from '@core/payments/domain/entities/Prize';
import { Prize as PrizeFactory, PrizeType } from '@core/payments/domain/entities/Prize';

import { PaymentsPrizeOrmEntity } from '../entities/PaymentsPrizeOrmEntity';
import {
    assertBoolean,
    assertDate,
    assertEnumValue,
    assertInteger,
    assertNonEmptyString,
    assertNumber,
    assertOptionalDate,
    assertOptionalStringOrNull,
} from '../schema/TypeOrmPaymentsSchemaGuards';

export class PaymentsPrizeOrmMapper {
  toOrmEntity(domain: Prize): PaymentsPrizeOrmEntity {
    const entity = new PaymentsPrizeOrmEntity();
    entity.id = domain.id;
    entity.leagueId = domain.leagueId;
    entity.seasonId = domain.seasonId;
    entity.position = domain.position;
    entity.name = domain.name;
    entity.amount = domain.amount;
    entity.type = domain.type;
    entity.description = domain.description ?? null;
    entity.awarded = domain.awarded;
    entity.awardedTo = domain.awardedTo ?? null;
    entity.awardedAt = domain.awardedAt ?? null;
    entity.createdAt = domain.createdAt;
    return entity;
  }

  toDomain(entity: PaymentsPrizeOrmEntity): Prize {
    const entityName = 'PaymentsPrize';

    assertNonEmptyString(entityName, 'id', entity.id);
    assertNonEmptyString(entityName, 'leagueId', entity.leagueId);
    assertNonEmptyString(entityName, 'seasonId', entity.seasonId);
    assertInteger(entityName, 'position', entity.position);
    assertNonEmptyString(entityName, 'name', entity.name);
    assertNumber(entityName, 'amount', entity.amount);
    assertEnumValue(entityName, 'type', entity.type, Object.values(PrizeType));
    assertOptionalStringOrNull(entityName, 'description', entity.description);
    assertBoolean(entityName, 'awarded', entity.awarded);
    assertOptionalStringOrNull(entityName, 'awardedTo', entity.awardedTo);
    assertOptionalDate(entityName, 'awardedAt', entity.awardedAt);
    assertDate(entityName, 'createdAt', entity.createdAt);

    return PrizeFactory.rehydrate({
      id: entity.id,
      leagueId: entity.leagueId,
      seasonId: entity.seasonId,
      position: entity.position,
      name: entity.name,
      amount: entity.amount,
      type: entity.type,
      awarded: entity.awarded,
      createdAt: entity.createdAt,
      ...(entity.description !== null && entity.description !== undefined ? { description: entity.description } : {}),
      ...(entity.awardedTo !== null && entity.awardedTo !== undefined ? { awardedTo: entity.awardedTo } : {}),
      ...(entity.awardedAt !== null && entity.awardedAt !== undefined ? { awardedAt: entity.awardedAt } : {}),
    });
  }
}
