/// BLoC pour la gestion des paramètres système (Clean Architecture)
library system_settings_bloc;

import 'package:dio/dio.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:injectable/injectable.dart';
import '../../domain/usecases/get_settings.dart';
import '../../domain/usecases/update_settings.dart';
import '../../domain/usecases/get_cache_stats.dart';
import '../../domain/usecases/clear_cache.dart' as uc;
import '../../domain/usecases/reset_settings.dart';
import '../../domain/repositories/system_config_repository.dart';
import 'system_settings_event.dart';
import 'system_settings_state.dart';

@injectable
class SystemSettingsBloc extends Bloc<SystemSettingsEvent, SystemSettingsState> {
  final GetSettings _getSettings;
  final UpdateSettings _updateSettings;
  final GetCacheStats _getCacheStats;
  final uc.ClearCache _clearCache;
  final ResetSettings _resetSettings;
  final ISystemConfigRepository _repository; // Pour méthodes non-couvertes (metrics, test DB, test email)

  SystemSettingsBloc(
    this._getSettings,
    this._updateSettings,
    this._getCacheStats,
    this._clearCache,
    this._resetSettings,
    this._repository,
  ) : super(SystemSettingsInitial()) {
    on<LoadSystemConfig>(_onLoadSystemConfig);
    on<UpdateSystemConfig>(_onUpdateSystemConfig);
    on<LoadCacheStats>(_onLoadCacheStats);
    on<LoadSystemMetrics>(_onLoadSystemMetrics);
    on<ClearCache>(_onClearCache);
    on<TestDatabaseConnection>(_onTestDatabaseConnection);
    on<TestEmailConfiguration>(_onTestEmailConfiguration);
    on<ResetSystemConfig>(_onResetSystemConfig);
    on<OptimizeDatabase>(_onOptimizeDatabase);
    on<ForceGlobalLogout>(_onForceGlobalLogout);
    on<CleanupSessions>(_onCleanupSessions);
    on<CleanOldLogs>(_onCleanOldLogs);
    on<PurgeExpiredData>(_onPurgeExpiredData);
    on<AnalyzePerformance>(_onAnalyzePerformance);
    on<CreateBackup>(_onCreateBackup);
    on<ScheduleMaintenance>(_onScheduleMaintenance);
    on<EmergencyMaintenance>(_onEmergencyMaintenance);
    on<CheckUpdates>(_onCheckUpdates);
    on<ExportLogs>(_onExportLogs);
    on<GenerateUsageReport>(_onGenerateUsageReport);
    on<GenerateAuditReport>(_onGenerateAuditReport);
    on<ExportGDPRData>(_onExportGDPRData);
  }

  Future<void> _onLoadSystemConfig(
    LoadSystemConfig event,
    Emitter<SystemSettingsState> emit,
  ) async {
    emit(SystemSettingsLoading());
    try {
      final config = await _getSettings(); // ✅ Use case
      emit(SystemConfigLoaded(config));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur de chargement: ${e.toString()}'));
    }
  }

