import "dart:convert";
import "package:http/http.dart" as http;

/// Erreur levée par le client API (serveur injoignable ou réponse en échec).
class ApiException implements Exception {
  const ApiException(this.message);

  final String message;

  @override
  String toString() => message;
}

/// Point d'accès unique au backend : centralise l'URL de base, l'en-tête
/// d'authentification (simulée) et la gestion des erreurs.
class ApiClient {
  ApiClient._();

  static const String _baseUrl = "http://localhost:3000/api";
  static const String _utilisateurEmail = "lucas.martin@ensitech.eu";

  static Future<dynamic> get(String chemin) async {
    final uri = Uri.parse("$_baseUrl$chemin");

    late final http.Response reponse;
    try {
      reponse = await http.get(uri, headers: const {"x-user-email": _utilisateurEmail});
    } catch (_) {
      throw const ApiException(
        "Impossible de joindre le serveur. Vérifiez que le backend est démarré.",
      );
    }

    if (reponse.statusCode >= 200 && reponse.statusCode < 300) {
      return jsonDecode(reponse.body);
    }
    throw ApiException(_messageErreur(reponse));
  }

  static Future<dynamic> post(String chemin, Map<String, dynamic> body) async {
    final uri = Uri.parse("$_baseUrl$chemin");

    late final http.Response reponse;
    try {
      reponse = await http.post(
        uri,
        headers: const {
          "content-type": "application/json",
          "x-user-email": _utilisateurEmail,
        },
        body: jsonEncode(body),
      );
    } catch (_) {
      throw const ApiException(
        "Impossible de joindre le serveur. Vérifiez que le backend est démarré.",
      );
    }

    if (reponse.statusCode >= 200 && reponse.statusCode < 300) {
      return jsonDecode(reponse.body);
    }
    throw ApiException(_messageErreur(reponse));
  }

  static String _messageErreur(http.Response reponse) {
    try {
      final corps = jsonDecode(reponse.body);
      if (corps is Map && corps["error"] is Map) {
        final message = (corps["error"] as Map)["message"];
        if (message is String) {
          return message;
        }
      }
    } catch (_) {
      // Corps non-JSON : on retombe sur le code HTTP.
    }
    return "Erreur ${reponse.statusCode}";
  }
}
