#include "user_manager.h"
#include "jwt_auth.h"
#include <nlohmann/json.hpp>
#include <fstream>
#include <filesystem>
#include <sstream>
#include <iomanip>
#include <regex>
#include <crypt.h>
#include <unistd.h>
#include <pwd.h>
#include <shadow.h>
#include <sys/types.h>
#include <openssl/sha.h>


// Define static permission constants
const std::string UserManager::Permissions::READ = "read";
const std::string UserManager::Permissions::GENERATE = "generate";
const std::string UserManager::Permissions::QUEUE_MANAGE = "queue_manage";
const std::string UserManager::Permissions::MODEL_MANAGE = "model_manage";
const std::string UserManager::Permissions::USER_MANAGE = "user_manage";
const std::string UserManager::Permissions::ADMIN = "admin";

UserManager::UserManager(const std::string& dataDir,
                         AuthMethod authMethod)
    : m_dataDir(dataDir)
    , m_authMethod(authMethod)
    , m_pamAuthEnabled(false)
{
#ifdef ENABLE_PAM_AUTH
    m_pamAuth = std::make_unique<PamAuth>();
#endif
}

UserManager::~UserManager() {
    shutdown();
}

bool UserManager::initialize() {
    try {
        // Create data directory if it doesn't exist
        std::filesystem::create_directories(m_dataDir);

        // Load existing user data
        if (!loadUserData()) {
            // Create default admin user if no users exist
            if (m_users.empty()) {
                auto [success, adminId] = createUser("admin", "admin123", "admin@localhost", UserRole::ADMIN, "system");
                if (!success) {
                    return false;
                }
            }
        }

        // Load existing API key data
        loadApiKeyData();

        return true;
    } catch (const std::exception& e) {
        return false;
    }
}

void UserManager::shutdown() {
    // Save data before shutdown
    saveUserData();
    saveApiKeyData();
}

AuthResult UserManager::authenticateUser(const std::string& username, const std::string& password) {
    AuthResult result;
    result.success = false;

    try {
        // Find user by username
        auto it = m_users.find(username);
        if (it == m_users.end()) {
            result.errorMessage = "User not found";
            result.errorCode = "USER_NOT_FOUND";
            return result;
        }

        const UserInfo& user = it->second;

        // Check if user is active
        if (!user.active) {
            result.errorMessage = "User account is disabled";
            result.errorCode = "ACCOUNT_DISABLED";
            return result;
        }

        // Verify password
        if (!verifyPassword(password, user.passwordHash)) {
            result.errorMessage = "Invalid password";
            result.errorCode = "INVALID_PASSWORD";
            return result;
        }

        // Authentication successful
        result.success = true;
        result.userId = user.id;
        result.username = user.username;
        result.role = user.role;
        result.permissions = user.permissions;

        // Update last login time
        m_users[username].lastLoginAt = getCurrentTimestamp();
        saveUserData();

    } catch (const std::exception& e) {
        result.errorMessage = "Authentication failed: " + std::string(e.what());
        result.errorCode = "AUTH_ERROR";
    }

    return result;
}

AuthResult UserManager::authenticateUnix(const std::string& username, const std::string& password) {
    AuthResult result;
    result.success = false;

    // Check if Unix authentication is the configured method
    if (m_authMethod != AuthMethod::UNIX) {
        result.errorMessage = "Unix authentication is not enabled";
        result.errorCode = "UNIX_AUTH_DISABLED";
        return result;
    }

    try {
        // If PAM is enabled, delegate to PAM authentication
        if (m_pamAuthEnabled) {
            return authenticatePam(username, password);
        }

        // Traditional Unix auth without PAM - just check if user exists
        // This is a fallback for when PAM is not available
        struct passwd* pw = getpwnam(username.c_str());
        if (!pw) {
            result.errorMessage = "Unix user not found";
            result.errorCode = "UNIX_USER_NOT_FOUND";
            return result;
        }

        // Check if user exists in our system or create guest user
        UserInfo user;
        auto it = m_users.find(username);
        if (it != m_users.end()) {
            user = it->second;
        } else {
            // Create guest user for Unix authentication
            user.id = generateUserId();
            user.username = username;
            user.email = username + "@localhost";
            user.role = roleToString(UserRole::USER);
            user.permissions = getDefaultPermissions(UserRole::USER);
            user.active = true;
            user.createdAt = getCurrentTimestamp();
            user.createdBy = "system";

            m_users[username] = user;
            saveUserData();
        }

        // Authentication successful
        result.success = true;
        result.userId = user.id;
        result.username = user.username;
        result.role = user.role;
        result.permissions = user.permissions;

    } catch (const std::exception& e) {
        result.errorMessage = "Unix authentication failed: " + std::string(e.what());
        result.errorCode = "UNIX_AUTH_ERROR";
    }

    return result;
}

