import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:recipe_flutter/core/api/api_client.dart';
import 'package:recipe_flutter/core/api/api_exception.dart';
import 'package:recipe_flutter/core/platform/platform_providers.dart';
import 'package:recipe_flutter/core/platform/token_storage.dart';
import 'package:recipe_flutter/features/profile/data/profile_repository.dart';
import 'package:recipe_flutter/features/profile/domain/user_profile.dart';

class _FakeApiClient extends ApiClient {
  dynamic _nextResponse;
  Exception? _nextError;

  void setResponse(dynamic response) {
    _nextResponse = response;
    _nextError = null;
  }

  void setError(Exception error) {
    _nextError = error;
    _nextResponse = null;
  }

  @override
  Future<dynamic> getJson(String path, {String? token}) async {
    if (_nextError != null) throw _nextError!;
    return _nextResponse;
  }

  @override
  Future<dynamic> patchJson(String path, {Object? body, String? token}) async {
    if (_nextError != null) throw _nextError!;
    return _nextResponse;
  }
}

/// In-memory token storage — no platform channels, no SharedPreferences.
class _FakeTokenStorage implements ITokenStorage {
  String? _token;

  @override
  Future<String?> getToken() async => _token;

  @override
  Future<void> saveToken(String token) async => _token = token;

  @override
  Future<void> deleteToken() async => _token = null;
}

void main() {
  late _FakeApiClient fakeClient;
  late ProviderContainer container;
  late ProfileRepository repo;

  final profileJson = {
    'id': 1,
    'username': 'testuser',
    'email': 'test@example.com',
    'role': 'user',
    'isPremium': false,
  };

  setUp(() {
    fakeClient = _FakeApiClient();
    container = ProviderContainer(
      overrides: [
        apiClientProvider.overrideWithValue(fakeClient),
        tokenStorageProvider.overrideWithValue(_FakeTokenStorage()),
      ],
    );
    repo = container.read(profileRepositoryProvider);
  });

  tearDown(() => container.dispose());

  group('getMe', () {
    test('returns UserProfile on success', () async {
      fakeClient.setResponse(profileJson);
      final result = await repo.getMe();
      expect(result, isA<UserProfile>());
      expect(result.username, 'testuser');
    });

    test('rethrows ApiException on failure', () async {
      fakeClient.setError(const ApiException(
        message: 'Unauthorized',
        type: ApiErrorType.unauthorized,
      ));
      expect(() => repo.getMe(), throwsA(isA<ApiException>()));
    });
  });

  group('updateMe', () {
    test('returns updated UserProfile on success', () async {
      final updated = {...profileJson, 'email': 'new@example.com'};
      fakeClient.setResponse(updated);
      final result = await repo.updateMe(email: 'new@example.com');
      expect(result.email, 'new@example.com');
    });
  });
}
