import 'dart:convert';

import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:moneymgr_mobile/services/api/api_token.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

part 'secure_storage.g.dart';

@riverpod
Future<SecureStorage> secureStorage(Ref ref) =>
    SecureStorage.getInstance(keys: {'token'});

class SecureStorage {
  SecureStorage._(this._flutterSecureStorage, this._cache);

  late final FlutterSecureStorage _flutterSecureStorage;

  late final Map<String, String> _cache;

  static Future<SecureStorage> getInstance({required Set<String> keys}) async {
    const flutterSecureStorage = FlutterSecureStorage();
    final cache = <String, String>{};
    await keys
        .map(
          (key) => flutterSecureStorage.read(key: key).then((value) {
            if (value != null) {
              cache[key] = value;
            }
          }),
        )
        .wait;
    return SecureStorage._(flutterSecureStorage, cache);
  }

  String? get(String key) => _cache[key];

  Future<void> set(String key, String value) {
    _cache[key] = value;
    return _flutterSecureStorage.write(key: key, value: value);
  }

  Future<void> remove(String key) {
    _cache.remove(key);
    return _flutterSecureStorage.delete(key: key);
  }

  /// Get auth token
  ApiToken? token() {
    final tokenStr = get("token");
    if (tokenStr != null) {
      return ApiToken.fromJson(jsonDecode(tokenStr));
    }
    return null;
  }

  /// Set auth token
  Future<void> setToken(ApiToken token) =>
      set("token", jsonEncode(token.toJson()));

  /// Remove auth token
  Future<void> removeToken() => remove("token");
}
