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

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

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

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

  group('UpdateEvent Use Case', () {
    const tEventId = 'event123';
    final tUpdatedEvent = EvenementModel(
      id: 123,
      titre: 'Assemblée Générale 2024 - Modifiée',
      description: 'Assemblée générale annuelle (mise à jour)',
      dateDebut: DateTime(2024, 12, 16, 14, 0),
      dateFin: DateTime(2024, 12, 16, 18, 0),
      lieu: 'Nouveau lieu',
      type: TypeEvenement.assembleeGenerale,
      statut: StatutEvenement.confirme,
    );

    test('should update event successfully', () async {
      // Arrange
      when(mockRepository.updateEvenement(tEventId, tUpdatedEvent))
          .thenAnswer((_) async => tUpdatedEvent);

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

      // Assert
      expect(result, equals(tUpdatedEvent));
      expect(result.titre, contains('Modifiée'));
      expect(result.lieu, equals('Nouveau lieu'));
      verify(mockRepository.updateEvenement(tEventId, tUpdatedEvent));
      verifyNoMoreInteractions(mockRepository);
    });

    test('should update event status', () async {
      // Arrange
      final statusUpdate = EvenementModel(
        id: 123,
        titre: 'Événement',
        dateDebut: DateTime(2024, 12, 15, 14, 0),
        dateFin: DateTime(2024, 12, 15, 18, 0),
        type: TypeEvenement.reunion,
        statut: StatutEvenement.annule,
      );
      when(mockRepository.updateEvenement(tEventId, statusUpdate))
          .thenAnswer((_) async => statusUpdate);

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

      // Assert
      expect(result.statut, equals(StatutEvenement.annule));
    });

    test('should update event capacity', () async {
      // Arrange
      final capacityUpdate = EvenementModel(
        id: 123,
        titre: 'Événement',
        dateDebut: DateTime(2024, 12, 15, 14, 0),
        dateFin: DateTime(2024, 12, 15, 18, 0),
        type: TypeEvenement.formation,
        statut: StatutEvenement.planifie,
        maxParticipants: 50,
        participantsActuels: 25,
      );
      when(mockRepository.updateEvenement(tEventId, capacityUpdate))
          .thenAnswer((_) async => capacityUpdate);

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

      // Assert
      expect(result.maxParticipants, equals(50));
      expect(result.participantsActuels, equals(25));
    });

    test('should throw exception when update fails', () async {
      // Arrange
      when(mockRepository.updateEvenement(any, any))
          .thenThrow(Exception('Update failed'));

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