import { Decimal } from '@prisma/client/runtime/library';
import { MatchBetStatsService } from './match-bet-stats.service';

describe('MatchBetStatsService', () => {
  let prisma: {
    betSelection: { findMany: jest.Mock };
  };
  let service: MatchBetStatsService;

  beforeEach(() => {
    prisma = {
      betSelection: { findMany: jest.fn().mockResolvedValue([]) },
    };
    service = new MatchBetStatsService(prisma as never);
  });

  it('returns empty stats without querying when match ids are empty', async () => {
    const stats = await service.betStatsForMatches([]);

    expect(stats.size).toBe(0);
    expect(prisma.betSelection.findMany).not.toHaveBeenCalled();
  });

  it('deduplicates bets and fills zero stats for matches without bets', async () => {
    const matchId = BigInt(10);
    const emptyMatchId = BigInt(11);
    prisma.betSelection.findMany.mockResolvedValue([
      {
        matchId,
        betId: BigInt(100),
        bet: { stake: new Decimal(50), status: 'PENDING' },
      },
      {
        matchId,
        betId: BigInt(100),
        bet: { stake: new Decimal(50), status: 'PENDING' },
      },
      {
        matchId,
        betId: BigInt(101),
        bet: { stake: new Decimal(25), status: 'WON' },
      },
      {
        matchId: null,
        betId: BigInt(102),
        bet: { stake: new Decimal(99), status: 'PENDING' },
      },
    ]);

    const stats = await service.betStatsForMatches([matchId, emptyMatchId]);

    expect(prisma.betSelection.findMany).toHaveBeenCalledWith({
      where: { matchId: { in: [matchId, emptyMatchId] } },
      select: {
        matchId: true,
        betId: true,
        bet: { select: { stake: true, status: true } },
      },
    });
    expect(stats.get(matchId.toString())).toEqual({
      betCount: 2,
      totalStake: '75',
      pendingCount: 1,
    });
    expect(stats.get(emptyMatchId.toString())).toEqual({
      betCount: 0,
      totalStake: '0',
      pendingCount: 0,
    });
  });
});
