/// Tests unitaires pour UpdateMember use case
library update_member_test;

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:unionflow_mobile_apps/features/members/domain/repositories/membre_repository.dart';
import 'package:unionflow_mobile_apps/features/members/domain/usecases/update_member.dart';
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart';

@GenerateMocks([IMembreRepository])
import 'update_member_test.mocks.dart';

void main() {
  late UpdateMember useCase;
  late MockIMembreRepository mockRepository;

  setUp(() {
    mockRepository = MockIMembreRepository();
    useCase = UpdateMember(mockRepository);
  });

  group('UpdateMember Use Case', () {
    const tMemberId = '123';
    final tUpdatedData = MembreCompletModel(
      id: tMemberId,
      nom: 'Diallo',
      prenom: 'Amadou',
      email: 'amadou.diallo.updated@example.com',
      telephone: '+221771112222',
      genre: Genre.homme,
      statut: StatutMembre.actif,
      profession: 'Directeur IT',
    );

    final tUpdatedMember = MembreCompletModel(
      id: tMemberId,
      nom: 'Diallo',
      prenom: 'Amadou',
      email: 'amadou.diallo.updated@example.com',
      telephone: '+221771112222',
      genre: Genre.homme,
      statut: StatutMembre.actif,
      profession: 'Directeur IT',
    );

    test('should update member successfully', () async {
      // Arrange
      when(mockRepository.updateMembre(tMemberId, tUpdatedData))
          .thenAnswer((_) async => tUpdatedMember);

      // Act
      final result = await useCase(tMemberId, tUpdatedData);

      // Assert
      expect(result, equals(tUpdatedMember));
      expect(result.email, equals('amadou.diallo.updated@example.com'));
      expect(result.telephone, equals('+221771112222'));
      expect(result.profession, equals('Directeur IT'));
      verify(mockRepository.updateMembre(tMemberId, tUpdatedData));
      verifyNoMoreInteractions(mockRepository);
    });

    test('should update member status to suspended', () async {
      // Arrange
      final suspendedMember = MembreCompletModel(
        id: tMemberId,
        nom: 'Diallo',
        prenom: 'Amadou',
        email: 'amadou.diallo@example.com',
        genre: Genre.homme,
        statut: StatutMembre.suspendu,
      );
      when(mockRepository.updateMembre(tMemberId, suspendedMember))
          .thenAnswer((_) async => suspendedMember);

      // Act
      final result = await useCase(tMemberId, suspendedMember);

      // Assert
      expect(result.statut, equals(StatutMembre.suspendu));
    });

    test('should throw exception when member not found', () async {
      // Arrange
      when(mockRepository.updateMembre(any, any))
          .thenThrow(Exception('Membre non trouvé'));

      // Act & Assert
      expect(() => useCase('999', tUpdatedData), throwsA(isA<Exception>()));
    });

    test('should throw exception when validation fails', () async {
      // Arrange
      when(mockRepository.updateMembre(any, any))
          .thenThrow(Exception('Email invalide'));

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