import 'package:flutter/foundation.dart';
import 'package:logging/logging.dart';

/// 日志级别
enum LogLevel {
  verbose, // 详细信息
  debug, // 调试信息
  info, // 普通信息
  warning, // 警告信息
  error, // 错误信息
  wtf // 严重错误
}

/// 应用程序日志管理类
class AppLogger {
  static bool _initialized = false;
  static final Map<String, Logger> _loggers = {};

  // 日志级别与Logging包级别的映射
  static final Map<LogLevel, Level> _levelMap = {
    LogLevel.verbose: Level.FINEST,
    LogLevel.debug: Level.FINE,
    LogLevel.info: Level.INFO,
    LogLevel.warning: Level.WARNING,
    LogLevel.error: Level.SEVERE,
    LogLevel.wtf: Level.SHOUT,
  };

  /// 初始化日志系统
  static void init() {
    if (_initialized) return;

    hierarchicalLoggingEnabled = true;

    // 在调试模式下显示所有日志，在生产模式下只显示INFO级别以上
    Logger.root.level = kDebugMode ? Level.ALL : Level.INFO;

    // 配置日志监听器
    Logger.root.onRecord.listen((record) {
      // 不在生产环境打印Verbose和Debug日志，即使 Root Level 允许
      if (!kDebugMode &&
          (record.level == Level.FINEST ||
              record.level == Level.FINER ||
              record.level == Level.FINE)) {
        return;
      }

      final lvlColor = _getLogLevelColor(record.level);
      const resetColor = '\x1B[0m'; // ANSI 重置颜色代码
      final emoji = _getLogEmoji(record.level);
      final timestamp = DateTime.now().toString().substring(0, 19);
      // 格式: 时间戳 [级别] [模块名] Emoji 日志内容
      final messageHeader =
          '$lvlColor$timestamp [${record.level.name}] [${record.loggerName}] $emoji $resetColor';
      final messageBody = '$lvlColor${record.message}$resetColor';

      final String logMessage;

      if (record.error != null) {
        // 添加错误详情和格式化的堆栈信息
        final errorString = '$lvlColor错误: ${record.error}$resetColor';
        // StackTrace 过滤：只显示应用相关的堆栈，限制行数
        final stackTraceString = _formatStackTrace(record.stackTrace,
            filterAppCode: true, maxLines: 15);
        logMessage =
            '$messageHeader $messageBody\n$errorString${stackTraceString.isNotEmpty ? '\n$lvlColor堆栈:$resetColor\n$stackTraceString' : ''}';
      } else {
        logMessage = '$messageHeader $messageBody';
      }

      // 使用 print 输出，以便颜色代码生效
      // 在 release 版本中，由于 Logger.root.level 的限制，低于 INFO 的日志不会走到这里
      print(logMessage);
    });

    _initialized = true;
  }

  /// 获取指定模块的日志记录器
  static Logger getLogger(String name) {
    if (!_initialized) init();

    return _loggers.putIfAbsent(name, () {
      final logger = Logger(name);
      logger.level = Logger.root.level;
      return logger;
    });
  }

  /// 记录详细日志
  static void v(String tag, String message,
      [Object? error, StackTrace? stackTrace]) {
    _log(tag, LogLevel.verbose, message, error, stackTrace);
  }

  /// 记录调试日志
  static void d(String tag, String message,
      [Object? error, StackTrace? stackTrace]) {
    _log(tag, LogLevel.debug, message, error, stackTrace);
  }

  /// 记录信息日志
  static void i(String tag, String message,
      [Object? error, StackTrace? stackTrace]) {
    _log(tag, LogLevel.info, message, error, stackTrace);
  }

  /// 记录警告日志
  static void w(String tag, String message,
      [Object? error, StackTrace? stackTrace]) {
    _log(tag, LogLevel.warning, message, error, stackTrace);
  }

  /// 记录错误日志
  static void e(String tag, String message,
      [Object? error, StackTrace? stackTrace]) {
    _log(tag, LogLevel.error, message, error, stackTrace);
  }

