<?php
/**
 * Authentication and Authorization Functions
 * Ultrasure Insurance Platform
 */

// 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() {
    return $_SESSION['user_data'] ?? null;
}

/**
 * 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;
    }
    
    // Super admins have all permissions
    if (isset($_SESSION['user_data']['role_name']) && $_SESSION['user_data']['role_name'] === 'Super Admin') {
        return true;
    }
    
    // Check if permission exists in user's permissions array
    if (isset($_SESSION['user_permissions']) && is_array($_SESSION['user_permissions'])) {
        return in_array($permission_name, $_SESSION['user_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;
    
    try {
        $stmt = $conn->prepare("
            SELECT DISTINCT p.name as permission_name 
            FROM users u
            JOIN user_roles ur ON u.role_id = ur.role_id
            JOIN role_permissions rp ON ur.role_id = rp.role_id
            JOIN permissions p ON rp.permission_id = p.permission_id
            WHERE u.user_id = ? AND u.status = 'ACTIVE' AND ur.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;
    
    try {
        $stmt = $conn->prepare("
            SELECT u.*, ur.role_name, b.branch_name
            FROM users u
            LEFT JOIN user_roles ur ON u.role_id = ur.role_id
            LEFT JOIN branches b ON u.branch_id = b.branch_id
            WHERE u.user_id = ? AND u.status = 'ACTIVE'
        ");
        
        $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['password_reset_token']);
            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['user_data'] = $user_data;
    $_SESSION['user_permissions'] = $permissions;
    $_SESSION['login_time'] = time();
    
    // 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;
    
    try {
        $stmt = $conn->prepare("UPDATE users SET last_login = NOW() WHERE user_id = ?");
        $stmt->bind_param("i", $user_id);
        $stmt->execute();
    } catch (Exception $e) {
        error_log("Error updating last login: " . $e->getMessage());
    }
}

/**
 * Logout user
 */
function logout() {
    // Log activity
    if (isLoggedIn()) {
        logActivity(getCurrentUserId(), 'LOGOUT', 'AUTH', null, null, null);
    }
    
    // Destroy session
    session_destroy();
    
    // 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
 * @param int $user_id
 * @param string $action
 * @param string $module
 * @param int $record_id
 * @param array $old_values
 * @param array $new_values
 */
function logActivity($user_id, $action, $module, $record_id = null, $old_values = null, $new_values = null) {
    global $conn;
    
    try {
        $stmt = $conn->prepare("
            INSERT INTO activity_log 
            (user_id, action, module, record_id, old_values, new_values, ip_address, user_agent, session_id) 
            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
        ");
        
        $ip_address = $_SERVER['REMOTE_ADDR'] ?? null;
        $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? null;
        $session_id = session_id();
        $old_values_json = $old_values ? json_encode($old_values) : null;
        $new_values_json = $new_values ? json_encode($new_values) : null;
        
        $stmt->bind_param("issiissss", 
            $user_id, $action, $module, $record_id, 
            $old_values_json, $new_values_json, 
            $ip_address, $user_agent, $session_id
        );
        
        $stmt->execute();
        
    } catch (Exception $e) {
        error_log("Error logging activity: " . $e->getMessage());
    }
}

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

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

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

/**
 * Get user avatar/profile picture
 */
function getUserAvatar() {
    $user_data = getCurrentUser();
    $profile_picture = $user_data['profile_picture'] ?? null;
    
    if ($profile_picture && file_exists($profile_picture)) {
        return $profile_picture;
    }
    
    // Return default avatar
    return 'assets/images/avatars/default-avatar.png';
}

/**
 * Check if current user is agent
 */
function isAgent() {
    $user_data = getCurrentUser();
    return !empty($user_data['agent_code']);
}

/**
 * Get agent code for current user
 */
function getAgentCode() {
    $user_data = getCurrentUser();
    return $user_data['agent_code'] ?? null;
}

/**
 * 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) . '">';
}

?>