/// Tests unitaires pour GetEventParticipants use case
library get_event_participants_test;

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:unionflow_mobile_apps/features/events/domain/repositories/evenement_repository.dart';
import 'package:unionflow_mobile_apps/features/events/domain/usecases/get_event_participants.dart';

@GenerateMocks([IEvenementRepository])
import 'get_event_participants_test.mocks.dart';

void main() {
  late GetEventParticipants useCase;
  late MockIEvenementRepository mockRepository;

  setUp(() {
    mockRepository = MockIEvenementRepository();
    useCase = GetEventParticipants(mockRepository);
  });

  group('GetEventParticipants Use Case', () {
    const tEventId = 'event123';
    final tParticipantsList = [
      {
        'id': 'membre1',
        'nom': 'Dupont',
        'prenom': 'Jean',
        'email': 'jean.dupont@example.com',
        'dateInscription': '2024-11-01T10:00:00Z',
        'statut': 'CONFIRME',
      },
      {
        'id': 'membre2',
        'nom': 'Martin',
        'prenom': 'Marie',
        'email': 'marie.martin@example.com',
        'dateInscription': '2024-11-02T14:00:00Z',
        'statut': 'EN_ATTENTE',
      },
      {
        'id': 'membre3',
        'nom': 'Diallo',
        'prenom': 'Amadou',
        'email': 'amadou.diallo@example.com',
        'dateInscription': '2024-11-03T09:00:00Z',
        'statut': 'CONFIRME',
      },
    ];

    test('should return list of event participants', () async {
      // Arrange
      when(mockRepository.getParticipants(tEventId))
          .thenAnswer((_) async => tParticipantsList);

      // Act
      final result = await useCase(tEventId);

      // Assert
      expect(result, equals(tParticipantsList));
      expect(result.length, equals(3));
      expect(result[0]['nom'], equals('Dupont'));
      expect(result[0]['statut'], equals('CONFIRME'));
      verify(mockRepository.getParticipants(tEventId));
      verifyNoMoreInteractions(mockRepository);
    });

    test('should return participants with different statuses', () async {
      // Arrange
      when(mockRepository.getParticipants(tEventId))
          .thenAnswer((_) async => tParticipantsList);

      // Act
      final result = await useCase(tEventId);

      // Assert
      expect(result.where((p) => p['statut'] == 'CONFIRME').length, equals(2));
      expect(result.where((p) => p['statut'] == 'EN_ATTENTE').length, equals(1));
    });

    test('should return empty list when no participants', () async {
      // Arrange
      when(mockRepository.getParticipants(tEventId))
          .thenAnswer((_) async => []);

      // Act
      final result = await useCase(tEventId);

      // Assert
      expect(result, isEmpty);
    });

    test('should throw exception when event not found', () async {
      // Arrange
      when(mockRepository.getParticipants(any))
          .thenThrow(Exception('Événement non trouvé'));

      // Act & Assert
      expect(() => useCase('nonexistent'), throwsException);
    });
  });
}
