import 'dart:io';
import 'package:hmg_qline/config/dependency_injection.dart';
import 'package:hmg_qline/constants/app_constants.dart';
import 'package:hmg_qline/services/cache_service.dart';
import 'package:hmg_qline/utilities/enums.dart';
import 'package:hmg_qline/view_models/screen_config_view_model.dart';
import 'package:intl/intl.dart';
import 'package:logger/logger.dart';
import 'package:path_provider/path_provider.dart';

abstract class LoggerService {
  Future<void> logToFile({required String message, required LogTypeEnum type, required String source});

  void logError(String message);

  void logInfo(String message);
}

class LoggerServiceImp implements LoggerService {
  Logger logger;

  LoggerServiceImp({required this.logger});

  @override
  Future<void> logToFile({required String message, required LogTypeEnum type, required String source}) async {
    try {
      ScreenConfigViewModel screenConfigViewModel = getIt.get<ScreenConfigViewModel>();
      final timestamp = DateFormat('yyyy-MM-dd hh:mm:ss a').format(DateTime.now());
      final formattedMessage = "[$timestamp] [SOURCE: $source] ${type.name.toUpperCase()}: $message";

      final baseDir = await getExternalStorageDirectory();
      final logDir = Directory('${baseDir!.path}/logs');
      if (!await logDir.exists()) {
        await logDir.create(recursive: true);
      }

      String logFileName = "";

      if (type == LogTypeEnum.error) {
        logFileName = AppStrings.errorLogsFileName;
      } else if (type == LogTypeEnum.data) {
        logFileName = AppStrings.dataLogsFileName;
      } else {
        logFileName = AppStrings.connectivityLogsFileName;
      }

      final file = File('${logDir.path}/${screenConfigViewModel.currentScreenIP}_$logFileName');

      CacheService cacheService = getIt.get<CacheService>();

      final lastLogsClearedAt = screenConfigViewModel.lastTimeLogsCleared;
      final now = DateTime.now();

      if (lastLogsClearedAt != null && now.difference(lastLogsClearedAt).inHours >= AppConstants.clearLogsHoursThreshold) {
        final clearingMessage = "[$timestamp] [SOURCE: $source] ${type.name.toUpperCase()}: LOGS HAVE BEEN CLEARED\n";
        await file.writeAsString(clearingMessage);
        screenConfigViewModel.lastTimeLogsCleared = now;
        cacheService.setLastTimeLogsCleared(lastTimeCleared: now.millisecondsSinceEpoch);
      }
      await file.writeAsString("$formattedMessage\n", mode: FileMode.append);
    } catch (e) {
      logger.e('Logging failed: $e');
    }
  }

  @override
  void logError(String message) {
    logger.e(message);
  }

  @override
  void logInfo(String message) {
    logger.i(message);
  }
}
