import 'dart:convert';
import 'package:logger/logger.dart';

class SimpleLogPrinter extends LogPrinter {
  final String className;
  static final _deviceStackTraceRegex = RegExp(r'#[0-9]+[\s]+(.+) \(([^\s]+)\)');
  static final _webStackTraceRegex = RegExp(r'^((packages|dart-sdk)\/[^\s]+\/)');
  SimpleLogPrinter(this.className);

  @override
  List<String> log(LogEvent event) {
    final Level level = event.level;
    final String message = stringifyMessage(event.message);
    final String error = event.error?.toString() ?? '';
    final color = PrettyPrinter.levelColors[level];
    final emoji = PrettyPrinter.levelEmojis[level];
    String? stack;
    if (event.stackTrace == null) {
     stack = formatStackTrace(StackTrace.current, 2);
    } else {
     stack = formatStackTrace(event.stackTrace!, 1);
    }
    // ignore: avoid_print
    print(color!(' $emoji $message $error -> $stack '));
    return [];
  }

  String stringifyMessage(dynamic message) {
   if (message is Map || message is Iterable) {
    const encoder = JsonEncoder.withIndent('  ');
    return encoder.convert(message);
   } else {
    return message.toString();
   }
  }

  String? formatStackTrace(StackTrace stackTrace, int methodPosition) {
    final lines = stackTrace.toString().split('\n');
    final formatted = <String>[];
    var count = 0;
    for (final line in lines) {
      if (_discardDeviceStacktraceLine(line) ||
          _discardWebStacktraceLine(line)) {
        continue;
      }
      formatted.add(line.replaceFirst(RegExp(r'#\d+\s+'), ''));
      if (++count == methodPosition) {
        break;
      }
    }

    if (formatted.isEmpty) {
      return null;
    } else {
      //return formatted.join('\n');
      return formatted.last;
    }
  }

  bool _discardDeviceStacktraceLine(String line) {
    final match = _deviceStackTraceRegex.matchAsPrefix(line);
    if (match == null) {
      return false;
    }
    return match.group(2)!.startsWith('package:logger');
  }

  bool _discardWebStacktraceLine(String line) {
    final match = _webStackTraceRegex.matchAsPrefix(line);
    if (match == null) {
      return false;
    }
    return match.group(1)!.startsWith('packages/logger') ||
        match.group(1)!.startsWith('dart-sdk/lib');
  }
}

Logger getLogger(String className) {
  return Logger(printer: SimpleLogPrinter(className));
}
