import 'dart:convert'; import 'package:http/http.dart' as http; import 'package:shared_preferences/shared_preferences.dart'; import '../config.dart'; import '../models.dart'; import 'auth_service.dart'; /// Client de l'API GameManager (Bearer JWT pocket-id). class ApiService { ApiService(this._auth); final AuthService _auth; Future get baseUrl async { final prefs = await SharedPreferences.getInstance(); return prefs.getString('api_base') ?? Config.defaultApiBase; } Future setBaseUrl(String url) async { final prefs = await SharedPreferences.getInstance(); await prefs.setString('api_base', url.trim().replaceAll(RegExp(r'/$'), '')); } Future> _headers() async { final token = await _auth.validToken(); return {'Authorization': 'Bearer ${token ?? ''}', 'Accept': 'application/json'}; } Future> servers() async { final base = await baseUrl; final res = await http.get(Uri.parse('$base/api/servers'), headers: await _headers()); if (res.statusCode == 401) throw UnauthorizedException(); if (res.statusCode != 200) throw ApiException('Erreur ${res.statusCode}'); final list = jsonDecode(res.body) as List; return list.map((e) => GameServer.fromJson(e as Map)).toList(); } Future start(String id) => _action(id, 'start'); Future stop(String id) => _action(id, 'stop'); Future _action(String id, String action) async { final base = await baseUrl; final res = await http.post( Uri.parse('$base/api/servers/$id/$action'), headers: await _headers(), ); if (res.statusCode == 401) throw UnauthorizedException(); if (res.statusCode >= 400) throw ApiException('Action refusée (${res.statusCode})'); } Future iconUrl(String id) async => '${await baseUrl}/api/servers/$id/icon'; } class UnauthorizedException implements Exception {} class ApiException implements Exception { ApiException(this.message); final String message; @override String toString() => message; }