import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import { beforeEach, describe, expect, it, vi, type Mock } from 'vitest';
import type { LeagueMembershipRepository } from '../../domain/repositories/LeagueMembershipRepository';
import {
    RejectLeagueJoinRequestUseCase,
} from './RejectLeagueJoinRequestUseCase';

describe('RejectLeagueJoinRequestUseCase', () => {
  let leagueMembershipRepository: {
    getJoinRequests: Mock;
    removeJoinRequest: Mock;
  };

  beforeEach(() => {
    leagueMembershipRepository = {
      getJoinRequests: vi.fn(),
      removeJoinRequest: vi.fn(),
    };
  });

  it('reject removes request only', async () => {
    const useCase = new RejectLeagueJoinRequestUseCase(leagueMembershipRepository as unknown as LeagueMembershipRepository);

    leagueMembershipRepository.getJoinRequests.mockResolvedValue([
      { id: 'jr-1', leagueId: 'league-1', driverId: 'driver-1' },
    ]);

    const result = await useCase.execute(
      { leagueId: 'league-1', joinRequestId: 'jr-1' },
    );

    expect(result.isOk()).toBe(true);
    expect(leagueMembershipRepository.removeJoinRequest).toHaveBeenCalledWith('jr-1');
    });

  it('reject returns error when request missing', async () => {
    const useCase = new RejectLeagueJoinRequestUseCase(leagueMembershipRepository as unknown as LeagueMembershipRepository);

    leagueMembershipRepository.getJoinRequests.mockResolvedValue([]);

    const result = await useCase.execute(
      { leagueId: 'league-1', joinRequestId: 'jr-404' },
    );

    expect(result.isErr()).toBe(true);
    const err = result.unwrapErr() as ApplicationErrorCode<'JOIN_REQUEST_NOT_FOUND'>;
    expect(err.code).toBe('JOIN_REQUEST_NOT_FOUND');
    expect(leagueMembershipRepository.removeJoinRequest).not.toHaveBeenCalled();
  });
});
