/// Logger centralisé pour l'application AfterWork.
///
/// Ce logger remplace tous les `print()` et `debugPrint()` pour offrir :
/// - Niveaux de log structurés (debug, info, warning, error)
/// - Filtrage par environnement (dev/prod)
/// - Formatage cohérent
/// - Support pour stack traces
///
/// **Usage:**
/// ```dart
/// AppLogger.i('Message informatif');
/// AppLogger.e('Erreur', error: e, stackTrace: stackTrace);
/// ```
import 'package:flutter/foundation.dart';
import '../constants/env_config.dart';

/// Niveaux de log disponibles.
enum LogLevel {
  /// Messages de débogage (développement uniquement).
  debug,

  /// Messages informatifs.
  info,

  /// Avertissements.
  warning,

  /// Erreurs.
  error,
}

/// Logger centralisé pour toute l'application.
///
/// Remplace tous les `print()` et `debugPrint()` pour une meilleure
/// maintenabilité et performance.
class AppLogger {
  /// Constructeur privé pour empêcher l'instanciation.
  AppLogger._();

  /// Préfixe pour les logs de l'application.
  static const String _logPrefix = '[AfterWork]';

  /// Log un message de niveau DEBUG.
  ///
  /// Les messages DEBUG ne sont affichés qu'en mode développement.
  ///
  /// [message] Le message à logger
  /// [tag] Tag optionnel pour catégoriser le log
  static void d(String message, {String? tag}) {
    if (EnvConfig.enableDetailedLogs && kDebugMode) {
      _log(LogLevel.debug, message, tag: tag);
    }
  }

  /// Log un message de niveau INFO.
  ///
  /// [message] Le message à logger
  /// [tag] Tag optionnel pour catégoriser le log
  static void i(String message, {String? tag}) {
    if (EnvConfig.enableDetailedLogs || kDebugMode) {
      _log(LogLevel.info, message, tag: tag);
    }
  }

  /// Log un message de niveau WARNING.
  ///
  /// [message] Le message à logger
  /// [tag] Tag optionnel pour catégoriser le log
  static void w(String message, {String? tag}) {
    _log(LogLevel.warning, message, tag: tag);
  }

  /// Log un message de niveau ERROR.
  ///
  /// [message] Le message à logger
  /// [error] L'erreur optionnelle
  /// [stackTrace] La stack trace optionnelle
  /// [tag] Tag optionnel pour catégoriser le log
  static void e(
    String message, {
    Object? error,
    StackTrace? stackTrace,
    String? tag,
  }) {
    _log(LogLevel.error, message, tag: tag);

    if (error != null) {
      _log(LogLevel.error, 'Error: $error', tag: tag);
    }

    if (stackTrace != null) {
      _log(LogLevel.error, 'StackTrace:\n$stackTrace', tag: tag);
    }

    // En production, envoyer à un service de monitoring si configuré
    if (EnvConfig.isProduction) {
      // TODO: Intégrer Firebase Crashlytics ou Sentry
      // _sendToCrashReporting(message, error, stackTrace);
    }
  }

  /// Log une requête HTTP.
  ///
  /// [method] La méthode HTTP (GET, POST, etc.)
  /// [url] L'URL de la requête
  /// [statusCode] Le code de statut de la réponse
  /// [duration] La durée de la requête en millisecondes
  static void http(
    String method,
    String url, {
    int? statusCode,
    int? duration,
  }) {
    if (!EnvConfig.enableDetailedLogs) {
      return;
    }

    final buffer = StringBuffer('HTTP $method $url');
    if (statusCode != null) {
      buffer.write(' → $statusCode');
    }
    if (duration != null) {
      buffer.write(' (${duration}ms)');
    }

    _log(LogLevel.info, buffer.toString(), tag: 'HTTP');
  }

  /// Méthode privée pour logger avec formatage.
  static void _log(
    LogLevel level,
    String message, {
    String? tag,
  }) {
    final timestamp = DateTime.now().toIso8601String();
    final levelStr = _getLevelString(level);
    final tagStr = tag != null ? '[$tag] ' : '';

    final logMessage = '$_logPrefix $timestamp $levelStr $tagStr$message';

    if (kDebugMode) {
      debugPrint(logMessage);
    } else {
      // En production, utiliser print uniquement pour les erreurs
      if (level == LogLevel.error) {
        print(logMessage);
      }
    }
  }

  /// Retourne la représentation string du niveau de log.
  static String _getLevelString(LogLevel level) {
    switch (level) {
      case LogLevel.debug:
        return '[DEBUG]';
      case LogLevel.info:
        return '[INFO] ';
      case LogLevel.warning:
        return '[WARN] ';
      case LogLevel.error:
        return '[ERROR]';
    }
  }
}

