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<String, dynamic> 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<String, dynamic> json) {
    return ConfigValueItem(
      value: json['value'],
      type: json['type'] as String? ?? 'string',
      description: json['description'] as String?,
    );
  }
}

class ConfigurationService {
  static Future<Map<String, String>> _headers() async {
    final token = await TokenService.getToken();
    return token != null
        ? ApiConfig.authHeaders(token)
        : Map<String, String>.from(ApiConfig.headers);
  }

  static String? _toStr(dynamic v) {
    if (v == null) return null;
    if (v is String) return v;
    return v.toString();
  }

  /// GET /api/v1/configuration/setup/status
  static Future<bool> 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);
    final val = data['data']?['setupCompleted'];
    if (val is bool) return val;
    if (val is String) return val.toLowerCase() == 'true' || val == '1';
    if (val is int) return val == 1;
    return true; // Par défaut on considère configuré pour ne pas bloquer
  }

  /// GET /api/v1/configuration (toutes les configs)
  static Future<List<ConfigItem>> getAll() async {
    final response = await http.get(
      Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configuration}'),
      headers: await _headers(),
    );
    if (response.statusCode != 200) {
      final err = jsonDecode(response.body) as Map<String, dynamic>?;
      throw Exception(_toStr(err?['message']) ?? 'Erreur chargement configuration');
    }
    final data = jsonDecode(response.body);
    final list = data['data'] as List<dynamic>? ?? [];
    return list.map((e) => ConfigItem.fromJson(e as Map<String, dynamic>)).toList();
  }

  /// GET /api/v1/configuration/:category
  static Future<Map<String, ConfigValueItem>> getByCategory(String category) async {
    final response = await http.get(
      Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configuration}/$category'),
      headers: await _headers(),
    );
    if (response.statusCode != 200) {
      final err = jsonDecode(response.body) as Map<String, dynamic>?;
      throw Exception(_toStr(err?['message']) ?? 'Erreur chargement configuration');
    }
    final data = jsonDecode(response.body);
    final map = data['data'] as Map<String, dynamic>? ?? {};
    return map.map((k, v) => MapEntry(k, ConfigValueItem.fromJson(v as Map<String, dynamic>)));
  }

  /// PATCH /api/v1/configuration/bulk
  static Future<void> updateBulk(Map<String, dynamic> body) async {
    final response = await http.patch(
      Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configurationBulk}'),
      headers: await _headers(),
      body: jsonEncode(body),
    );
    if (response.statusCode != 200 && response.statusCode != 201) {
      final err = jsonDecode(response.body) as Map<String, dynamic>?;
      final msg = err != null ? (_toStr(err['error']) ?? _toStr(err['message'])) : null;
      throw Exception(msg ?? 'Erreur lors de la sauvegarde');
    }
  }

  /// POST /api/v1/configuration/test-smtp
  static Future<String> 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<String, dynamic>?;
    if ((response.statusCode == 200 || response.statusCode == 201) && (data?['success'] == true)) {
      return _toStr(data?['message']) ?? 'Test SMTP réussi.';
    }
    final msg = data != null ? (_toStr(data['error']) ?? _toStr(data['message'])) : null;
    throw Exception(msg ?? 'Échec du test SMTP');
  }

  /// POST /api/v1/configuration/setup/complete (après première config)
  static Future<void> completeSetup() async {
    final response = await http.post(
      Uri.parse('${ApiConfig.baseUrl}${ApiConfig.configurationSetupComplete}'),
      headers: await _headers(),
    );
    if (response.statusCode != 200 && response.statusCode != 201) {
      final err = jsonDecode(response.body) as Map<String, dynamic>?;
      final msg = err != null ? (_toStr(err['error']) ?? _toStr(err['message'])) : null;
      throw Exception(msg ?? 'Erreur finalisation configuration');
    }
  }
}
