import 'package:result_monad/result_monad.dart';
import 'package:time_machine/time_machine_text_patterns.dart';

import '../models/exec_error.dart';

class OffsetDateTimeUtils {
  static final _offsetTimeParser =
      OffsetDateTimePattern.createWithInvariantCulture(
          'ddd MMM dd HH:mm:ss o<+HHmm> yyyy');

  static Result<int, ExecError> epochSecTimeFromFriendicaString(
      String dateString) {
    final offsetDateTime = _offsetTimeParser.parse(dateString);
    if (!offsetDateTime.success) {
      return Result.error(ExecError(
          type: ErrorType.parsingError,
          message: offsetDateTime.error.toString()));
    }

    return Result.ok(offsetDateTime.value.localDateTime
            .toDateTimeLocal()
            .millisecondsSinceEpoch ~/
        1000);
  }

  static Result<int, ExecError> epochSecTimeFromTimeZoneString(
      String dateString) {
    final offsetDateTime = OffsetDateTimePattern.extendedIso.parse(dateString);
    if (!offsetDateTime.success) {
      return Result.error(ExecError(
          type: ErrorType.parsingError,
          message: offsetDateTime.error.toString()));
    }

    return Result.ok(offsetDateTime.value.localDateTime
            .toDateTimeLocal()
            .millisecondsSinceEpoch ~/
        1000);
  }
}

class ElapsedDateUtils {
  static String epochSecondsToString(int epochSeconds) {
    final epoch = DateTime.fromMillisecondsSinceEpoch(epochSeconds * 1000);
    final elapsed = DateTime.now().difference(epoch);
    if (elapsed.inDays > 0) {
      return '${elapsed.inDays} days ago';
    }

    if (elapsed.inHours > 0) {
      return '${elapsed.inHours} hours ago';
    }

    if (elapsed.inMinutes > 0) {
      return '${elapsed.inMinutes} minutes ago';
    }

    return 'seconds ago';
  }
}

const _separator = '_';

extension DateTimeExtensions on DateTime {
  String toFileNameString() => '$year$month$day$_separator$hour$minute$second';
}
