<?php
/**
 * Authentication and Authorization Functions
 * Kenyan Pension & Life Insurance Management System
 */

// Start session if not already started
if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

/**
 * Check if user is logged in
 */
function isLoggedIn() {
    return isset($_SESSION['user_id']) && !empty($_SESSION['user_id']);
}

/**
 * Get current user ID
 */
function getCurrentUserId() {
    return $_SESSION['user_id'] ?? null;
}

/**
 * Get current user data
 */
function getCurrentUser() {
    if (!isLoggedIn()) {
        return null;
    }
    
    return [
        'user_id' => $_SESSION['user_id'] ?? null,
        'username' => $_SESSION['username'] ?? null,
        'email' => $_SESSION['email'] ?? null,
        'full_name' => $_SESSION['full_name'] ?? null,
        'first_name' => $_SESSION['first_name'] ?? null,
        'last_name' => $_SESSION['last_name'] ?? null,
        'phone_number' => $_SESSION['phone_number'] ?? null,
        'role_id' => $_SESSION['role_id'] ?? null,
        'role_name' => $_SESSION['role_name'] ?? null,
        'user_permissions' => $_SESSION['user_permissions'] ?? []
    ];
}

/**
 * Check if user has specific permission
 * @param string $permission_name The permission to check
 * @return bool
 */
function hasPermission($permission_name) {
    // If user is not logged in, deny permission
    if (!isLoggedIn()) {
        return false;
    }
    
    // Admins have all permissions (check role name)
    $role_name = $_SESSION['role_name'] ?? '';
    if (in_array(strtoupper($role_name), ['ADMIN', 'SUPER ADMIN', 'SUPERADMIN'])) {
        return true;
    }
    
    // Check if permission exists in user's permissions array
    $permissions = $_SESSION['user_permissions'] ?? [];
    if (is_array($permissions)) {
        return in_array($permission_name, $permissions);
    }
    
    return false;
}

/**
 * Check if user has any of the specified permissions
 * @param array $permissions Array of permission names
 * @return bool
 */
function hasAnyPermission($permissions) {
    if (!is_array($permissions)) {
        return hasPermission($permissions);
    }
    
    foreach ($permissions as $permission) {
        if (hasPermission($permission)) {
            return true;
        }
    }
    
    return false;
}

/**
 * Check if user has all specified permissions
 * @param array $permissions Array of permission names
 * @return bool
 */
function hasAllPermissions($permissions) {
    if (!is_array($permissions)) {
        return hasPermission($permissions);
    }
    
    foreach ($permissions as $permission) {
        if (!hasPermission($permission)) {
            return false;
        }
    }
    
    return true;
}

/**
 * Require user to be logged in
 * Redirects to login page if not logged in
 */
function requireLogin() {
    if (!isLoggedIn()) {
        header('Location: login.php');
        exit();
    }
}

/**
 * Require specific permission
 * Shows 403 error if user doesn't have permission
 */
function requirePermission($permission_name) {
    requireLogin();
    
    if (!hasPermission($permission_name)) {
        http_response_code(403);
        include 'errors/403.php';
        exit();
    }
}

/**
 * Load user permissions from database
 * @param int $user_id
 * @return array
 */