AuthResult UserManager::authenticatePam(const std::string& username, const std::string& password) {
    AuthResult result;
    result.success = false;

    // Check if PAM authentication is the configured method
    if (m_authMethod != AuthMethod::PAM) {
        result.errorMessage = "PAM authentication is not enabled";
        result.errorCode = "PAM_AUTH_DISABLED";
        return result;
    }

#ifdef ENABLE_PAM_AUTH
    if (!m_pamAuth || !m_pamAuth->isAvailable()) {
        result.errorMessage = "PAM authentication not available";
        result.errorCode = "PAM_AUTH_UNAVAILABLE";
        return result;
    }

    try {
        // Authenticate with PAM
        PamAuthResult pamResult = m_pamAuth->authenticate(username, password);
        if (!pamResult.success) {
            result.errorMessage = pamResult.errorMessage;
            result.errorCode = pamResult.errorCode;
            return result;
        }

        // Check if user exists in our system or create guest user
        UserInfo user;
        auto it = m_users.find(username);
        if (it != m_users.end()) {
            user = it->second;
        } else {
            // Create guest user for PAM authentication
            user.id = generateUserId();
            user.username = username;
            user.email = username + "@localhost";
            user.role = roleToString(UserRole::USER);
            user.permissions = getDefaultPermissions(UserRole::USER);
            user.active = true;
            user.createdAt = getCurrentTimestamp();
            user.createdBy = "system";

            m_users[username] = user;
            saveUserData();
        }

        // Authentication successful
        result.success = true;
        result.userId = user.id;
        result.username = user.username;
        result.role = user.role;
        result.permissions = user.permissions;

    } catch (const std::exception& e) {
        result.errorMessage = "PAM authentication failed: " + std::string(e.what());
        result.errorCode = "PAM_AUTH_ERROR";
    }
#else
    result.errorMessage = "PAM authentication not available (compiled without PAM support)";
    result.errorCode = "PAM_NOT_AVAILABLE";
#endif

    return result;
}

AuthResult UserManager::authenticateApiKey(const std::string& apiKey) {
    AuthResult result;
    result.success = false;

    try {
        // Hash the API key to compare with stored hashes
        std::string keyHash = hashApiKey(apiKey);

        auto it = m_apiKeyMap.find(keyHash);
        if (it == m_apiKeyMap.end()) {
            result.errorMessage = "Invalid API key";
            result.errorCode = "INVALID_API_KEY";
            return result;
        }

        const std::string& keyId = it->second;
        const ApiKeyInfo& keyInfo = m_apiKeys[keyId];

        // Check if key is active
        if (!keyInfo.active) {
            result.errorMessage = "API key is disabled";
            result.errorCode = "API_KEY_DISABLED";
            return result;
        }

        // Check expiration
        if (keyInfo.expiresAt > 0 && getCurrentTimestamp() >= keyInfo.expiresAt) {
            result.errorMessage = "API key has expired";
            result.errorCode = "API_KEY_EXPIRED";
            return result;
        }

        // Get user information
        auto userIt = m_users.find(keyInfo.userId);
        if (userIt == m_users.end()) {
            result.errorMessage = "API key owner not found";
            result.errorCode = "USER_NOT_FOUND";
            return result;
        }

        const UserInfo& user = userIt->second;
        if (!user.active) {
            result.errorMessage = "API key owner account is disabled";
            result.errorCode = "ACCOUNT_DISABLED";
            return result;
        }

        // Authentication successful
        result.success = true;
        result.userId = user.id;
        result.username = user.username;
        result.role = user.role;
        result.permissions = keyInfo.permissions.empty() ? user.permissions : keyInfo.permissions;

        // Update last used timestamp
        m_apiKeys[keyId].lastUsedAt = getCurrentTimestamp();
        saveApiKeyData();

    } catch (const std::exception& e) {
        result.errorMessage = "API key authentication failed: " + std::string(e.what());
        result.errorCode = "API_KEY_AUTH_ERROR";
    }

    return result;
}

