import 'package:flutter/foundation.dart';

/// Service de monitoring des performances de l'application
/// Permet de mesurer les temps de chargement et d'identifier les goulots d'étranglement
class PerformanceMonitor {
  static final Map<String, DateTime> _timings = {};
  static final Map<String, Duration> _results = {};
  static bool _enabled = kDebugMode; // Actif uniquement en mode debug par défaut

  /// Active ou désactive le monitoring
  static void setEnabled(bool enabled) {
    _enabled = enabled;
  }

  /// Démarre le chronomètre pour une opération
  static void start(String key) {
    if (!_enabled) return;
    _timings[key] = DateTime.now();
    if (kDebugMode) {
      print('[PerformanceMonitor] START: $key');
    }
  }

  /// Arrête le chronomètre et affiche le résultat
  static void end(String key) {
    if (!_enabled) return;

    if (_timings.containsKey(key)) {
      final duration = DateTime.now().difference(_timings[key]!);
      _results[key] = duration;
      _timings.remove(key);

      if (kDebugMode) {
        final color = _getColorForDuration(duration);
        print('[PerformanceMonitor] $color END: $key - ${duration.inMilliseconds}ms');
      }
    } else {
      if (kDebugMode) {
        print('[PerformanceMonitor] ⚠️ No start time found for: $key');
      }
    }
  }

  /// Marque un point dans le temps (pour mesurer des étapes)
  static void mark(String key) {
    if (!_enabled) return;

    if (kDebugMode) {
      print('[PerformanceMonitor] 📍 MARK: $key');
    }
  }

  /// Récupère les résultats de toutes les mesures
  static Map<String, Duration> getResults() {
    return Map.unmodifiable(_results);
  }

  /// Affiche un résumé des performances
  static void printSummary() {
    if (!_enabled || _results.isEmpty) return;

    print('\n${'=' * 60}');
    print('PERFORMANCE SUMMARY');
    print('=' * 60);

    // Trier par durée décroissante
    final sortedResults = _results.entries.toList()
      ..sort((a, b) => b.value.compareTo(a.value));

    for (var entry in sortedResults) {
      final color = _getColorForDuration(entry.value);
      final ms = entry.value.inMilliseconds;
      print('$color ${entry.key.padRight(40)} : ${ms.toString().padLeft(6)}ms');
    }

    final total = _results.values.fold<Duration>(
      Duration.zero,
      (sum, duration) => sum + duration,
    );
    print('=' * 60);
    print('TOTAL: ${total.inMilliseconds}ms');
    print('=' * 60 + '\n');
  }

  /// Réinitialise toutes les mesures
  static void reset() {
    _timings.clear();
    _results.clear();
    if (kDebugMode) {
      print('[PerformanceMonitor] 🔄 Reset');
    }
  }

  /// Retourne une couleur basée sur la durée (pour les logs)
  static String _getColorForDuration(Duration duration) {
    final ms = duration.inMilliseconds;
    if (ms < 100) return '🟢'; // Rapide
    if (ms < 500) return '🟡'; // Moyen
    if (ms < 1000) return '🟠'; // Lent
    return '🔴'; // Très lent
  }

  /// Mesure une opération asynchrone
  static Future<T> measure<T>(String key, Future<T> Function() operation) async {
    start(key);
    try {
      final result = await operation();
      end(key);
      return result;
    } catch (e) {
      end(key);
      rethrow;
    }
  }

  /// Mesure une opération synchrone
  static T measureSync<T>(String key, T Function() operation) {
    start(key);
    try {
      final result = operation();
      end(key);
      return result;
    } catch (e) {
      end(key);
      rethrow;
    }
  }
}

