/// Tests unitaires pour GetMyRegistrations use case
library get_my_registrations_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_my_registrations.dart';
import 'package:unionflow_mobile_apps/features/events/data/models/evenement_model.dart';
import 'package:unionflow_mobile_apps/features/events/data/repositories/evenement_repository_impl.dart';

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

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

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

  group('GetMyRegistrations Use Case', () {
    final tRegisteredEvents = [
      EvenementModel(
        id: 1,
        titre: 'Formation Leadership',
        dateDebut: DateTime(2024, 12, 20, 9, 0),
        dateFin: DateTime(2024, 12, 20, 17, 0),
        type: TypeEvenement.formation,
        statut: StatutEvenement.confirme,
        inscriptionRequise: true,
        participantsActuels: 15,
      ),
      EvenementModel(
        id: 2,
        titre: 'Séminaire Annuel',
        dateDebut: DateTime(2025, 1, 10, 14, 0),
        dateFin: DateTime(2025, 1, 10, 18, 0),
        type: TypeEvenement.seminaire,
        statut: StatutEvenement.planifie,
        inscriptionRequise: true,
        participantsActuels: 30,
      ),
    ];

    final tSearchResult = EvenementSearchResult(
      evenements: tRegisteredEvents,
      total: 2,
      page: 0,
      size: 20,
      totalPages: 1,
    );

    test('should return list of registered events', () async {
      // Arrange
      when(mockRepository.getEvenementsAVenir(page: anyNamed('page'), size: anyNamed('size')))
          .thenAnswer((_) async => tSearchResult);

      // Act
      final result = await useCase(page: 0, size: 20);

      // Assert
      expect(result, equals(tSearchResult));
      expect(result.evenements.length, equals(2));
      expect(result.total, equals(2));
      verify(mockRepository.getEvenementsAVenir(page: 0, size: 20));
      verifyNoMoreInteractions(mockRepository);
    });

    test('should return events with custom page size', () async {
      // Arrange
      final smallResult = EvenementSearchResult(
        evenements: [tRegisteredEvents[0]],
        total: 2,
        page: 0,
        size: 1,
        totalPages: 2,
      );
      when(mockRepository.getEvenementsAVenir(page: 0, size: 1))
          .thenAnswer((_) async => smallResult);

      // Act
      final result = await useCase(page: 0, size: 1);

      // Assert
      expect(result.evenements.length, equals(1));
      expect(result.size, equals(1));
    });

    test('should return empty result when no registrations', () async {
      // Arrange
      final emptyResult = EvenementSearchResult(
        evenements: [],
        total: 0,
        page: 0,
        size: 20,
        totalPages: 0,
      );
      when(mockRepository.getEvenementsAVenir(page: anyNamed('page'), size: anyNamed('size')))
          .thenAnswer((_) async => emptyResult);

      // Act
      final result = await useCase(page: 0, size: 20);

      // Assert
      expect(result.evenements, isEmpty);
      expect(result.total, equals(0));
    });

    test('should throw exception when repository fails', () async {
      // Arrange
      when(mockRepository.getEvenementsAVenir(page: anyNamed('page'), size: anyNamed('size')))
          .thenThrow(Exception('Network error'));

      // Act & Assert
      expect(() => useCase(page: 0, size: 20), throwsException);
    });
  });
}