  /// 记录严重错误日志
  static void wtf(String tag, String message,
      [Object? error, StackTrace? stackTrace]) {
    _log(tag, LogLevel.wtf, message, error, stackTrace);
  }

  // 为了向后兼容，添加简化的方法名
  /// 记录信息日志（简化版）
  static void info(String tag, String message,
      [Object? error, StackTrace? stackTrace]) {
    _log(tag, LogLevel.info, message, error, stackTrace);
  }

  /// 记录错误日志（简化版）
  static void error(String tag, String message,
      [Object? error, StackTrace? stackTrace]) {
    _log(tag, LogLevel.error, message, error, stackTrace);
  }

  /// 内部日志记录方法
  static void _log(String tag, LogLevel level, String message,
      [Object? error, StackTrace? stackTrace]) {
    final logger = getLogger(tag);
    final logLevel = _levelMap[level]!;

    logger.log(logLevel, message, error, stackTrace);
  }

  /// 获取日志级别对应的emoji
  static String _getLogEmoji(Level level) {
    if (level == Level.FINEST || level == Level.FINER || level == Level.FINE) {
      return '🔍'; // 调试
    }
    if (level == Level.CONFIG || level == Level.INFO) return '📘'; // 信息
    if (level == Level.WARNING) return '⚠️'; // 警告
    if (level == Level.SEVERE) return '❌'; // 错误
    if (level == Level.SHOUT) return '💥'; // 严重错误
    return '📝'; // 默认
  }

  /// 获取日志级别对应的ANSI颜色代码
  static String _getLogLevelColor(Level level) {
    if (level == Level.FINEST || level == Level.FINER || level == Level.FINE) {
      return '\x1B[90m'; // 灰色 (Verbose/Debug)
    }
    if (level == Level.CONFIG || level == Level.INFO) {
      return '\x1B[34m'; // 蓝色 (Info/Config)
    }
    if (level == Level.WARNING) return '\x1B[33m'; // 黄色 (Warning)
    if (level == Level.SEVERE) return '\x1B[31m'; // 红色 (Error)
    if (level == Level.SHOUT) return '\x1B[35;41m'; // 紫色 + 红色背景 (WTF/Shout)
    return '\x1B[0m'; // 默认 (重置)
  }

  /// 格式化并过滤堆栈信息
  static String _formatStackTrace(StackTrace? stackTrace,
      {int maxLines = 10, bool filterAppCode = true}) {
    if (stackTrace == null) return '';

    final lines = stackTrace.toString().split('\n');
    final formattedLines = <String>[];
    const appPackagePrefix = 'package:ainoval/'; // 修改为你的应用包名
    const flutterPackagePrefix = 'package:flutter/';
    const dartPrefix = 'dart:';

    int linesAdded = 0;
    for (final line in lines) {
      final trimmedLine = line.trim();
      if (trimmedLine.isEmpty) continue;

      bool isAppCode = trimmedLine.contains(appPackagePrefix);
      bool isFrameworkCode = trimmedLine.contains(flutterPackagePrefix) ||
          trimmedLine.startsWith(dartPrefix);

      // 如果开启过滤，只保留应用代码；否则不过滤
      // 同时，排除纯dart:前缀和flutter框架内部调用（除非没有应用代码帧时酌情显示）
      if (!filterAppCode ||
          isAppCode ||
          (!isFrameworkCode && !trimmedLine.startsWith('#'))) {
        // 也包含一些非 package 的项目内部调用格式
        // 尝试保持可点击的格式
        // IDE 通常能识别类似 'package:my_app/my_file.dart:123:45' 的格式
        formattedLines.add('  $trimmedLine'); // 添加缩进
        linesAdded++;
        if (linesAdded >= maxLines) break; // 限制最大行数
      }
    }

    // 如果过滤后为空（可能错误发生在框架深处），则显示原始堆栈的前几行
    if (formattedLines.isEmpty && lines.isNotEmpty) {
      formattedLines.addAll(lines
          .take(maxLines)
          .map((l) => '  ${l.trim()}')
          .where((l) => l.length > 2));
    }

    return formattedLines.join('\n');
  }
}
