import 'dart:convert';
import 'dart:io';

import 'package:logging/logging.dart';
import 'package:result_monad/result_monad.dart';

class PersistentInfoService {
  static final _logger = Logger('$PersistentInfoService');
  final String filePath;

  DateTime _lastMyConnectionsUpdate;

  DateTime get lastMyConnectionsUpdate => _lastMyConnectionsUpdate;

  Future<void> updateLastMyConnectionUpdate(DateTime value) async {
    _lastMyConnectionsUpdate = value;
    await save();
  }

  PersistentInfoService(this.filePath)
      : _lastMyConnectionsUpdate = DateTime(1970);

  void load() {
    final file = File(filePath);
    if (!file.existsSync()) {
      return;
    }

    Result.ok('')
        .transform((_) => File(filePath).readAsStringSync())
        .transform((str) => jsonDecode(str))
        .transform((json) => _PersistentInfo.fromJson(json))
        .match(onSuccess: (info) {
      _lastMyConnectionsUpdate = info.lastMyConnectionsUpdate;
    }, onError: (error) {
      _logger.severe('Error reading Persistence: $error');
    });
  }

  Future<void> save() async {
    Result.ok(
      _PersistentInfo(
        lastMyConnectionsUpdate: _lastMyConnectionsUpdate,
      ).toJson(),
    )
        .transform((json) => jsonEncode(json))
        .withResultAsync((json) async => File(filePath).writeAsString(json))
        .withError(
          (error) => _logger.severe('Error reading Persistence: $error'),
        );
  }
}

class _PersistentInfo {
  final DateTime lastMyConnectionsUpdate;

  const _PersistentInfo({
    required this.lastMyConnectionsUpdate,
  });

  Map<String, dynamic> toJson() => {
        'lastMyConnectionsUpdate': lastMyConnectionsUpdate.toIso8601String(),
      };

  factory _PersistentInfo.fromJson(Map<String, dynamic> json) =>
      _PersistentInfo(
        lastMyConnectionsUpdate:
            DateTime.tryParse(json['lastMyConnectionsUpdate']) ??
                DateTime(1970),
      );
}
