/// Tests unitaires pour GetMemberById use case
library get_member_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/members/domain/repositories/membre_repository.dart';
import 'package:unionflow_mobile_apps/features/members/domain/usecases/get_member_by_id.dart';
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart';

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

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

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

  group('GetMemberById Use Case', () {
    const tMemberId = '123';
    final tMember = MembreCompletModel(
      id: tMemberId,
      nom: 'Diallo',
      prenom: 'Amadou',
      email: 'amadou.diallo@example.com',
      telephone: '+221771234567',
      genre: Genre.homme,
      statut: StatutMembre.actif,
      dateNaissance: DateTime(1985, 3, 15),
      adresse: '12 Avenue Bourguiba, Dakar',
      profession: 'Ingénieur Informatique',
    );

    test('should return member details by ID', () async {
      // Arrange
      when(mockRepository.getMembreById(tMemberId))
          .thenAnswer((_) async => tMember);

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

      // Assert
      expect(result, equals(tMember));
      expect(result!.id, equals(tMemberId));
      expect(result.nom, equals('Diallo'));
      expect(result.prenom, equals('Amadou'));
      expect(result.email, equals('amadou.diallo@example.com'));
      verify(mockRepository.getMembreById(tMemberId));
      verifyNoMoreInteractions(mockRepository);
    });

    test('should return member with all optional fields populated', () async {
      // Arrange
      when(mockRepository.getMembreById(tMemberId))
          .thenAnswer((_) async => tMember);

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

      // Assert
      expect(result!.telephone, equals('+221771234567'));
      expect(result.dateNaissance, isNotNull);
      expect(result.adresse, equals('12 Avenue Bourguiba, Dakar'));
      expect(result.profession, equals('Ingénieur Informatique'));
    });

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

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

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

    test('should throw exception when repository fails', () async {
      // Arrange
      when(mockRepository.getMembreById(any))
          .thenThrow(Exception('Membre non trouvé'));

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