import 'package:afterwork/data/services/category_service.dart';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  group('CategoryService', () {
    late CategoryService categoryService;

    setUp(() {
      categoryService = CategoryService();
    });

    test('should load categories from JSON file', () async {
      // Arrange
      const jsonString = '{"categories":{"sport":["Football","Basketball","Tennis"],"culture":["Cinéma","Théâtre","Musique"],"food":["Restaurant","Bar","Café"]}}';

      // Setup mock handler before creating service
      TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
          .setMockMethodCallHandler(
        const MethodChannel('flutter/assets'),
        (MethodCall methodCall) async {
          if (methodCall.method == 'loadString') {
            final String assetPath = methodCall.arguments as String;
            if (assetPath == 'lib/assets/json/event_categories.json') {
              return jsonString;
            }
          }
          return null;
        },
      );

      // Recreate service to ensure it uses the mocked handler
      categoryService = CategoryService();

      // Act
      final result = await categoryService.loadCategories();

      // Assert
      expect(result, isA<Map<String, List<String>>>());
      expect(result.containsKey('sport'), isTrue);
      expect(result.containsKey('culture'), isTrue);
      expect(result.containsKey('food'), isTrue);
      expect(result['sport'], contains('Football'));
      expect(result['culture'], contains('Cinéma'));
    });

    test('should throw exception when JSON file is invalid', () async {
      // Arrange
      TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
          .setMockMethodCallHandler(
        const MethodChannel('flutter/assets'),
        (MethodCall methodCall) async {
          if (methodCall.method == 'loadString') {
            return 'invalid json';
          }
          return null;
        },
      );

      // Act & Assert
      expect(
        () => categoryService.loadCategories(),
        throwsA(isA<Exception>()),
      );
    });

    test('should throw exception when file is not found', () async {
      // Arrange
      TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger
          .setMockMethodCallHandler(
        const MethodChannel('flutter/assets'),
        (MethodCall methodCall) async {
          if (methodCall.method == 'loadString') {
            throw PlatformException(code: 'file_not_found');
          }
          return null;
        },
      );

      // Act & Assert
      expect(
        () => categoryService.loadCategories(),
        throwsA(isA<Exception>()),
      );
    });
  });
}

