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

import type { IWalletRepository, ITransactionRepository } from '../../domain/repositories/IWalletRepository';
import type { Wallet, Transaction } from '../../domain/entities/Wallet';
import type { UseCase } from '@core/shared/application/UseCase';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';

export type GetWalletErrorCode = 'INVALID_INPUT';

export interface GetWalletInput {
  leagueId: string;
}

export interface GetWalletResult {
  wallet: Wallet;
  transactions: Transaction[];
}

export class GetWalletUseCase
  implements UseCase<GetWalletInput, void, GetWalletErrorCode>
{
  constructor(
    private readonly walletRepository: IWalletRepository,
    private readonly transactionRepository: ITransactionRepository,
    private readonly output: UseCaseOutputPort<GetWalletResult>,
  ) {}

  async execute(input: GetWalletInput): Promise<Result<void, ApplicationErrorCode<GetWalletErrorCode>>> {
    const { leagueId } = input;

    if (!leagueId) {
      return Result.err({ code: 'INVALID_INPUT' as const });
    }

    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());

    this.output.present({ wallet, transactions });

    return Result.ok(undefined);
  }
}