std::pair<bool, std::string> UserManager::createUser(const std::string& username,
                                                     const std::string& password,
                                                     const std::string& email,
                                                     UserRole role,
                                                     const std::string& createdBy) {
    try {
        // Validate inputs
        if (!validateUsername(username)) {
            return {false, "Invalid username format"};
        }

        if (!validatePassword(password)) {
            return {false, "Password does not meet requirements"};
        }

        if (!validateEmail(email)) {
            return {false, "Invalid email format"};
        }

        // Check if user already exists
        if (m_users.find(username) != m_users.end()) {
            return {false, "User already exists"};
        }

        // Create user
        UserInfo user;
        user.id = generateUserId();
        user.username = username;
        user.email = email;
        user.passwordHash = hashPassword(password);
        user.role = roleToString(role);
        user.permissions = getDefaultPermissions(role);
        user.active = true;
        user.createdAt = getCurrentTimestamp();
        user.passwordChangedAt = getCurrentTimestamp();
        user.createdBy = createdBy;

        m_users[username] = user;
        saveUserData();

        return {true, user.id};

    } catch (const std::exception& e) {
        return {false, "Failed to create user: " + std::string(e.what())};
    }
}

std::pair<bool, std::string> UserManager::updateUser(const std::string& userId,
                                                     const std::map<std::string, std::string>& updates) {
    try {
        // Find user by ID
        std::string username;
        for (const auto& pair : m_users) {
            if (pair.second.id == userId) {
                username = pair.first;
                break;
            }
        }

        if (username.empty()) {
            return {false, "User not found"};
        }

        UserInfo& user = m_users[username];

        // Update allowed fields
        for (const auto& update : updates) {
            const std::string& field = update.first;
            const std::string& value = update.second;

            if (field == "email") {
                if (!validateEmail(value)) {
                    return {false, "Invalid email format"};
                }
                user.email = value;
            } else if (field == "role") {
                user.role = value;
                user.permissions = getDefaultPermissions(stringToRole(value));
            } else if (field == "active") {
                user.active = (value == "true" || value == "1");
            }
        }

        saveUserData();
        return {true, "User updated successfully"};

    } catch (const std::exception& e) {
        return {false, "Failed to update user: " + std::string(e.what())};
    }
}

std::pair<bool, std::string> UserManager::deleteUser(const std::string& userId,
                                                     const std::string& requestingUserId) {
    try {
        // Find user by ID
        std::string username;
        for (const auto& pair : m_users) {
            if (pair.second.id == userId) {
                username = pair.first;
                break;
            }
        }

        if (username.empty()) {
            return {false, "User not found"};
        }

        // Check permissions
        if (!canManageUser(requestingUserId, userId)) {
            return {false, "Insufficient permissions to delete user"};
        }

        // Delete user's API keys
        auto it = m_apiKeys.begin();
        while (it != m_apiKeys.end()) {
            if (it->second.userId == userId) {
                m_apiKeyMap.erase(it->second.keyHash);
                it = m_apiKeys.erase(it);
            } else {
                ++it;
            }
        }

        // Delete user
        m_users.erase(username);
        saveUserData();
        saveApiKeyData();

        return {true, "User deleted successfully"};

    } catch (const std::exception& e) {
        return {false, "Failed to delete user: " + std::string(e.what())};
    }
}

std::pair<bool, std::string> UserManager::changePassword(const std::string& userId,
                                                          const std::string& oldPassword,
                                                          const std::string& newPassword,
                                                          const std::string& requestingUserId) {
    try {
        // Find user by ID
        std::string username;
        for (const auto& pair : m_users) {
            if (pair.second.id == userId) {
                username = pair.first;
                break;
            }
        }

        if (username.empty()) {
            return {false, "User not found"};
        }

        UserInfo& user = m_users[username];

        // Check permissions (admin can change without old password)
        if (requestingUserId != userId) {
            if (!canManageUser(requestingUserId, userId)) {
                return {false, "Insufficient permissions to change password"};
            }
        } else {
            // User changing own password - verify old password
            if (!verifyPassword(oldPassword, user.passwordHash)) {
                return {false, "Current password is incorrect"};
            }
        }

        // Validate new password
        if (!validatePassword(newPassword)) {
            return {false, "New password does not meet requirements"};
        }

        // Update password
        user.passwordHash = hashPassword(newPassword);
        user.passwordChangedAt = getCurrentTimestamp();
        saveUserData();

        return {true, "Password changed successfully"};

    } catch (const std::exception& e) {
        return {false, "Failed to change password: " + std::string(e.what())};
    }
}

