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

class _LongMessagePrinter extends pkg.LogPrinter {
  final pkg.PrettyPrinter _prettyPrinter;
  final int _chunkSize;

  _LongMessagePrinter({
    required int methodCount,
    required int errorMethodCount,
    required int lineLength,
    required bool colors,
    required bool printEmojis,
    int chunkSize = 800,
  })  : _prettyPrinter = pkg.PrettyPrinter(
          methodCount: methodCount,
          errorMethodCount: errorMethodCount,
          lineLength: lineLength,
          colors: colors,
          printEmojis: printEmojis,
        ),
        _chunkSize = chunkSize;

  String _tryPrettyJson(String message) {
    try {
      final trimmed = message.trim();
      if ((trimmed.startsWith('{') && trimmed.endsWith('}')) ||
          (trimmed.startsWith('[') && trimmed.endsWith(']'))) {
        final decoded = jsonDecode(trimmed);
        return const JsonEncoder.withIndent('  ').convert(decoded);
      }
    } catch (_) {}
    return message;
  }

  List<String> _chunk(String text) {
    if (text.length <= _chunkSize) return [text];
    final chunks = <String>[];
    for (var i = 0; i < text.length; i += _chunkSize) {
      chunks.add(text.substring(i, i + _chunkSize > text.length ? text.length : i + _chunkSize));
    }
    return chunks;
  }

  @override
  List<String> log(pkg.LogEvent event) {
    final original = event.message;
    final output = StringBuffer();
    final lines = const LineSplitter().convert(_tryPrettyJson(original.toString()));
    for (final line in lines) {
      for (final chunk in _chunk(line)) {
        output.writeln(chunk);
      }
    }
    final wrappedEvent = pkg.LogEvent(
      event.level,
      output.toString().trimRight(),
      error: event.error,
      stackTrace: event.stackTrace,
    );
    return _prettyPrinter.log(wrappedEvent);
  }
}

class Log {
  static final pkg.Logger _logger = pkg.Logger(
    printer: _LongMessagePrinter(
      methodCount: 0,
      errorMethodCount: 5,
      lineLength: 90,
      colors: true,
      printEmojis: true,
      chunkSize: 800,
    ),
  );

  static void info(String message) {
    _logger.i(message);
  }

  static void warn(String message) {
    _logger.w(message);
  }

  static void error(String message, [dynamic error]) {
    _logger.e(message, error: error);
  }

  static void request(String message) {
    _logger.i('[REQUEST] $message');
  }

  static void response(String message) {
    _logger.i('[RESPONSE] $message');
  }
}