function loadUserPermissions($user_id) {
    global $conn;
    
    if (!isset($conn)) {
        include 'layouts/dbconn.php';
    }
    
    try {
        $stmt = $conn->prepare("
            SELECT DISTINCT p.permission_name 
            FROM users u
            INNER JOIN roles r ON u.role_id = r.role_id
            INNER JOIN role_permissions rp ON r.role_id = rp.role_id
            INNER JOIN permissions p ON rp.permission_id = p.permission_id
            WHERE u.user_id = ? 
            AND u.status = 'ACTIVE' 
            AND u.deleted_at IS NULL
            AND r.is_active = 1
        ");
        
        $stmt->bind_param("i", $user_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        $permissions = [];
        while ($row = $result->fetch_assoc()) {
            $permissions[] = $row['permission_name'];
        }
        
        return $permissions;
        
    } catch (Exception $e) {
        error_log("Error loading user permissions: " . $e->getMessage());
        return [];
    }
}

/**
 * Get user data from database
 * @param int $user_id
 * @return array|null
 */
function getUserData($user_id) {
    global $conn;
    
    if (!isset($conn)) {
        include 'layouts/dbconn.php';
    }
    
    try {
        $stmt = $conn->prepare("
            SELECT u.*, r.role_name, r.role_id
            FROM users u
            INNER JOIN roles r ON u.role_id = r.role_id
            WHERE u.user_id = ? 
            AND u.status = 'ACTIVE'
            AND u.deleted_at IS NULL
        ");
        
        $stmt->bind_param("i", $user_id);
        $stmt->execute();
        $result = $stmt->get_result();
        
        if ($row = $result->fetch_assoc()) {
            // Remove sensitive data
            unset($row['password_hash']);
            unset($row['two_factor_secret']);
            return $row;
        }
        
        return null;
        
    } catch (Exception $e) {
        error_log("Error loading user data: " . $e->getMessage());
        return null;
    }
}

/**
 * Set user session data
 * @param int $user_id
 * @return bool
 */
function setUserSession($user_id) {
    // Get user data
    $user_data = getUserData($user_id);
    if (!$user_data) {
        return false;
    }
    
    // Load user permissions
    $permissions = loadUserPermissions($user_id);
    
    // Set session data
    $_SESSION['user_id'] = $user_id;
    $_SESSION['username'] = $user_data['username'];
    $_SESSION['email'] = $user_data['email'];
    $_SESSION['first_name'] = $user_data['first_name'];
    $_SESSION['last_name'] = $user_data['last_name'];
    $_SESSION['full_name'] = $user_data['first_name'] . ' ' . $user_data['last_name'];
    $_SESSION['phone_number'] = $user_data['phone_number'];
    $_SESSION['role_id'] = $user_data['role_id'];
    $_SESSION['role_name'] = $user_data['role_name'];
    $_SESSION['user_permissions'] = $permissions;
    $_SESSION['login_time'] = time();
    $_SESSION['session_token'] = bin2hex(random_bytes(32));
    
    // Update last login in database
    updateLastLogin($user_id);
    
    return true;
}

/**
 * Update user's last login time
 * @param int $user_id
 */
function updateLastLogin($user_id) {
    global $conn;
    
    if (!isset($conn)) {
        include 'layouts/dbconn.php';
    }
    
    try {
        $stmt = $conn->prepare("UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE user_id = ?");
        $stmt->bind_param("i", $user_id);
        $stmt->execute();
        $stmt->close();
    } catch (Exception $e) {
        error_log("Error updating last login: " . $e->getMessage());
    }
}

/**
 * Logout user
 */
function logout() {
    // Log activity before destroying session
    if (isLoggedIn()) {
        logActivity(getCurrentUserId(), 'USER_LOGOUT', 'SYSTEM', null, null);
    }
    
    // Destroy session
    session_unset();
    session_destroy();
    
    // Clear session cookie
    if (ini_get("session.use_cookies")) {
        $params = session_get_cookie_params();
        setcookie(
            session_name(),
            '',
            time() - 42000,
            $params["path"],
            $params["domain"],
            $params["secure"],
            $params["httponly"]
        );
    }
    
    // Redirect to login
    header('Location: login.php');
    exit();
}

/**
 * Check session timeout
 * @param int $timeout_minutes Default 120 minutes
 */
function checkSessionTimeout($timeout_minutes = 120) {
    if (isLoggedIn() && isset($_SESSION['login_time'])) {
        $elapsed = time() - $_SESSION['login_time'];
        
        if ($elapsed > ($timeout_minutes * 60)) {
            logout();
        }
        
        // Update activity time
        $_SESSION['last_activity'] = time();
    }
}

/**
 * Log user activity to audit_logs
 * @param int $user_id
 * @param string $event_type
 * @param string $event_category
 * @param int $entity_id
 * @param array $old_values
 * @param array $new_values
 */
function logActivity($user_id, $event_type, $event_category, $entity_id = null, $old_values = null, $new_values = null) {
    global $conn;
    
    if (!isset($conn)) {
        include 'layouts/dbconn.php';
    }
    
    try {
        $stmt = $conn->prepare("
            INSERT INTO audit_logs 
            (event_type, event_category, event_description, performed_by, ip_address, created_at) 
            VALUES (?, ?, ?, ?, ?, CURRENT_TIMESTAMP)
        ");
        
        $ip_address = $_SERVER['REMOTE_ADDR'] ?? null;
        $event_description = json_encode([
            'user_id' => $user_id,
            'entity_id' => $entity_id,
            'old_values' => $old_values,
            'new_values' => $new_values,
            'session_id' => session_id()
        ]);
        $performed_by = $_SESSION['username'] ?? 'SYSTEM';
        
        $stmt->bind_param("sssss", $event_type, $event_category, $event_description, $performed_by, $ip_address);
        $stmt->execute();
        $stmt->close();
        
    } catch (Exception $e) {
        error_log("Error logging activity: " . $e->getMessage());
    }
}

/**
 * Get user role display name
 */
function getUserRole() {
    return $_SESSION['role_name'] ?? 'Unknown';
}

/**
 * Get user full name
 */
function getUserFullName() {
    return $_SESSION['full_name'] ?? $_SESSION['username'] ?? 'Unknown User';
}

/**
 * Get user email
 */
function getUserEmail() {
    return $_SESSION['email'] ?? '';
}

/**
 * Check if current user is admin
 */
function isAdmin() {
    $role_name = strtoupper($_SESSION['role_name'] ?? '');
    return in_array($role_name, ['ADMIN', 'SUPER ADMIN', 'SUPERADMIN']);
}

/**
 * Check if current user is trustee
 */
function isTrustee() {
    $role_name = strtoupper($_SESSION['role_name'] ?? '');
    return $role_name === 'TRUSTEE';
}

/**
 * Check if current user is member
 */
function isMember() {
    $role_name = strtoupper($_SESSION['role_name'] ?? '');
    return $role_name === 'MEMBER';
}

/**
 * Check if current user is employer
 */
function isEmployer() {
    $role_name = strtoupper($_SESSION['role_name'] ?? '');
    return $role_name === 'EMPLOYER';
}

/**
 * Validate CSRF token
 */
function validateCSRFToken($token) {
    return isset($_SESSION['csrf_token']) && hash_equals($_SESSION['csrf_token'], $token);
}

/**
 * Generate CSRF token
 */
function generateCSRFToken() {
    if (!isset($_SESSION['csrf_token'])) {
        $_SESSION['csrf_token'] = bin2hex(random_bytes(32));
    }
    return $_SESSION['csrf_token'];
}

/**
 * Get CSRF token HTML input
 */
function getCSRFTokenInput() {
    $token = generateCSRFToken();
    return '<input type="hidden" name="csrf_token" value="' . htmlspecialchars($token) . '">';
}

?>