UserInfo UserManager::getUserInfo(const std::string& userId) {
    for (const auto& pair : m_users) {
        if (pair.second.id == userId) {
            return pair.second;
        }
    }
    return UserInfo{};
}

UserInfo UserManager::getUserInfoByUsername(const std::string& username) {
    auto it = m_users.find(username);
    if (it != m_users.end()) {
        return it->second;
    }
    return UserInfo{};
}

std::vector<UserInfo> UserManager::listUsers(const std::string& requestingUserId) {
    std::vector<UserInfo> users;

    // Check if requester is admin
    UserInfo requester = getUserInfo(requestingUserId);
    bool isAdmin = (requester.role == roleToString(UserRole::ADMIN));

    for (const auto& pair : m_users) {
        const UserInfo& user = pair.second;

        // Non-admins can only see themselves
        if (!isAdmin && user.id != requestingUserId) {
            continue;
        }

        // Don't include sensitive information for non-admins
        UserInfo userInfo = user;
        if (!isAdmin) {
            userInfo.passwordHash = "";
            userInfo.apiKeys.clear();
        }

        users.push_back(userInfo);
    }

    return users;
}

std::pair<bool, std::string> UserManager::createApiKey(const std::string& userId,
                                                        const std::string& name,
                                                        const std::vector<std::string>& permissions,
                                                        int64_t expiresAt,
                                                        const std::string& createdBy) {
    try {
        // Check if user exists
        bool userExists = false;
        for (const auto& pair : m_users) {
            if (pair.second.id == userId) {
                userExists = true;
                break;
            }
        }

        if (!userExists) {
            return {false, "User not found"};
        }

        // Generate API key
        std::string apiKey = JWTAuth::generateApiKey(32);
        std::string keyId = generateKeyId();
        std::string keyHash = hashApiKey(apiKey);

        // Create API key info
        ApiKeyInfo keyInfo;
        keyInfo.keyId = keyId;
        keyInfo.keyHash = keyHash;
        keyInfo.name = name;
        keyInfo.userId = userId;
        keyInfo.permissions = permissions;
        keyInfo.active = true;
        keyInfo.createdAt = getCurrentTimestamp();
        keyInfo.lastUsedAt = 0;
        keyInfo.expiresAt = expiresAt;
        keyInfo.createdBy = createdBy;

        m_apiKeys[keyId] = keyInfo;
        m_apiKeyMap[keyHash] = keyId;
        saveApiKeyData();

        return {true, apiKey};

    } catch (const std::exception& e) {
        return {false, "Failed to create API key: " + std::string(e.what())};
    }
}

std::pair<bool, std::string> UserManager::revokeApiKey(const std::string& keyId,
                                                       const std::string& requestingUserId) {
    try {
        auto it = m_apiKeys.find(keyId);
        if (it == m_apiKeys.end()) {
            return {false, "API key not found"};
        }

        const ApiKeyInfo& keyInfo = it->second;

        // Check permissions
        if (keyInfo.userId != requestingUserId) {
            if (!canManageUser(requestingUserId, keyInfo.userId)) {
                return {false, "Insufficient permissions to revoke API key"};
            }
        }

        // Remove API key
        m_apiKeyMap.erase(keyInfo.keyHash);
        m_apiKeys.erase(it);
        saveApiKeyData();

        return {true, "API key revoked successfully"};

    } catch (const std::exception& e) {
        return {false, "Failed to revoke API key: " + std::string(e.what())};
    }
}

