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

import { TransactionType } from '@core/payments/domain/entities/Wallet';

import { TypeOrmPaymentsSchemaError } from '../errors/TypeOrmPaymentsSchemaError';
import { PaymentsWalletOrmEntity } from '../entities/PaymentsWalletOrmEntity';
import { PaymentsWalletOrmMapper } from './PaymentsWalletOrmMapper';

describe('PaymentsWalletOrmMapper', () => {
  it('maps Wallet domain <-> orm', () => {
    const wallet = {
      id: 'wallet-1',
      leagueId: 'league-1',
      balance: 10,
      totalRevenue: 20,
      totalPlatformFees: 1,
      totalWithdrawn: 5,
      currency: 'USD',
      createdAt: new Date('2025-01-01T00:00:00.000Z'),
    };

    const mapper = new PaymentsWalletOrmMapper();
    const orm = mapper.toOrmEntity(wallet);
    const rehydrated = mapper.toDomain(orm);

    expect(rehydrated.id).toBe('wallet-1');
    expect(rehydrated.leagueId).toBe('league-1');
    expect(rehydrated.balance).toBe(10);
    expect(rehydrated.currency).toBe('USD');
    expect(rehydrated.createdAt.toISOString()).toBe('2025-01-01T00:00:00.000Z');
  });

  it('throws schema error on invalid Wallet', () => {
    const mapper = new PaymentsWalletOrmMapper();

    const orm = new PaymentsWalletOrmEntity();
    orm.id = '';
    orm.leagueId = 'league-1';
    orm.balance = 0;
    orm.totalRevenue = 0;
    orm.totalPlatformFees = 0;
    orm.totalWithdrawn = 0;
    orm.currency = 'USD';
    orm.createdAt = new Date();

    expect(() => mapper.toDomain(orm)).toThrow(TypeOrmPaymentsSchemaError);
  });

  it('maps Transaction domain <-> orm', () => {
    const transaction = {
      id: 'txn-1',
      walletId: 'wallet-1',
      type: TransactionType.DEPOSIT,
      amount: 123,
      description: 'Deposit',
      createdAt: new Date('2025-01-01T00:00:00.000Z'),
    };

    const mapper = new PaymentsWalletOrmMapper();
    const orm = mapper.toOrmTransaction(transaction);
    const rehydrated = mapper.toDomainTransaction(orm);

    expect(rehydrated.id).toBe('txn-1');
    expect(rehydrated.walletId).toBe('wallet-1');
    expect(rehydrated.type).toBe(TransactionType.DEPOSIT);
    expect(rehydrated.amount).toBe(123);
  });
});
