import { describe, it, expect, vi, beforeEach } from 'vitest';
import { TeamJoinService } from './TeamJoinService';
import type { TeamsApiClient } from '@/lib/api/teams/TeamsApiClient';

describe('TeamJoinService', () => {
  let service: TeamJoinService;
  let mockApiClient: TeamsApiClient;

  beforeEach(() => {
    mockApiClient = {
      getJoinRequests: vi.fn(),
    } as any;

    service = new TeamJoinService(mockApiClient);
  });

  describe('getJoinRequests', () => {
    it('should return view models for join requests', async () => {
      const mockDto = {
        requests: [
          {
            requestId: 'request-1',
            teamId: 'team-1',
            driverId: 'driver-1',
            driverName: 'Driver One',
            status: 'pending',
            requestedAt: '2023-01-01T00:00:00Z',
            avatarUrl: 'https://example.com/avatar-1.jpg',
          },
          {
            requestId: 'request-2',
            teamId: 'team-1',
            driverId: 'driver-2',
            driverName: 'Driver Two',
            status: 'pending',
            requestedAt: '2023-01-02T00:00:00Z',
            avatarUrl: 'https://example.com/avatar-2.jpg',
          },
        ],
      };

      mockApiClient.getJoinRequests = vi.fn().mockResolvedValue(mockDto);

      const result = await service.getJoinRequests('team-1', 'user-1', true);

      expect(mockApiClient.getJoinRequests).toHaveBeenCalledWith('team-1');
      expect(result.isOk()).toBe(true);
      const viewModels = result.unwrap();
      expect(viewModels).toHaveLength(2);

      const first = viewModels[0];
      const second = viewModels[1];

      expect(first).toBeDefined();
      expect(second).toBeDefined();

      expect(first!.id).toBe('request-1');
      expect(first!.canApprove).toBe(true);
      expect(second!.id).toBe('request-2');
      expect(second!.canApprove).toBe(true);
    });

    it('should pass correct parameters to view model constructor', async () => {
      const mockDto = {
        requests: [
          {
            requestId: 'request-1',
            teamId: 'team-1',
            driverId: 'driver-1',
            driverName: 'Driver One',
            status: 'pending',
            requestedAt: '2023-01-01T00:00:00Z',
            avatarUrl: 'https://example.com/avatar-1.jpg',
          },
        ],
      };

      mockApiClient.getJoinRequests = vi.fn().mockResolvedValue(mockDto);

      const result = await service.getJoinRequests('team-1', 'user-1', false);

      expect(result.isOk()).toBe(true);
      const viewModels = result.unwrap();
      expect(viewModels[0]).toBeDefined();
      expect(viewModels[0]!.canApprove).toBe(false);
    });
  });

  describe('approveJoinRequest', () => {
    it('should throw not implemented error', async () => {
      const result = await service.approveJoinRequest();
      expect(result.isErr()).toBe(true);
      expect(result.getError().message).toBe('Not implemented: API endpoint for approving join requests');
    });
  });

  describe('rejectJoinRequest', () => {
    it('should throw not implemented error', async () => {
      const result = await service.rejectJoinRequest();
      expect(result.isErr()).toBe(true);
      expect(result.getError().message).toBe('Not implemented: API endpoint for rejecting join requests');
    });
  });
});