import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';

class UserManager {
  static const String _userKey = 'user';
  static const String _accountKey = 'sys_account';
  static UserManager? _instance;
  static Map<String, dynamic>? _cachedUser;
  static Map<String, dynamic>? _cachedAccount;

  // Private constructor for singleton
  UserManager._privateConstructor();

  // Factory constructor to get the singleton instance
  factory UserManager() {
    _instance ??= UserManager._privateConstructor();
    return _instance!;
  }

  // Initialize and load user data
  Future<void> initialize() async {
    if (_cachedUser == null) {
      final prefs = await SharedPreferences.getInstance();
      final userData = prefs.getString(_userKey);
      if (userData != null) {
        _cachedUser = jsonDecode(userData) as Map<String, dynamic>;
      }
    }
    if (_cachedAccount == null) {
      final prefs = await SharedPreferences.getInstance();
      final accountData = prefs.getString(_accountKey);
      if (accountData != null) {
        _cachedAccount = jsonDecode(accountData) as Map<String, dynamic>;
      }
    }
  }

  // Accessor for user token
  String? get token {
    return _cachedUser?['token'];
  }

  // Accessor for user name
  String? get userName {
    return _cachedUser?['fullname'];
  }

  // Accessor for user email
  String? get email {
    return _cachedUser?['email'];
  }

  // Accessor for user id
  int? get userId {
    return _cachedUser?['userId'];
  }

  // Accessor for user roles (Assuming it's a list of roles in the user data)
  List<String>? get roles {
    if (_cachedUser?['roles'] != null) {
      return List<String>.from(_cachedUser!['roles']);
    }
    return null;
  }

  // Save user data and cache it
  Future<void> setUser(Map<String, dynamic> user) async {
    final prefs = await SharedPreferences.getInstance();
    final userData = jsonEncode(user);
    await prefs.setString(_userKey, userData);
    _cachedUser = user; // Update cache
  }

  // Save account data and cache it
  Future<void> setAccount(Map<String, dynamic> account) async {
    final prefs = await SharedPreferences.getInstance();
    final accountData = jsonEncode(account);
    await prefs.setString(_accountKey, accountData);
    _cachedAccount = account;
  }

  Map<String, dynamic>? get account => _cachedAccount;

  String? get accountId {
    final id = _cachedAccount?['account_id'] ?? _cachedAccount?['id'];
    return id?.toString();
  }

  // Clear user data and cache
  Future<void> clearUser() async {
    final prefs = await SharedPreferences.getInstance();

    await prefs.remove(_userKey);
    await prefs.remove(_accountKey);
    await prefs.remove('isLoggedIn');
    await prefs.clear();
    _cachedUser = null; // Clear cache
    _cachedAccount = null;
  }
}
