// Dart imports:
import 'dart:async';
import 'dart:convert';
import 'dart:io';

// Flutter imports:
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';

// Package imports:
import 'package:fluttertoast/fluttertoast.dart';
import 'package:injectable/injectable.dart';
import 'package:path_provider/path_provider.dart';
import 'package:remever/common/functions.dart';
import 'package:remever/common/typedef.dart';
import 'package:remever/models/logs/build_log.dart';
import 'package:talker_flutter/talker_flutter.dart';

@Singleton()
class LogsService {
  void log(String message) {
    talker.log(message);
  }

  void logDebug(String message) {
    talker.debug(message);
  }

  void logInfo(String message) {
    talker.info(message);
  }

  void logError(String message, Object? exception, StackTrace? stackTrace) {
    talker.error(message, exception, stackTrace);

    if (kDebugMode) showErrorToast('$message ${exception.toString()}');
  }

  void logCritical(String message, Object? exception, StackTrace? stackTrace) {
    talker.critical(message, exception, stackTrace);
  }

  void logBuild(String message) {
    talker.logCustom(BuildLog(message));
  }

  // Метод для получения истории
  Future<List<TalkerData>?> getHistory() async {
    try {
      final Directory docDir = await getApplicationDocumentsDirectory();
      final String path = '${docDir.path}/history.log';
      final File logFile = File(path);

      if (!logFile.existsSync()) {
        return null;
      }

      final List<String> lines = await logFile.readAsLines();
      if (lines.length > 1500) {
        lines.removeRange(0, lines.length - 1500);

        logFile.deleteSync();
        logFile.createSync();
        logFile.writeAsStringSync(lines.join('\n'));
      }

      final List<Json> entities = await _parseLines(lines, logFile);

      if (entities.isEmpty) {
        return null;
      }

      final List<TalkerData> talkerData = _convertEntitiesToTalkerData(
        entities,
      );
      return talkerData;
    } catch (e) {
      debugPrint('ALARM ERROR IN GETHISTORY $e');
      return null;
    }
  }

  // Парсинг строк из файла
  Future<List<Json>> _parseLines(List<String> lines, File logFile) async {
    final List<Json> entities = <Json>[];

    for (String line in lines) {
      try {
        entities.add(jsonDecode(line));
      } catch (e) {
        debugPrint('Error $e in line $line of ${logFile.path}');

        if (e.toString().contains('Unexpected character')) {
          unawaited(logFile.delete());
          break;
        }
      }
    }

    return entities;
  }

  // Преобразование JSON-сущностей в TalkerData
  List<TalkerData> _convertEntitiesToTalkerData(List<Json> entities) {
    final List<TalkerData> talkerData = <TalkerData>[];

    for (Json json in entities) {
      talkerData.add(
        TalkerData(
          json['message'],
          error: json['error'],
          exception: json['exception'],
          key: json['key'],
          logLevel: json['logLevel'],
          stackTrace: json['stackTrace'],
          time: DateTime.tryParse(json['time']),
          title: 'SAVED ${json['title']}',
        ),
      );
    }

    return talkerData;
  }
}
