import { LeagueService } from './LeagueService';
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
import { GetLeagueStandingsUseCase } from '@core/racing/application/use-cases/GetLeagueStandingsUseCase';
import { GetLeagueStatsUseCase } from '@core/racing/application/use-cases/GetLeagueStatsUseCase';
import { GetLeagueFullConfigUseCase } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
import { CreateLeagueWithSeasonAndScoringUseCase } from '@core/racing/application/use-cases/CreateLeagueWithSeasonAndScoringUseCase';
import { GetRaceProtestsUseCase } from '@core/racing/application/use-cases/GetRaceProtestsUseCase';
import { GetTotalLeaguesUseCase } from '@core/racing/application/use-cases/GetTotalLeaguesUseCase';
import { GetLeagueJoinRequestsUseCase } from '@core/racing/application/use-cases/GetLeagueJoinRequestsUseCase';
import { ApproveLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/ApproveLeagueJoinRequestUseCase';
import { RejectLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/RejectLeagueJoinRequestUseCase';
import { RemoveLeagueMemberUseCase } from '@core/racing/application/use-cases/RemoveLeagueMemberUseCase';
import { UpdateLeagueMemberRoleUseCase } from '@core/racing/application/use-cases/UpdateLeagueMemberRoleUseCase';
import { GetLeagueOwnerSummaryUseCase } from '@core/racing/application/use-cases/GetLeagueOwnerSummaryUseCase';
import { GetLeagueProtestsUseCase } from '@core/racing/application/use-cases/GetLeagueProtestsUseCase';
import type { Logger } from '@core/shared/application/Logger';

describe('LeagueService', () => {
  let service: LeagueService;
  let mockGetTotalLeaguesUseCase: jest.Mocked<GetTotalLeaguesUseCase>;
  let mockGetLeagueJoinRequestsUseCase: jest.Mocked<GetLeagueJoinRequestsUseCase>;
  let mockApproveLeagueJoinRequestUseCase: jest.Mocked<ApproveLeagueJoinRequestUseCase>;
  let mockLogger: jest.Mocked<Logger>;

  beforeEach(() => {
    mockGetTotalLeaguesUseCase = {
      execute: jest.fn(),
    } as any;
    mockGetLeagueJoinRequestsUseCase = {
      execute: jest.fn(),
    } as any;
    mockApproveLeagueJoinRequestUseCase = {
      execute: jest.fn(),
    } as any;
    mockLogger = {
      debug: jest.fn(),
    } as any;

    service = new LeagueService(
      {} as any, // mockGetAllLeaguesWithCapacityUseCase
      {} as any, // mockGetLeagueStandingsUseCase
      {} as any, // mockGetLeagueStatsUseCase
      {} as any, // mockGetLeagueFullConfigUseCase
      {} as any, // mockCreateLeagueWithSeasonAndScoringUseCase
      {} as any, // mockGetRaceProtestsUseCase
      mockGetTotalLeaguesUseCase,
      mockGetLeagueJoinRequestsUseCase,
      mockApproveLeagueJoinRequestUseCase,
      {} as any, // mockRejectLeagueJoinRequestUseCase
      {} as any, // mockRemoveLeagueMemberUseCase
      {} as any, // mockUpdateLeagueMemberRoleUseCase
      {} as any, // mockGetLeagueOwnerSummaryUseCase
      {} as any, // mockGetLeagueProtestsUseCase
      {} as any, // mockGetLeagueSeasonsUseCase
      {} as any, // mockGetLeagueMembershipsUseCase
      {} as any, // mockGetLeagueScheduleUseCase
      {} as any, // mockGetLeagueAdminPermissionsUseCase
      mockLogger,
    );
  });

  it('should get total leagues', async () => {
    mockGetTotalLeaguesUseCase.execute.mockImplementation(async (params, presenter) => {
      presenter.present({ totalLeagues: 5 });
    });

    const result = await service.getTotalLeagues();

    expect(result).toEqual({ totalLeagues: 5 });
    expect(mockLogger.debug).toHaveBeenCalledWith('[LeagueService] Fetching total leagues count.');
  });

  it('should get league join requests', async () => {
    mockGetLeagueJoinRequestsUseCase.execute.mockImplementation(async (params, presenter) => {
      presenter.present({
        joinRequests: [{ id: 'req-1', leagueId: 'league-1', driverId: 'driver-1', requestedAt: new Date(), message: 'msg' }],
        drivers: [{ id: 'driver-1', name: 'Driver 1' }],
      });
    });

    const result = await service.getLeagueJoinRequests('league-1');

    expect(result).toEqual([{
      id: 'req-1',
      leagueId: 'league-1',
      driverId: 'driver-1',
      requestedAt: expect.any(Date),
      message: 'msg',
      driver: { id: 'driver-1', name: 'Driver 1' },
    }]);
  });

  it('should approve league join request', async () => {
    mockApproveLeagueJoinRequestUseCase.execute.mockImplementation(async (params, presenter) => {
      presenter.present({ success: true, message: 'Join request approved.' });
    });

    const result = await service.approveLeagueJoinRequest({ leagueId: 'league-1', requestId: 'req-1' });

    expect(result).toEqual({ success: true, message: 'Join request approved.' });
  });

  it('should reject league join request', async () => {
    const mockRejectUseCase = {
      execute: jest.fn().mockImplementation(async (params, presenter) => {
        presenter.present({ success: true, message: 'Join request rejected.' });
      }),
    } as any;

    service = new LeagueService(
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      mockRejectUseCase,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      mockLogger,
    );

    const result = await service.rejectLeagueJoinRequest({ requestId: 'req-1', leagueId: 'league-1' });

    expect(result).toEqual({ success: true, message: 'Join request rejected.' });
  });

  it('should remove league member', async () => {
    const mockRemoveUseCase = {
      execute: jest.fn().mockImplementation(async (params, presenter) => {
        presenter.present({ success: true });
      }),
    } as any;

    service = new LeagueService(
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      mockRemoveUseCase,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      {} as any,
      mockLogger,
    );

    const result = await service.removeLeagueMember({ leagueId: 'league-1', performerDriverId: 'performer-1', targetDriverId: 'driver-1' });

    expect(result).toEqual({ success: true });
  });
});