import type { ILeagueWalletRepository } from '../../domain/repositories/ILeagueWalletRepository'; import type { ITransactionRepository } from '../../domain/repositories/ITransactionRepository'; import type { GetLeagueWalletOutputPort, WalletTransactionOutputPort } from '../ports/output/GetLeagueWalletOutputPort'; import type { TransactionType } from '../../domain/entities/league-wallet/Transaction'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; export interface GetLeagueWalletUseCaseParams { leagueId: string; } /** * Use Case for retrieving league wallet information. */ export class GetLeagueWalletUseCase { constructor( private readonly leagueWalletRepository: ILeagueWalletRepository, private readonly transactionRepository: ITransactionRepository, ) {} async execute( params: GetLeagueWalletUseCaseParams, ): Promise>> { try { const wallet = await this.leagueWalletRepository.findByLeagueId(params.leagueId); if (!wallet) { return Result.err({ code: 'REPOSITORY_ERROR', message: 'Wallet not found' }); } const transactions = await this.transactionRepository.findByWalletId(wallet.id.toString()); let totalRevenue = 0; let totalFees = 0; let totalWithdrawals = 0; let pendingPayouts = 0; const transactionViewModels: WalletTransactionOutputPort[] = transactions .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()) .map(transaction => { const amount = transaction.amount.amount; const fee = transaction.platformFee.amount; const netAmount = transaction.netAmount.amount; if ( transaction.type === 'sponsorship_payment' || transaction.type === 'membership_payment' || transaction.type === 'prize_payout' ) { totalRevenue += amount; totalFees += fee; } if (transaction.type === 'withdrawal' && transaction.status === 'completed') { totalWithdrawals += netAmount; } if (transaction.type === 'prize_payout' && transaction.status === 'pending') { pendingPayouts += netAmount; } return { id: transaction.id.toString(), type: this.mapTransactionType(transaction.type), description: transaction.description ?? '', amount, fee, netAmount, date: transaction.createdAt.toISOString(), status: transaction.status === 'cancelled' ? 'failed' : transaction.status, }; }); const output: GetLeagueWalletOutputPort = { balance: wallet.balance.amount, currency: wallet.balance.currency, totalRevenue, totalFees, totalWithdrawals, pendingPayouts, canWithdraw: true, transactions: transactionViewModels, }; return Result.ok(output); } catch { return Result.err({ code: 'REPOSITORY_ERROR', message: 'Failed to fetch league wallet' }); } } private mapTransactionType(type: TransactionType): WalletTransactionOutputPort['type'] { switch (type) { case 'sponsorship_payment': return 'sponsorship'; case 'membership_payment': return 'membership'; case 'prize_payout': return 'prize'; case 'withdrawal': return 'withdrawal'; case 'refund': return 'sponsorship'; } } }