/// Tests unitaires pour CreateMember use case
library create_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/create_member.dart';
import 'package:unionflow_mobile_apps/features/members/data/models/membre_complete_model.dart';

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

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

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

  group('CreateMember Use Case', () {
    final tMemberData = MembreCompletModel(
      nom: 'Ndiaye',
      prenom: 'Fatou',
      email: 'fatou.ndiaye@example.com',
      telephone: '+221776543210',
      genre: Genre.femme,
      statut: StatutMembre.enAttente,
      dateNaissance: DateTime(1990, 7, 22),
      adresse: '45 Rue de la République, Dakar',
    );

    final tCreatedMember = MembreCompletModel(
      id: '456',
      nom: 'Ndiaye',
      prenom: 'Fatou',
      email: 'fatou.ndiaye@example.com',
      telephone: '+221776543210',
      genre: Genre.femme,
      statut: StatutMembre.enAttente,
      dateNaissance: DateTime(1990, 7, 22),
      adresse: '45 Rue de la République, Dakar',
    );

    test('should create new member successfully', () async {
      // Arrange
      when(mockRepository.createMembre(tMemberData))
          .thenAnswer((_) async => tCreatedMember);

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

      // Assert
      expect(result, equals(tCreatedMember));
      expect(result.id, equals('456'));
      expect(result.nom, equals('Ndiaye'));
      expect(result.email, equals('fatou.ndiaye@example.com'));
      verify(mockRepository.createMembre(tMemberData));
      verifyNoMoreInteractions(mockRepository);
    });

    test('should create member with minimal required fields', () async {
      // Arrange
      final minimalMember = MembreCompletModel(
        nom: 'Ba',
        prenom: 'Moussa',
        email: 'moussa.ba@example.com',
        genre: Genre.homme,
        statut: StatutMembre.enAttente,
      );
      final createdMinimal = MembreCompletModel(
        id: '789',
        nom: 'Ba',
        prenom: 'Moussa',
        email: 'moussa.ba@example.com',
        genre: Genre.homme,
        statut: StatutMembre.enAttente,
      );
      when(mockRepository.createMembre(minimalMember))
          .thenAnswer((_) async => createdMinimal);

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

      // Assert
      expect(result.id, equals('789'));
      expect(result.nom, equals('Ba'));
    });

    test('should throw exception when email already exists', () async {
      // Arrange
      when(mockRepository.createMembre(any))
          .thenThrow(Exception('Email déjà utilisé'));

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

    test('should throw exception when validation fails', () async {
      // Arrange
      final invalidMember = MembreCompletModel(
        nom: '',
        prenom: 'Test',
        email: 'invalid-email',
        genre: Genre.autre,
        statut: StatutMembre.enAttente,
      );
      when(mockRepository.createMembre(any))
          .thenThrow(Exception('Données invalides'));

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