std::vector<ApiKeyInfo> UserManager::listApiKeys(const std::string& userId,
                                                  const std::string& requestingUserId) {
    std::vector<ApiKeyInfo> apiKeys;

    // Check if requester is admin or owner
    UserInfo requester = getUserInfo(requestingUserId);
    bool isAdmin = (requester.role == roleToString(UserRole::ADMIN));
    bool isOwner = (requestingUserId == userId);

    for (const auto& pair : m_apiKeys) {
        const ApiKeyInfo& keyInfo = pair.second;

        // Filter by user ID if specified
        if (!userId.empty() && keyInfo.userId != userId) {
            continue;
        }

        // Check permissions
        if (!isAdmin && keyInfo.userId != requestingUserId) {
            continue;
        }

        // Don't include hash for non-owners
        ApiKeyInfo keyInfoCopy = keyInfo;
        if (!isOwner && !isAdmin) {
            keyInfoCopy.keyHash = "";
        }

        apiKeys.push_back(keyInfoCopy);
    }

    return apiKeys;
}

ApiKeyInfo UserManager::getApiKeyInfo(const std::string& keyId,
                                       const std::string& requestingUserId) {
    auto it = m_apiKeys.find(keyId);
    if (it == m_apiKeys.end()) {
        return ApiKeyInfo{};
    }

    const ApiKeyInfo& keyInfo = it->second;

    // Check permissions
    UserInfo requester = getUserInfo(requestingUserId);
    bool isAdmin = (requester.role == roleToString(UserRole::ADMIN));
    bool isOwner = (keyInfo.userId == requestingUserId);

    if (!isAdmin && !isOwner) {
        return ApiKeyInfo{};
    }

    // Don't include hash for non-owners
    ApiKeyInfo keyInfoCopy = keyInfo;
    if (!isOwner) {
        keyInfoCopy.keyHash = "";
    }

    return keyInfoCopy;
}

void UserManager::updateApiKeyLastUsed(const std::string& keyId) {
    auto it = m_apiKeys.find(keyId);
    if (it != m_apiKeys.end()) {
        it->second.lastUsedAt = getCurrentTimestamp();
        saveApiKeyData();
    }
}

bool UserManager::hasPermission(const std::string& userId, const std::string& permission) {
    UserInfo user = getUserInfo(userId);
    if (user.id.empty()) {
        return false;
    }

    return JWTAuth::hasPermission(user.permissions, permission);
}

bool UserManager::hasAnyPermission(const std::string& userId,
                                   const std::vector<std::string>& permissions) {
    UserInfo user = getUserInfo(userId);
    if (user.id.empty()) {
        return false;
    }

    return JWTAuth::hasAnyPermission(user.permissions, permissions);
}

std::string UserManager::roleToString(UserRole role) {
    switch (role) {
        case UserRole::GUEST: return "guest";
        case UserRole::USER: return "user";
        case UserRole::ADMIN: return "admin";
        case UserRole::SERVICE: return "service";
        default: return "unknown";
    }
}

UserManager::UserRole UserManager::stringToRole(const std::string& roleStr) {
    if (roleStr == "guest") return UserRole::GUEST;
    if (roleStr == "user") return UserRole::USER;
    if (roleStr == "admin") return UserRole::ADMIN;
    if (roleStr == "service") return UserRole::SERVICE;
    return UserRole::USER; // Default
}

std::vector<std::string> UserManager::getDefaultPermissions(UserRole role) {
    switch (role) {
        case UserRole::GUEST:
            return {Permissions::READ};
        case UserRole::USER:
            return {Permissions::READ, Permissions::GENERATE};
        case UserRole::ADMIN:
            return {Permissions::READ, Permissions::GENERATE, Permissions::QUEUE_MANAGE,
                    Permissions::MODEL_MANAGE, Permissions::USER_MANAGE, Permissions::ADMIN};
        case UserRole::SERVICE:
            return {Permissions::READ, Permissions::GENERATE, Permissions::QUEUE_MANAGE};
        default:
            return {};
    }
}

void UserManager::setAuthMethod(AuthMethod method) {
    m_authMethod = method;
}

UserManager::AuthMethod UserManager::getAuthMethod() const {
    return m_authMethod;
}


void UserManager::setPamAuthEnabled(bool enable) {
    m_pamAuthEnabled = enable;

#ifdef ENABLE_PAM_AUTH
    if (enable && m_pamAuth && !m_pamAuth->isAvailable()) {
        if (!m_pamAuth->initialize()) {
            m_pamAuthEnabled = false;
        }
    }
#endif
}

bool UserManager::isPamAuthEnabled() const {
    return m_pamAuthEnabled;
}