  Future<void> _onUpdateSystemConfig(
    UpdateSystemConfig event,
    Emitter<SystemSettingsState> emit,
  ) async {
    emit(SystemSettingsLoading());
    try {
      final config = await _updateSettings(event.config); // ✅ Use case
      emit(SystemConfigLoaded(config));
      emit(const SystemSettingsSuccess('Configuration mise à jour'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur de mise à jour: ${e.toString()}'));
    }
  }

  Future<void> _onLoadCacheStats(
    LoadCacheStats event,
    Emitter<SystemSettingsState> emit,
  ) async {
    emit(SystemSettingsLoading());
    try {
      final stats = await _getCacheStats(); // ✅ Use case
      emit(CacheStatsLoaded(stats));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur de chargement: ${e.toString()}'));
    }
  }

  Future<void> _onLoadSystemMetrics(
    LoadSystemMetrics event,
    Emitter<SystemSettingsState> emit,
  ) async {
    emit(SystemSettingsLoading());
    try {
      final metrics = await _repository.getMetrics();
      emit(SystemMetricsLoaded(metrics));
    } catch (e) {
      emit(SystemSettingsError('Erreur de chargement des métriques: ${e.toString()}'));
    }
  }

  Future<void> _onClearCache(
    ClearCache event,
    Emitter<SystemSettingsState> emit,
  ) async {
    emit(SystemSettingsLoading());
    try {
      await _clearCache(); // ✅ Use case
      emit(const SystemSettingsSuccess('Cache vidé avec succès'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onTestDatabaseConnection(
    TestDatabaseConnection event,
    Emitter<SystemSettingsState> emit,
  ) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.testDatabase();
      final success = result['success'] as bool? ?? false;
      final message = result['message'] as String? ?? 'Test terminé';
      if (success) {
        emit(SystemSettingsSuccess(message));
      } else {
        emit(SystemSettingsError(message));
      }
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur de test: ${e.toString()}'));
    }
  }

  Future<void> _onTestEmailConfiguration(
    TestEmailConfiguration event,
    Emitter<SystemSettingsState> emit,
  ) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.testEmail();
      final success = result['success'] as bool? ?? false;
      final message = result['message'] as String? ?? 'Test terminé';
      if (success) {
        emit(SystemSettingsSuccess(message));
      } else {
        emit(SystemSettingsError(message));
      }
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur de test: ${e.toString()}'));
    }
  }

  /// Réinitialise la configuration système aux valeurs par défaut
  Future<void> _onResetSystemConfig(
    ResetSystemConfig event,
    Emitter<SystemSettingsState> emit,
  ) async {
    emit(SystemSettingsLoading());
    try {
      final config = await _resetSettings(); // ✅ Use case
      emit(SystemConfigLoaded(config));
      emit(const SystemSettingsSuccess('Configuration réinitialisée'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur de réinitialisation: ${e.toString()}'));
    }
  }

  Future<void> _onOptimizeDatabase(OptimizeDatabase event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.optimizeDatabase();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Base de données optimisée'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onForceGlobalLogout(ForceGlobalLogout event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.forceGlobalLogout();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Déconnexion globale déclenchée'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onCleanupSessions(CleanupSessions event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.cleanupSessions();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Sessions nettoyées'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onCleanOldLogs(CleanOldLogs event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.cleanOldLogs();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Logs nettoyés'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onPurgeExpiredData(PurgeExpiredData event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.purgeExpiredData();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Données purgées'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onAnalyzePerformance(AnalyzePerformance event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.analyzePerformance();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Analyse terminée'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onCreateBackup(CreateBackup event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.createBackup();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Sauvegarde créée'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onScheduleMaintenance(ScheduleMaintenance event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.scheduleMaintenance(scheduledAt: event.scheduledAt, reason: event.reason);
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Maintenance planifiée'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onEmergencyMaintenance(EmergencyMaintenance event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.emergencyMaintenance();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Maintenance d\'urgence activée'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onCheckUpdates(CheckUpdates event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.checkUpdates();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Vérification terminée'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onExportLogs(ExportLogs event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.exportLogs();
      final count = result['count'] as int? ?? 0;
      emit(SystemSettingsSuccess('$count log(s) exporté(s)'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onGenerateUsageReport(GenerateUsageReport event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.generateUsageReport();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Rapport généré'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onGenerateAuditReport(GenerateAuditReport event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.generateAuditReport();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Rapport d\'audit généré'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }

  Future<void> _onExportGDPRData(ExportGDPRData event, Emitter<SystemSettingsState> emit) async {
    emit(SystemSettingsLoading());
    try {
      final result = await _repository.exportGDPRData();
      emit(SystemSettingsSuccess(result['message'] as String? ?? 'Export RGPD initié'));
    } catch (e) {
      if (e is DioException && e.type == DioExceptionType.cancel) return;
      emit(SystemSettingsError('Erreur: ${e.toString()}'));
    }
  }
}
