import { describe, it, expect, vi, Mocked } from 'vitest';
import { DriverRegistrationService } from './DriverRegistrationService';
import { DriversApiClient } from '@/lib/api/drivers/DriversApiClient';
import { DriverRegistrationStatusViewModel } from '@/lib/view-models/DriverRegistrationStatusViewModel';

describe('DriverRegistrationService', () => {
  let mockApiClient: Mocked<DriversApiClient>;
  let service: DriverRegistrationService;

  beforeEach(() => {
    mockApiClient = {
      getRegistrationStatus: vi.fn(),
    } as Mocked<DriversApiClient>;

    service = new DriverRegistrationService(mockApiClient);
  });

  describe('getDriverRegistrationStatus', () => {
    it('should call apiClient.getRegistrationStatus and return DriverRegistrationStatusViewModel', async () => {
      const driverId = 'driver-123';
      const raceId = 'race-456';

      const mockDto = {
        isRegistered: true,
        raceId: 'race-456',
        driverId: 'driver-123',
      };

      mockApiClient.getRegistrationStatus.mockResolvedValue(mockDto);

      const result = await service.getDriverRegistrationStatus(driverId, raceId);

      expect(mockApiClient.getRegistrationStatus).toHaveBeenCalledWith(driverId, raceId);
      expect(result).toBeInstanceOf(DriverRegistrationStatusViewModel);
      expect(result.isRegistered).toBe(true);
      expect(result.raceId).toBe('race-456');
      expect(result.driverId).toBe('driver-123');
      expect(result.statusMessage).toBe('Registered for this race');
      expect(result.statusColor).toBe('green');
      expect(result.statusBadgeVariant).toBe('success');
      expect(result.registrationButtonText).toBe('Withdraw');
      expect(result.canRegister).toBe(false);
    });

    it('should handle unregistered driver', async () => {
      const driverId = 'driver-123';
      const raceId = 'race-456';

      const mockDto = {
        isRegistered: false,
        raceId: 'race-456',
        driverId: 'driver-123',
      };

      mockApiClient.getRegistrationStatus.mockResolvedValue(mockDto);

      const result = await service.getDriverRegistrationStatus(driverId, raceId);

      expect(result.isRegistered).toBe(false);
      expect(result.statusMessage).toBe('Not registered');
      expect(result.statusColor).toBe('red');
      expect(result.statusBadgeVariant).toBe('warning');
      expect(result.registrationButtonText).toBe('Register');
      expect(result.canRegister).toBe(true);
    });

    it('should throw error when apiClient.getRegistrationStatus fails', async () => {
      const driverId = 'driver-123';
      const raceId = 'race-456';

      const error = new Error('API call failed');
      mockApiClient.getRegistrationStatus.mockRejectedValue(error);

      await expect(service.getDriverRegistrationStatus(driverId, raceId)).rejects.toThrow('API call failed');
    });
  });
});