/// Tests unitaires pour GetOrganizations use case
library get_organizations_test;

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:unionflow_mobile_apps/features/organizations/domain/repositories/organization_repository.dart';
import 'package:unionflow_mobile_apps/features/organizations/domain/usecases/get_organizations.dart';
import 'package:unionflow_mobile_apps/features/organizations/data/models/organization_model.dart';

@GenerateMocks([IOrganizationRepository])
import 'get_organizations_test.mocks.dart';

void main() {
  late GetOrganizations useCase;
  late MockIOrganizationRepository mockRepository;

  setUp(() {
    mockRepository = MockIOrganizationRepository();
    useCase = GetOrganizations(mockRepository);
  });

  group('GetOrganizations Use Case', () {
    final tOrganizationList = [
      OrganizationModel(
        id: 'org1',
        nom: 'Organisation Alpha',
        nomCourt: 'OA',
        email: 'contact@alpha.org',
        typeOrganisation: TypeOrganization.association,
        statut: StatutOrganization.active,
      ),
      OrganizationModel(
        id: 'org2',
        nom: 'Organisation Beta',
        nomCourt: 'OB',
        email: 'contact@beta.org',
        typeOrganisation: TypeOrganization.association,
        statut: StatutOrganization.active,
      ),
    ];

    test('should return list of organizations', () async {
      // Arrange
      when(mockRepository.getOrganizations(
        page: anyNamed('page'),
        size: anyNamed('size'),
        recherche: anyNamed('recherche'),
      )).thenAnswer((_) async => tOrganizationList);

      // Act
      final result = await useCase(page: 0, size: 20);

      // Assert
      expect(result, equals(tOrganizationList));
      expect(result.length, equals(2));
      verify(mockRepository.getOrganizations(page: 0, size: 20));
      verifyNoMoreInteractions(mockRepository);
    });

    test('should filter organizations by search query', () async {
      // Arrange
      final filteredList = [tOrganizationList[0]];
      when(mockRepository.getOrganizations(
        page: anyNamed('page'),
        size: anyNamed('size'),
        recherche: 'Alpha',
      )).thenAnswer((_) async => filteredList);

      // Act
      final result = await useCase(page: 0, size: 20, recherche: 'Alpha');

      // Assert
      expect(result.length, equals(1));
      expect(result.first.nom, contains('Alpha'));
      verify(mockRepository.getOrganizations(page: 0, size: 20, recherche: 'Alpha'));
    });

    test('should return empty list when no organizations exist', () async {
      // Arrange
      when(mockRepository.getOrganizations(
        page: anyNamed('page'),
        size: anyNamed('size'),
        recherche: anyNamed('recherche'),
      )).thenAnswer((_) async => []);

      // Act
      final result = await useCase(page: 0, size: 20);

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

    test('should throw exception when repository fails', () async {
      // Arrange
      when(mockRepository.getOrganizations(
        page: anyNamed('page'),
        size: anyNamed('size'),
        recherche: anyNamed('recherche'),
      )).thenThrow(Exception('Network error'));

      // Act & Assert
      expect(() => useCase(page: 0, size: 20), throwsException);
    });
  });
}
