import 'dart:convert';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:userfront/core/services/auth_proxy_service.dart';
import 'package:userfront/core/services/auth_token_store.dart';
import 'package:userfront/core/services/http_client.dart';
import 'package:userfront/core/services/runtime_env.dart';

class LinkedRp {
  final String id;
  final String name;
  final String logo;
  final String url;
  final String initUrl;
  final bool autoLoginSupported;
  final String autoLoginUrl;
  final String status;
  final List<String> scopes;
  final DateTime? lastAuthenticatedAt;

  LinkedRp({
    required this.id,
    required this.name,
    required this.logo,
    required this.url,
    required this.initUrl,
    required this.autoLoginSupported,
    required this.autoLoginUrl,
    required this.status,
    required this.scopes,
    required this.lastAuthenticatedAt,
  });

  factory LinkedRp.fromJson(Map<String, dynamic> json) {
    final rawLastAuth = json['lastAuthenticatedAt']?.toString() ?? '';
    DateTime? parsedLastAuth;
    if (rawLastAuth.isNotEmpty) {
      try {
        parsedLastAuth = DateTime.parse(rawLastAuth).toLocal();
      } catch (_) {
        parsedLastAuth = null;
      }
    }

    return LinkedRp(
      id: json['id']?.toString() ?? '',
      name: json['name']?.toString() ?? '',
      logo: json['logo']?.toString() ?? '',
      url: json['url']?.toString() ?? '',
      initUrl: json['init_url']?.toString() ?? '',
      autoLoginSupported: json['auto_login_supported'] == true,
      autoLoginUrl: json['auto_login_url']?.toString() ?? '',
      status: json['status']?.toString() ?? 'unknown',
      scopes: (json['scopes'] as List?)?.whereType<String>().toList() ?? [],
      lastAuthenticatedAt: parsedLastAuth,
    );
  }
}

class LinkedRpsNotifier extends AsyncNotifier<List<LinkedRp>> {
  @override
  Future<List<LinkedRp>> build() async {
    return _fetchLinkedRps();
  }

  Future<List<LinkedRp>> _fetchLinkedRps() async {
    try {
      final baseUrl = runtimeBackendUrl();
      final url = Uri.parse('$baseUrl/api/v1/user/rp/linked');

      final useCookie = AuthTokenStore.usesCookie();
      final token = AuthTokenStore.getToken();

      final client = createHttpClient(withCredentials: useCookie);
      final headers = <String, String>{'Content-Type': 'application/json'};
      if (!useCookie && token != null) {
        headers['Authorization'] = 'Bearer $token';
      }

      final response = await client.get(url, headers: headers);
      client.close();

      if (response.statusCode != 200) {
        throw Exception('Failed to load linked rps: ${response.statusCode}');
      }

      final body = jsonDecode(response.body) as Map<String, dynamic>;
      final items = (body['items'] as List?) ?? [];

      return items
          .whereType<Map<String, dynamic>>()
          .map(LinkedRp.fromJson)
          .toList();
    } catch (e) {
      rethrow;
    }
  }

  Future<void> refresh() async {
    state = const AsyncLoading();
    state = await AsyncValue.guard(() => _fetchLinkedRps());
  }

  Future<void> revokeRp(String clientId) async {
    await AuthProxyService.revokeLinkedRp(clientId);
    await refresh();
  }
}

final linkedRpsProvider =
    AsyncNotifierProvider<LinkedRpsNotifier, List<LinkedRp>>(() {
      return LinkedRpsNotifier();
    });
