import { describe, it, expect, vi, Mocked, beforeEach } from 'vitest';
import { LeagueWalletService } from './LeagueWalletService';
import { WalletsApiClient } from '@/lib/api/wallets/WalletsApiClient';

describe('LeagueWalletService', () => {
  let mockApiClient: Mocked<WalletsApiClient>;
  let service: LeagueWalletService;

  beforeEach(() => {
    mockApiClient = {
      getLeagueWallet: vi.fn(),
      withdrawFromLeagueWallet: vi.fn(),
    } as unknown as Mocked<WalletsApiClient>;

    service = new LeagueWalletService(mockApiClient);
  });

  describe('getWalletForLeague', () => {
    it('should call apiClient.getLeagueWallet and return DTO', async () => {
      const leagueId = 'league-123';
      const mockDto = {
        balance: 1000,
        currency: 'USD',
        totalRevenue: 5000,
        totalFees: 1000,
        totalWithdrawals: 2000,
        pendingPayouts: 500,
        canWithdraw: true,
        transactions: [
          {
            id: 'txn-1',
            type: 'sponsorship' as const,
            description: 'Sponsorship payment',
            amount: 100,
            fee: 10,
            netAmount: 90,
            date: '2023-10-01T10:00:00Z',
            status: 'completed' as const,
            reference: 'ref-1',
          },
        ],
      };

      mockApiClient.getLeagueWallet.mockResolvedValue(mockDto);

      const result = await service.getWalletForLeague(leagueId);

      expect(mockApiClient.getLeagueWallet).toHaveBeenCalledWith(leagueId);
      expect(result).toEqual(mockDto);
    });

    it('should throw error when apiClient.getLeagueWallet fails', async () => {
      const leagueId = 'league-123';
      const error = new Error('API call failed');
      mockApiClient.getLeagueWallet.mockRejectedValue(error);

      await expect(service.getWalletForLeague(leagueId)).rejects.toThrow('API call failed');
    });
  });

  describe('withdraw', () => {
    it('should call apiClient.withdrawFromLeagueWallet with correct parameters', async () => {
      const leagueId = 'league-123';
      const amount = 500;
      const currency = 'USD';
      const seasonId = 'season-456';
      const destinationAccount = 'account-789';

      const mockResponse = { success: true, message: 'Withdrawal successful' };
      mockApiClient.withdrawFromLeagueWallet.mockResolvedValue(mockResponse);

      const result = await service.withdraw(leagueId, amount, currency, seasonId, destinationAccount);

      expect(mockApiClient.withdrawFromLeagueWallet).toHaveBeenCalledWith(leagueId, {
        amount,
        currency,
        seasonId,
        destinationAccount,
      });
      expect(result).toEqual(mockResponse);
    });

    it('should throw error when apiClient.withdrawFromLeagueWallet fails', async () => {
      const leagueId = 'league-123';
      const amount = 500;
      const currency = 'USD';
      const seasonId = 'season-456';
      const destinationAccount = 'account-789';

      const error = new Error('Withdrawal failed');
      mockApiClient.withdrawFromLeagueWallet.mockRejectedValue(error);

      await expect(service.withdraw(leagueId, amount, currency, seasonId, destinationAccount)).rejects.toThrow('Withdrawal failed');
    });
  });
});
