import 'package:marco/helpers/services/auth_service.dart';
import 'package:marco/helpers/services/localizations/language.dart';
import 'package:marco/helpers/theme/theme_customizer.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:marco/model/user_permission.dart';
import 'package:marco/model/employee_info.dart';
import 'dart:convert';
import 'package:marco/controller/project_controller.dart';
import 'package:get/get.dart'; 


class LocalStorage {
  static const String _loggedInUserKey = "user";
  static const String _themeCustomizerKey = "theme_customizer";
  static const String _languageKey = "lang_code";
  static const String _jwtTokenKey = "jwt_token";
  static const String _refreshTokenKey = "refresh_token";
  static const String _userPermissionsKey = "user_permissions";
  static const String _employeeInfoKey = "employee_info";
  static const String _mpinTokenKey = "mpinToken";
  static const String _isMpinKey = "isMpin";
  static SharedPreferences? _preferencesInstance;

  static SharedPreferences get preferences {
    if (_preferencesInstance == null) {
      throw ("Call LocalStorage.init() to initialize local storage");
    }
    return _preferencesInstance!;
  }
// In LocalStorage class

  static Future<bool> setUserPermissions(
      List<UserPermission> permissions) async {
    // Convert the list of UserPermission objects to a List<Map<String, dynamic>>
    final jsonList = permissions.map((e) => e.toJson()).toList();

    // Save as a JSON string
    return preferences.setString(_userPermissionsKey, jsonEncode(jsonList));
  }

  static List<UserPermission> getUserPermissions() {
    final storedJson = preferences.getString(_userPermissionsKey);

    if (storedJson != null) {
      final List<dynamic> parsedList = jsonDecode(storedJson);
      return parsedList
          .map((e) => UserPermission.fromJson(e as Map<String, dynamic>))
          .toList();
    }

    return [];
  }

  static Future<bool> removeUserPermissions() async {
    return preferences.remove(_userPermissionsKey);
  }

  // Store EmployeeInfo
  static Future<bool> setEmployeeInfo(EmployeeInfo employeeInfo) async {
    final jsonData = employeeInfo.toJson();
    return preferences.setString(_employeeInfoKey, jsonEncode(jsonData));
  }

  static EmployeeInfo? getEmployeeInfo() {
    final storedJson = preferences.getString(_employeeInfoKey);
    if (storedJson != null) {
      final Map<String, dynamic> json = jsonDecode(storedJson);
      return EmployeeInfo.fromJson(json);
    }
    return null;
  }

  static Future<bool> removeEmployeeInfo() async {
    return preferences.remove(_employeeInfoKey);
  }

  // Other methods for handling JWT, refresh token, etc.
  static Future<void> init() async {
    _preferencesInstance = await SharedPreferences.getInstance();
    await initData();
  }

  static Future<void> initData() async {
    SharedPreferences preferences = await SharedPreferences.getInstance();
    AuthService.isLoggedIn = preferences.getBool(_loggedInUserKey) ?? false;
    ThemeCustomizer.fromJSON(preferences.getString(_themeCustomizerKey));
  }

  static Future<bool> setLoggedInUser(bool loggedIn) async {
    return preferences.setBool(_loggedInUserKey, loggedIn);
  }

  static Future<bool> setCustomizer(ThemeCustomizer themeCustomizer) {
    return preferences.setString(_themeCustomizerKey, themeCustomizer.toJSON());
  }

  static Future<bool> setLanguage(Language language) {
    return preferences.setString(_languageKey, language.locale.languageCode);
  }

  static String? getLanguage() {
    return preferences.getString(_languageKey);
  }

  static Future<bool> removeLoggedInUser() async {
    return preferences.remove(_loggedInUserKey);
  }

  // Add methods to handle JWT and Refresh Token
  static Future<bool> setToken(String key, String token) {
    return preferences.setString(key, token);
  }

  static String? getToken(String key) {
    return preferences.getString(key);
  }

  static Future<bool> removeToken(String key) {
    return preferences.remove(key);
  }

  // Convenience methods for getting the JWT and Refresh tokens
  static String? getJwtToken() {
    return getToken(_jwtTokenKey);
  }

  static String? getRefreshToken() {
    return getToken(_refreshTokenKey);
  }

  static Future<bool> setJwtToken(String jwtToken) {
    return setToken(_jwtTokenKey, jwtToken);
  }

  static Future<bool> setRefreshToken(String refreshToken) {
    return setToken(_refreshTokenKey, refreshToken);
  }

static Future<void> logout() async {
  await removeLoggedInUser();
  await removeToken(_jwtTokenKey);
  await removeToken(_refreshTokenKey);
  await removeUserPermissions();
  await removeEmployeeInfo();
  await removeMpinToken(); 
  await removeIsMpin(); 
  await preferences.remove("mpin_verified");
  await preferences.remove(_languageKey);
  await preferences.remove(_themeCustomizerKey);
  await preferences.remove('selectedProjectId');
  if (Get.isRegistered<ProjectController>()) {
    Get.find<ProjectController>().clearProjects();
  }

  Get.offAllNamed('/auth/login-option');
}

  static Future<bool> setMpinToken(String token) {
    return preferences.setString(_mpinTokenKey, token);
  }

  static String? getMpinToken() {
    return preferences.getString(_mpinTokenKey);
  }

  static Future<bool> removeMpinToken() {
    return preferences.remove(_mpinTokenKey);
  }

  // MPIN Enabled flag
  static Future<bool> setIsMpin(bool value) {
    return preferences.setBool(_isMpinKey, value);
  }

  static bool getIsMpin() {
    return preferences.getBool(_isMpinKey) ?? false;
  }

  static Future<bool> removeIsMpin() {
    return preferences.remove(_isMpinKey);
  }

  static Future<bool> setBool(String key, bool value) async {
    return preferences.setBool(key, value);
  }

  static bool? getBool(String key) {
    return preferences.getBool(key);
  }
 // Save and retrieve String values
  static String? getString(String key) {
  return preferences.getString(key);
}

static Future<bool> saveString(String key, String value) async {
  return preferences.setString(key, value);
}

}
