import type { Payment } from '@core/payments/domain/entities/Payment';
import {
  Payment as PaymentFactory,
  PaymentStatus,
  PaymentType,
  PayerType,
} from '@core/payments/domain/entities/Payment';

import { PaymentsPaymentOrmEntity } from '../entities/PaymentsPaymentOrmEntity';
import {
  assertDate,
  assertEnumValue,
  assertNonEmptyString,
  assertNumber,
  assertOptionalStringOrNull,
} from '../schema/TypeOrmPaymentsSchemaGuards';

export class PaymentsPaymentOrmMapper {
  toOrmEntity(domain: Payment): PaymentsPaymentOrmEntity {
    const entity = new PaymentsPaymentOrmEntity();
    entity.id = domain.id;
    entity.type = domain.type;
    entity.amount = domain.amount;
    entity.platformFee = domain.platformFee;
    entity.netAmount = domain.netAmount;
    entity.payerId = domain.payerId;
    entity.payerType = domain.payerType;
    entity.leagueId = domain.leagueId;
    entity.seasonId = domain.seasonId ?? null;
    entity.status = domain.status;
    entity.createdAt = domain.createdAt;
    entity.completedAt = domain.completedAt ?? null;
    return entity;
  }

  toDomain(entity: PaymentsPaymentOrmEntity): Payment {
    const entityName = 'PaymentsPayment';

    assertNonEmptyString(entityName, 'id', entity.id);
    assertEnumValue(entityName, 'type', entity.type, Object.values(PaymentType));
    assertNumber(entityName, 'amount', entity.amount);
    assertNumber(entityName, 'platformFee', entity.platformFee);
    assertNumber(entityName, 'netAmount', entity.netAmount);
    assertNonEmptyString(entityName, 'payerId', entity.payerId);
    assertEnumValue(entityName, 'payerType', entity.payerType, Object.values(PayerType));
    assertNonEmptyString(entityName, 'leagueId', entity.leagueId);
    assertOptionalStringOrNull(entityName, 'seasonId', entity.seasonId);
    assertEnumValue(entityName, 'status', entity.status, Object.values(PaymentStatus));
    assertDate(entityName, 'createdAt', entity.createdAt);

    if (entity.completedAt !== null && entity.completedAt !== undefined) {
      assertDate(entityName, 'completedAt', entity.completedAt);
    }

    return PaymentFactory.rehydrate({
      id: entity.id,
      type: entity.type,
      amount: entity.amount,
      platformFee: entity.platformFee,
      netAmount: entity.netAmount,
      payerId: entity.payerId,
      payerType: entity.payerType,
      leagueId: entity.leagueId,
      status: entity.status,
      createdAt: entity.createdAt,
      ...(entity.seasonId !== null && entity.seasonId !== undefined ? { seasonId: entity.seasonId } : {}),
      ...(entity.completedAt !== null && entity.completedAt !== undefined ? { completedAt: entity.completedAt } : {}),
    });
  }
}
