import 'dart:convert';

import 'package:rasadyar_auth/data/models/local/user_local/user_local_model.dart';
import 'package:rasadyar_auth/hive_registrar.g.dart';
import 'package:rasadyar_core/core.dart';

class TokenStorageService extends GetxService {
  static const String _boxName = 'secureBox';
  static const String _accessTokenKey = 'accessToken';
  static const String _refreshTokenKey = 'refreshToken';
  static const String _baseUrlKey = 'baseUrl';
  static const String _apiKey = 'apiKey';
  static const String _moduleKey = 'moduleSelected';

  final FlutterSecureStorage _secureStorage = FlutterSecureStorage();
  final HiveLocalStorage _localStorage = diCore.get<HiveLocalStorage>();

  RxnString accessToken = RxnString();
  RxnString refreshToken = RxnString();
  RxnString baseurl= RxnString();
  Rxn<Module> appModule = Rxn(null);

  Future<void> init() async {
    await Hive.initFlutter();
    Hive.registerAdapters();

    final String? encryptedKey = await _secureStorage.read(key: 'hive_enc_key');
    final encryptionKey = encryptedKey != null ? base64Url.decode(encryptedKey) : Hive.generateSecureKey();

    if (encryptedKey == null) {
      await _secureStorage.write(key: 'hive_enc_key', value: base64UrlEncode(encryptionKey));
    }

    await _localStorage.init();
    await _localStorage.openBox(_boxName, encryptionCipher: HiveAesCipher(encryptionKey));

    accessToken.value = _localStorage.read<String?>(boxName: _boxName, key: _accessTokenKey);
    refreshToken.value = _localStorage.read<String?>(boxName: _boxName, key: _refreshTokenKey);
    appModule.value = _localStorage.read<Module?>(boxName: _boxName, key: _moduleKey);
    baseurl.value = _localStorage.read<String?>(boxName: _boxName, key: _baseUrlKey);
  }

  Future<void> saveAccessToken(String token) async {
    await _localStorage.save(boxName: _boxName, key: _accessTokenKey, value: token);
    accessToken.value = token;
    accessToken.refresh();
  }

  Future<void> saveRefreshToken(String token) async {
    await _localStorage.save(boxName: _boxName, key: _refreshTokenKey, value: token);
    refreshToken.value = token;
    refreshToken.refresh();
  }

  Future<void> saveModule(Module input) async {
    await _localStorage.save(boxName: _boxName, key: _moduleKey, value: input);
    appModule.value = input;
    appModule.refresh();
  }

  Future<void> deleteTokens() async {
    await _localStorage.clear(_boxName);
    accessToken.value = null;
    refreshToken.value = null;
  }


  Future<void> saveBaseUrl(String url) async {
    await _localStorage.save(boxName: _boxName, key: _baseUrlKey, value: url);
    baseurl.value = url;
    baseurl.refresh();
  }

  Future<void> saveApiKey(String key) async {
    await _localStorage.save(boxName: _boxName, key: _apiKey, value: key);

  }
}