std::map<std::string, int> UserManager::getStatistics() {
    std::map<std::string, int> stats;

    stats["total_users"] = m_users.size();
    stats["active_users"] = 0;
    stats["admin_users"] = 0;
    stats["total_api_keys"] = m_apiKeys.size();
    stats["active_api_keys"] = 0;
    stats["expired_api_keys"] = 0;

    int64_t currentTime = getCurrentTimestamp();

    for (const auto& pair : m_users) {
        const UserInfo& user = pair.second;
        if (user.active) {
            stats["active_users"]++;
        }
        if (user.role == roleToString(UserRole::ADMIN)) {
            stats["admin_users"]++;
        }
    }

    for (const auto& pair : m_apiKeys) {
        const ApiKeyInfo& keyInfo = pair.second;
        if (keyInfo.active) {
            stats["active_api_keys"]++;
        }
        if (keyInfo.expiresAt > 0 && currentTime >= keyInfo.expiresAt) {
            stats["expired_api_keys"]++;
        }
    }

    return stats;
}

std::string UserManager::hashPassword(const std::string& password) {
    // Simple SHA256 hash for now (in production, use proper password hashing like bcrypt/argon2)
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256((unsigned char*)password.c_str(), password.length(), hash);

    std::stringstream ss;
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
        ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
    }

    return "sha256:" + ss.str();
}

bool UserManager::verifyPassword(const std::string& password, const std::string& storedHash) {
    // Simple SHA256 verification (in production, use proper password hashing)
    if (storedHash.substr(0, 7) != "sha256:") {
        return false;
    }

    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256((unsigned char*)password.c_str(), password.length(), hash);

    std::stringstream ss;
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
        ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
    }

    return "sha256:" + ss.str() == storedHash;
}

std::string UserManager::hashApiKey(const std::string& apiKey) {
    // Use SHA256 for API key hashing
    unsigned char hash[SHA256_DIGEST_LENGTH];
    SHA256((unsigned char*)apiKey.c_str(), apiKey.length(), hash);

    std::stringstream ss;
    for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
        ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i];
    }

    return ss.str();
}

std::string UserManager::generateUserId() {
    return "user_" + std::to_string(getCurrentTimestamp()) + "_" +
           std::to_string(rand() % 10000);
}

std::string UserManager::generateKeyId() {
    return "key_" + std::to_string(getCurrentTimestamp()) + "_" +
           std::to_string(rand() % 10000);
}

bool UserManager::saveUserData() {
    try {
        nlohmann::json usersData = nlohmann::json::object();

        for (const auto& pair : m_users) {
            const UserInfo& user = pair.second;
            nlohmann::json userData = {
                {"id", user.id},
                {"username", user.username},
                {"email", user.email},
                {"password_hash", user.passwordHash},
                {"role", user.role},
                {"permissions", user.permissions},
                {"api_keys", user.apiKeys},
                {"active", user.active},
                {"created_at", user.createdAt},
                {"last_login_at", user.lastLoginAt},
                {"password_changed_at", user.passwordChangedAt},
                {"created_by", user.createdBy}
            };
            usersData[user.username] = userData;
        }

        std::string filename = m_dataDir + "/users.json";
        std::ofstream file(filename);
        if (!file.is_open()) {
            return false;
        }

        file << usersData.dump(2);
        file.close();

        return true;

    } catch (const std::exception& e) {
        return false;
    }
}

bool UserManager::loadUserData() {
    try {
        std::string filename = m_dataDir + "/users.json";
        std::ifstream file(filename);
        if (!file.is_open()) {
            return false; // File doesn't exist is OK for first run
        }

        nlohmann::json usersJson;
        file >> usersJson;
        file.close();

        m_users.clear();

        for (auto& item : usersJson.items()) {
            const std::string& username = item.key();
            nlohmann::json& userJson = item.value();

            UserInfo user;
            user.id = userJson.value("id", "");
            user.username = userJson.value("username", username);
            user.email = userJson.value("email", "");
            user.passwordHash = userJson.value("password_hash", "");
            user.role = userJson.value("role", "user");
            user.permissions = userJson.value("permissions", std::vector<std::string>{});
            user.apiKeys = userJson.value("api_keys", std::vector<std::string>{});
            user.active = userJson.value("active", true);
            user.createdAt = userJson.value("created_at", 0);
            user.lastLoginAt = userJson.value("last_login_at", 0);
            user.passwordChangedAt = userJson.value("password_changed_at", 0);
            user.createdBy = userJson.value("created_by", "system");

            m_users[username] = user;
        }

        return true;

    } catch (const std::exception& e) {
        return false;
    }
}

