/**
 * Application Use Case: GetWalletUseCase
 *
 * Retrieves wallet information and transactions.
 */

import type { IWalletRepository, ITransactionRepository } from '../../domain/repositories/IWalletRepository';
import type { Wallet } from '../../domain/entities/Wallet';
import type {
  IGetWalletPresenter,
  GetWalletResultDTO,
  GetWalletViewModel,
} from '../presenters/IGetWalletPresenter';
import type { UseCase } from '@core/shared/application/UseCase';

export interface GetWalletInput {
  leagueId: string;
}

export class GetWalletUseCase
  implements UseCase<GetWalletInput, GetWalletResultDTO, GetWalletViewModel, IGetWalletPresenter>
{
  constructor(
    private readonly walletRepository: IWalletRepository,
    private readonly transactionRepository: ITransactionRepository,
  ) {}

  async execute(
    input: GetWalletInput,
    presenter: IGetWalletPresenter,
  ): Promise<void> {
    presenter.reset();

    const { leagueId } = input;

    if (!leagueId) {
      throw new Error('LeagueId is required');
    }

    let wallet = await this.walletRepository.findByLeagueId(leagueId);
    
    if (!wallet) {
      const id = `wallet-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
      const newWallet: Wallet = {
        id,
        leagueId,
        balance: 0,
        totalRevenue: 0,
        totalPlatformFees: 0,
        totalWithdrawn: 0,
        currency: 'USD',
        createdAt: new Date(),
      };
      wallet = await this.walletRepository.create(newWallet);
    }

    const transactions = await this.transactionRepository.findByWalletId(wallet.id);
    transactions.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());

    const dto: GetWalletResultDTO = {
      wallet: {
        id: wallet.id,
        leagueId: wallet.leagueId,
        balance: wallet.balance,
        totalRevenue: wallet.totalRevenue,
        totalPlatformFees: wallet.totalPlatformFees,
        totalWithdrawn: wallet.totalWithdrawn,
        currency: wallet.currency,
        createdAt: wallet.createdAt,
      },
      transactions: transactions.map(t => ({
        id: t.id,
        walletId: t.walletId,
        type: t.type,
        amount: t.amount,
        description: t.description,
        referenceId: t.referenceId,
        referenceType: t.referenceType,
        createdAt: t.createdAt,
      })),
    };

    presenter.present(dto);
  }
}