import 'dart:convert'; import 'package:http/http.dart' as http; import 'api/api_config.dart'; import 'api/tokenService.dart'; /// Réponse GET /configuration (liste complète) class ConfigItem { final String cle; final String? valeur; final String type; final String? categorie; final String? description; ConfigItem({ required this.cle, this.valeur, required this.type, this.categorie, this.description, }); factory ConfigItem.fromJson(Map json) { return ConfigItem( cle: json['cle'] as String, valeur: json['valeur'] as String?, type: json['type'] as String? ?? 'string', categorie: json['categorie'] as String?, description: json['description'] as String?, ); } } /// Réponse GET /configuration/:category (objet clé -> { value, type, description }) class ConfigValueItem { final dynamic value; final String type; final String? description; ConfigValueItem({required this.value, required this.type, this.description}); factory ConfigValueItem.fromJson(Map json) { return ConfigValueItem( value: json['value'], type: json['type'] as String? ?? 'string', description: json['description'] as String?, ); } } class ConfigurationService { static Future> _headers() async { final token = await TokenService.getToken(); return token != null ? ApiConfig.authHeaders(token) : Map.from(ApiConfig.headers); } /// GET /api/v1/configuration/setup/status static Future getSetupStatus() async { final response = await http.get( Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configurationSetupStatus}'), headers: await _headers(), ); if (response.statusCode != 200) return true; final data = jsonDecode(response.body); return data['data']?['setupCompleted'] as bool? ?? true; } /// GET /api/v1/configuration (toutes les configs) static Future> getAll() async { final response = await http.get( Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configuration}'), headers: await _headers(), ); if (response.statusCode != 200) { throw Exception( (jsonDecode(response.body) as Map)['message'] ?? 'Erreur chargement configuration', ); } final data = jsonDecode(response.body); final list = data['data'] as List? ?? []; return list.map((e) => ConfigItem.fromJson(e as Map)).toList(); } /// GET /api/v1/configuration/:category static Future> getByCategory(String category) async { final response = await http.get( Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configuration}/$category'), headers: await _headers(), ); if (response.statusCode != 200) { throw Exception( (jsonDecode(response.body) as Map)['message'] ?? 'Erreur chargement configuration', ); } final data = jsonDecode(response.body); final map = data['data'] as Map? ?? {}; return map.map((k, v) => MapEntry(k, ConfigValueItem.fromJson(v as Map))); } /// PATCH /api/v1/configuration/bulk static Future updateBulk(Map body) async { final response = await http.patch( Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configurationBulk}'), headers: await _headers(), body: jsonEncode(body), ); if (response.statusCode != 200) { final err = jsonDecode(response.body) as Map; throw Exception(err['message'] ?? 'Erreur lors de la sauvegarde'); } } /// POST /api/v1/configuration/test-smtp static Future testSmtp(String testEmail) async { final response = await http.post( Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configurationTestSmtp}'), headers: await _headers(), body: jsonEncode({'testEmail': testEmail}), ); final data = jsonDecode(response.body) as Map; if (response.statusCode == 200 && data['success'] == true) { return data['message'] as String? ?? 'Test SMTP réussi.'; } throw Exception(data['error'] ?? data['message'] ?? 'Échec du test SMTP'); } /// POST /api/v1/configuration/setup/complete (après première config) static Future completeSetup() async { final response = await http.post( Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configurationSetupComplete}'), headers: await _headers(), ); if (response.statusCode != 200) { final err = jsonDecode(response.body) as Map; throw Exception(err['message'] ?? 'Erreur finalisation configuration'); } } }