import { WalletsApiClient, LeagueWalletDTO, WithdrawRequestDTO, WithdrawResponseDTO } from '@/lib/api/wallets/WalletsApiClient';
import { LeagueWalletViewModel } from '@/lib/view-models/LeagueWalletViewModel';
import { WalletTransactionViewModel } from '@/lib/view-models/WalletTransactionViewModel';
import { SubmitBlocker, ThrottleBlocker } from '@/lib/blockers';

/**
 * League Wallet Service
 *
 * Orchestrates league wallet operations by coordinating API calls and view model creation.
 * All dependencies are injected via constructor.
 */
export class LeagueWalletService {
  private readonly submitBlocker = new SubmitBlocker();
  private readonly throttle = new ThrottleBlocker(500);

  constructor(
    private readonly apiClient: WalletsApiClient
  ) {}

  /**
   * Get wallet for a league
   */
  async getWalletForLeague(leagueId: string): Promise<LeagueWalletViewModel> {
    const dto = await this.apiClient.getLeagueWallet(leagueId);
    const transactions = dto.transactions.map(t => new WalletTransactionViewModel({
      id: t.id,
      type: t.type,
      description: t.description,
      amount: t.amount,
      fee: t.fee,
      netAmount: t.netAmount,
      date: new Date(t.date),
      status: t.status,
      reference: t.reference,
    }));
    return new LeagueWalletViewModel({
      balance: dto.balance,
      currency: dto.currency,
      totalRevenue: dto.totalRevenue,
      totalFees: dto.totalFees,
      totalWithdrawals: dto.totalWithdrawals,
      pendingPayouts: dto.pendingPayouts,
      transactions,
      canWithdraw: dto.canWithdraw,
      withdrawalBlockReason: dto.withdrawalBlockReason,
    });
  }

  /**
   * Withdraw from league wallet
   */
  async withdraw(leagueId: string, amount: number, currency: string, seasonId: string, destinationAccount: string): Promise<WithdrawResponseDTO> {
    if (!this.submitBlocker.canExecute() || !this.throttle.canExecute()) {
      throw new Error('Request blocked due to rate limiting');
    }

    this.submitBlocker.block();
    this.throttle.block();
    try {
      const request: WithdrawRequestDTO = {
        amount,
        currency,
        seasonId,
        destinationAccount,
      };
      return await this.apiClient.withdrawFromLeagueWallet(leagueId, request);
    } finally {
      this.submitBlocker.release();
    }
  }
}