/// Repository pour la gestion de la configuration système
/// Implémentation avec l'API backend SystemResource
library system_config_repository_impl;

import 'package:dio/dio.dart';
import 'package:injectable/injectable.dart';
import 'package:unionflow_mobile_apps/core/network/api_client.dart';
import 'package:unionflow_mobile_apps/core/utils/logger.dart';
import '../../domain/repositories/system_config_repository.dart';
import '../models/system_config_model.dart';
import '../models/cache_stats_model.dart';
import '../models/system_metrics_model.dart';

/// Implémentation du repository de configuration système
@LazySingleton(as: ISystemConfigRepository)
class SystemConfigRepositoryImpl implements ISystemConfigRepository {
  final ApiClient _apiClient;
  static const String _base = '/api/system';

  SystemConfigRepositoryImpl(this._apiClient);

  @override
  Future<SystemConfigModel> getConfig() async {
    final response = await _apiClient.get('$_base/config');
    if (response.statusCode == 200) {
      return SystemConfigModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<SystemConfigModel> updateConfig(Map<String, dynamic> config) async {
    final response = await _apiClient.put('$_base/config', data: config);
    if (response.statusCode == 200) {
      return SystemConfigModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<CacheStatsModel> getCacheStats() async {
    final response = await _apiClient.get('$_base/cache/stats');
    if (response.statusCode == 200) {
      return CacheStatsModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<SystemMetricsModel> getMetrics() async {
    final response = await _apiClient.get('$_base/metrics');
    if (response.statusCode == 200) {
      return SystemMetricsModel.fromJson(response.data as Map<String, dynamic>);
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<void> clearCache() async {
    final response = await _apiClient.post('$_base/cache/clear');
    if (response.statusCode != 200) {
      throw Exception('Erreur ${response.statusCode}');
    }
  }

  @override
  Future<Map<String, dynamic>> testDatabase() async {
    final response = await _apiClient.post('$_base/test/database');
    if (response.statusCode == 200) {
      return response.data as Map<String, dynamic>;
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> testEmail() async {
    final response = await _apiClient.post('$_base/test/email');
    if (response.statusCode == 200) {
      return response.data as Map<String, dynamic>;
    }
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> optimizeDatabase() async {
    final response = await _apiClient.post('$_base/database/optimize');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> forceGlobalLogout() async {
    final response = await _apiClient.post('$_base/auth/logout-all');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> cleanupSessions() async {
    final response = await _apiClient.post('$_base/sessions/cleanup');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> cleanOldLogs() async {
    final response = await _apiClient.post('$_base/logs/cleanup');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> purgeExpiredData() async {
    final response = await _apiClient.post('$_base/data/purge');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> analyzePerformance() async {
    final response = await _apiClient.post('$_base/performance/analyze');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> createBackup() async {
    final response = await _apiClient.post('$_base/backup/create');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> scheduleMaintenance({String? scheduledAt, String? reason}) async {
    final queryParams = <String, String>{};
    if (scheduledAt != null) queryParams['scheduledAt'] = scheduledAt;
    if (reason != null) queryParams['reason'] = reason;
    final response = await _apiClient.post(
      '$_base/maintenance/schedule',
      queryParameters: queryParams.isNotEmpty ? queryParams : null,
    );
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> emergencyMaintenance() async {
    final response = await _apiClient.post('$_base/maintenance/emergency');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> checkUpdates() async {
    final response = await _apiClient.get('$_base/updates/check');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> exportLogs() async {
    final response = await _apiClient.get('$_base/logs/export');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> generateUsageReport() async {
    final response = await _apiClient.get('$_base/reports/usage');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> generateAuditReport() async {
    final response = await _apiClient.get('$_base/audit/report');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<Map<String, dynamic>> exportGDPRData() async {
    final response = await _apiClient.post('$_base/gdpr/export');
    if (response.statusCode == 200) return response.data as Map<String, dynamic>;
    throw Exception('Erreur ${response.statusCode}');
  }

  @override
  Future<SystemConfigModel> resetConfig() async {
    try {
      // Tente d'abord l'endpoint dédié pour le reset
      final response = await _apiClient.post('$_base/config/reset');
      if (response.statusCode == 200 || response.statusCode == 201) {
        return SystemConfigModel.fromJson(response.data as Map<String, dynamic>);
      }
      throw Exception('Erreur ${response.statusCode}');
    } on DioException catch (e, st) {
      if (e.type == DioExceptionType.cancel) rethrow;
      // Si l'endpoint n'existe pas (404), fallback : récupérer config par défaut via GET
      if (e.response?.statusCode == 404) {
        AppLogger.warning(
          'SystemConfigRepository: Endpoint /reset non disponible, fallback sur config par défaut',
        );
        // Alternative: Appeler un endpoint qui retourne la config par défaut
        // ou construire une config minimale côté client
        try {
          final defaultResponse = await _apiClient.get('$_base/config/default');
          if (defaultResponse.statusCode == 200) {
            return SystemConfigModel.fromJson(defaultResponse.data as Map<String, dynamic>);
          }
        } catch (_) {
          // Si même le default échoue, retourner une config minimale
          AppLogger.error(
            'SystemConfigRepository: resetConfig fallback échoué, config minimale retournée',
            error: e,
            stackTrace: st,
          );
          // Config minimale codée en dur pour éviter un crash total
          return SystemConfigModel.fromJson({
            'id': 'default',
            'appName': 'UnionFlow',
            'version': '1.0.0',
            'maintenance': false,
            'enableCache': true,
            'cacheExpirationMinutes': 30,
          });
        }
      }
      AppLogger.error('SystemConfigRepository: resetConfig échoué', error: e, stackTrace: st);
      rethrow;
    }
  }
}
