import 'dart:developer';
import 'package:hub/shared/utils/storage_util.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:hub/shared/utils/cache_util.dart';

class SharedPreferencesStorageHelper implements Storage {
  static final SharedPreferencesStorageHelper _instance =
      SharedPreferencesStorageHelper._internal();
  SharedPreferences? _prefs;

  SharedPreferences? get prefs => _prefs;
  set prefs(SharedPreferences? value) => _prefs = value;

  factory SharedPreferencesStorageHelper() => _instance;

  SharedPreferencesStorageHelper._internal();

  static SharedPreferencesStorageHelper get instance => _instance;

  Future<void> initialize() async =>  _prefs = await SharedPreferences.getInstance();
  

  Future<void> _setAndCache<T>(String key, T value, Function(T) cacheSetter, Future<void> Function(String, T) setFunc) async {
    log('setAndCache value for key: $key to $value');
    await setFunc(key, value);
    CacheUtil.instance.set(key, value);
    cacheSetter(value);
  }
  Future<void> _setAndCacheString(String key, String value, Function(String) cacheSetter) async {
    log('setAndCacheString value for key: $key to $value');
    await _setAndCache(key, value, cacheSetter, _prefs!.setString);
  }
  Future<void> _setAndCacheBool(String key, bool value, Function(bool) cacheSetter) async {
    log('setAndCacheBool value for key: $key to $value');
    await _setAndCache(key, value, cacheSetter, _prefs!.setBool);
  }
  Future<void> _setAndCacheInt(String key, int value, Function(int) cacheSetter) async {
    log('setAndCacheInt value for key: $key to $value');
    await _setAndCache(key, value, cacheSetter, _prefs!.setInt);
  }
  Future<void> _setAndCacheDouble(String key, double value, Function(double) cacheSetter) async {
    log('setAndCacheDouble value for key: $key to $value');
    await _setAndCache(key, value, cacheSetter, _prefs!.setDouble);
  }
  Future<void> _setAndCacheStringList(String key, List<String> value, Function(List<String>) cacheSetter) async {
    log('setAndCacheStringList value for key: $key to $value');
    await _setAndCache(key, value, cacheSetter, _prefs!.setStringList);
  }


  @override Future<void> set(String key, dynamic value, Function(dynamic) cacheSetter) async {
    if (value is bool) {
      log('() => setAndCacheBool $key to $value');
      await _prefs?.setBool(key, value);
    } else if (value is String) {
      await _prefs?.setString(key, value);
    } else if (value is int) {
      await _prefs?.setInt(key, value);
    } else if (value is double) {
      await _prefs?.setDouble(key, value);
    } else if (value is List<String>) {
      await _prefs?.setStringList(key, value);
    }
    CacheUtil.instance.set(key, value);
  }
  @override Future<dynamic> get(String key) async {
    log('Getting value for key: $key');
    var value = CacheUtil.instance.get(key);
    if (value == null) {
      value = _prefs?.get(key);
      CacheUtil.instance.set(key, value);
    }
    return value;
  }
  @override Future<void> delete(String key) async {
    log('Deleting value for key: $key');
    await _prefs?.remove(key);
    CacheUtil.instance.delete(key);
  }
  @override Future<void> purge() async {
    log('Purging shared preferences');
    await _prefs?.clear();
    CacheUtil.instance.clear();
  }


}
