/// Tests unitaires pour GetEventById use case
library get_event_by_id_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_by_id.dart';
import 'package:unionflow_mobile_apps/features/events/data/models/evenement_model.dart';

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

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

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

  group('GetEventById Use Case', () {
    const tEventId = 'event123';
    final tEvent = EvenementModel(
      id: 123,
      titre: 'Assemblée Générale 2024',
      description: 'Assemblée générale annuelle de l\'organisation',
      dateDebut: DateTime(2024, 12, 15, 14, 0),
      dateFin: DateTime(2024, 12, 15, 18, 0),
      lieu: 'Salle des Congrès',
      adresse: '123 Rue de la République',
      ville: 'Dakar',
      type: TypeEvenement.assembleeGenerale,
      statut: StatutEvenement.confirme,
      priorite: PrioriteEvenement.haute,
      participantsActuels: 45,
      maxParticipants: 100,
      estPublic: true,
      inscriptionRequise: true,
    );

    test('should return event by id', () async {
      // Arrange
      when(mockRepository.getEvenementById(tEventId))
          .thenAnswer((_) async => tEvent);

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

      // Assert
      expect(result, equals(tEvent));
      expect(result?.id, equals(123));
      expect(result?.titre, equals('Assemblée Générale 2024'));
      verify(mockRepository.getEvenementById(tEventId));
      verifyNoMoreInteractions(mockRepository);
    });

    test('should return event with all details populated', () async {
      // Arrange
      when(mockRepository.getEvenementById(tEventId))
          .thenAnswer((_) async => tEvent);

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

      // Assert
      expect(result?.lieu, isNotNull);
      expect(result?.adresse, isNotNull);
      expect(result?.participantsActuels, equals(45));
      expect(result?.maxParticipants, equals(100));
    });

    test('should return null when event not found', () async {
      // Arrange
      when(mockRepository.getEvenementById(any))
          .thenAnswer((_) async => null);

      // Act
      final result = await useCase('nonexistent');

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

    test('should throw exception when repository fails', () async {
      // Arrange
      when(mockRepository.getEvenementById(any))
          .thenThrow(Exception('Database error'));

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