bool UserManager::saveApiKeyData() {
    try {
        nlohmann::json apiKeysData = nlohmann::json::object();

        for (const auto& pair : m_apiKeys) {
            const ApiKeyInfo& keyInfo = pair.second;
            nlohmann::json keyData = {
                {"key_id", keyInfo.keyId},
                {"key_hash", keyInfo.keyHash},
                {"name", keyInfo.name},
                {"user_id", keyInfo.userId},
                {"permissions", keyInfo.permissions},
                {"active", keyInfo.active},
                {"created_at", keyInfo.createdAt},
                {"last_used_at", keyInfo.lastUsedAt},
                {"expires_at", keyInfo.expiresAt},
                {"created_by", keyInfo.createdBy}
            };
            apiKeysData[keyInfo.keyId] = keyData;
        }

        std::string filename = m_dataDir + "/api_keys.json";
        std::ofstream file(filename);
        if (!file.is_open()) {
            return false;
        }

        file << apiKeysData.dump(2);
        file.close();

        return true;

    } catch (const std::exception& e) {
        return false;
    }
}

bool UserManager::loadApiKeyData() {
    try {
        std::string filename = m_dataDir + "/api_keys.json";
        std::ifstream file(filename);
        if (!file.is_open()) {
            return false; // File doesn't exist is OK for first run
        }

        nlohmann::json apiKeysJson;
        file >> apiKeysJson;
        file.close();

        m_apiKeys.clear();
        m_apiKeyMap.clear();

        for (auto& item : apiKeysJson.items()) {
            const std::string& keyId = item.key();
            nlohmann::json& keyJson = item.value();

            ApiKeyInfo keyInfo;
            keyInfo.keyId = keyJson.value("key_id", keyId);
            keyInfo.keyHash = keyJson.value("key_hash", "");
            keyInfo.name = keyJson.value("name", "");
            keyInfo.userId = keyJson.value("user_id", "");
            keyInfo.permissions = keyJson.value("permissions", std::vector<std::string>{});
            keyInfo.active = keyJson.value("active", true);
            keyInfo.createdAt = keyJson.value("created_at", 0);
            keyInfo.lastUsedAt = keyJson.value("last_used_at", 0);
            keyInfo.expiresAt = keyJson.value("expires_at", 0);
            keyInfo.createdBy = keyJson.value("created_by", "system");

            m_apiKeys[keyId] = keyInfo;
            m_apiKeyMap[keyInfo.keyHash] = keyId;
        }

        return true;

    } catch (const std::exception& e) {
        return false;
    }
}

int64_t UserManager::getCurrentTimestamp() {
    return std::chrono::duration_cast<std::chrono::seconds>(
        std::chrono::system_clock::now().time_since_epoch()).count();
}

bool UserManager::validateUsername(const std::string& username) {
    if (username.length() < 3 || username.length() > 32) {
        return false;
    }

    // Username should contain only alphanumeric characters, underscores, and hyphens
    std::regex pattern("^[a-zA-Z0-9_-]+$");
    return std::regex_match(username, pattern);
}

bool UserManager::validatePassword(const std::string& password) {
    if (password.length() < 8 || password.length() > 128) {
        return false;
    }

    // Password should contain at least one letter and one digit
    bool hasLetter = false;
    bool hasDigit = false;

    for (char c : password) {
        if (std::isalpha(c)) hasLetter = true;
        if (std::isdigit(c)) hasDigit = true;
    }

    return hasLetter && hasDigit;
}

bool UserManager::validateEmail(const std::string& email) {
    if (email.length() < 5 || email.length() > 254) {
        return false;
    }

    // Basic email validation
    std::regex pattern("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");
    return std::regex_match(email, pattern);
}

bool UserManager::canManageUser(const std::string& requestingUserId, const std::string& targetUserId) {
    // Users can always manage themselves
    if (requestingUserId == targetUserId) {
        return true;
    }

    // Check if requester is admin
    UserInfo requester = getUserInfo(requestingUserId);
    return requester.role == roleToString(UserRole::ADMIN);
}
