<?php
/*******************************************************************************************************************
| RBAC Helper Functions
| Convenience functions for role-based access control
|*******************************************************************************************************************/

defined('_ISVALID') or header('Location: /error');

/**
 * Check if current user has permission
 * @param string $permission Permission name
 * @param array $context Additional context
 * @return bool True if user has permission
 */
function has_permission($permission, $context = [])
{
    $rbac = VRBAC::getInstance();
    return $rbac->hasPermission('current', $permission, $context);
}

/**
 * Check if user has permission
 * @param int $userId User ID
 * @param string $permission Permission name
 * @param array $context Additional context
 * @return bool True if user has permission
 */
function user_has_permission($userId, $permission, $context = [])
{
    $rbac = VRBAC::getInstance();
    return $rbac->hasPermission($userId, $permission, $context);
}

/**
 * Require permission or redirect/exit
 * @param string $permission Permission name
 * @param array $context Additional context
 * @param string $redirectUrl Redirect URL on failure
 * @param string $errorMessage Error message
 */
function require_permission($permission, $context = [], $redirectUrl = '/error', $errorMessage = 'Access denied')
{
    if (!has_permission($permission, $context)) {
        if ($redirectUrl) {
            header("Location: {$redirectUrl}");
            exit;
        } else {
            http_response_code(403);
            die($errorMessage);
        }
    }
}

/**
 * Get current user roles
 * @return array User roles
 */
function get_user_roles($userId = null)
{
    $rbac = VRBAC::getInstance();
    $userId = $userId ?: ($_SESSION['USER_ID'] ?? null);
    
    if (!$userId) {
        return [VRBAC::ROLE_GUEST];
    }
    
    return $rbac->getUserRoles($userId);
}

/**
 * Check if user has role
 * @param string $role Role name
 * @param int $userId User ID (optional, defaults to current user)
 * @return bool True if user has role
 */
function user_has_role($role, $userId = null)
{
    $userRoles = get_user_roles($userId);
    return in_array($role, $userRoles);
}

/**
 * Check if current user is admin
 * @return bool True if user is admin
 */
function is_admin()
{
    return user_has_role(VRBAC::ROLE_ADMIN) || user_has_role(VRBAC::ROLE_SUPER_ADMIN);
}

/**
 * Check if current user is moderator or higher
 * @return bool True if user is moderator or higher
 */
function is_moderator()
{
    return user_has_role(VRBAC::ROLE_MODERATOR) || is_admin();
}

/**
 * Check if current user is verified
 * @return bool True if user is verified
 */
function is_verified()
{
    $roles = get_user_roles();
    return !in_array(VRBAC::ROLE_GUEST, $roles) && !empty(array_intersect($roles, [
        VRBAC::ROLE_VERIFIED, VRBAC::ROLE_CREATOR, VRBAC::ROLE_MODERATOR, 
        VRBAC::ROLE_ADMIN, VRBAC::ROLE_SUPER_ADMIN
    ]));
}

/**
 * Assign role to user
 * @param int $userId User ID
 * @param string $role Role name
 * @param string $reason Reason for assignment
 * @return bool Success status
 */
function assign_user_role($userId, $role, $reason = '')
{
    $rbac = VRBAC::getInstance();
    $assignedBy = $_SESSION['USER_ID'] ?? null;
    
    return $rbac->assignRole($userId, $role, $assignedBy, $reason);
}

/**
 * Remove role from user
 * @param int $userId User ID
 * @param string $role Role name
 * @param string $reason Reason for removal
 * @return bool Success status
 */
function remove_user_role($userId, $role, $reason = '')
{
    $rbac = VRBAC::getInstance();
    $removedBy = $_SESSION['USER_ID'] ?? null;
    
    return $rbac->removeRole($userId, $role, $removedBy, $reason);
}

/**
 * Get permission-based navigation menu
 * @return array Navigation menu items
 */
function get_permission_menu()
{
    $menu = [];
    
    // Public menu items
    $menu[] = ['title' => 'Home', 'url' => '/', 'permission' => 'content.view'];
    $menu[] = ['title' => 'Browse', 'url' => '/videos', 'permission' => 'content.view'];
    $menu[] = ['title' => 'Search', 'url' => '/search', 'permission' => 'content.search'];
    
    // Member menu items
    if (has_permission('user.upload.basic')) {
        $menu[] = ['title' => 'Upload', 'url' => '/upload', 'permission' => 'user.upload.basic'];
    }
    
    // Creator menu items
    if (has_permission('live.stream.basic')) {
        $menu[] = ['title' => 'Go Live', 'url' => '/live', 'permission' => 'live.stream.basic'];
    }
    
    if (has_permission('analytics.view')) {
        $menu[] = ['title' => 'Analytics', 'url' => '/analytics', 'permission' => 'analytics.view'];
    }
    
    // Admin menu items
    if (has_permission('admin.dashboard')) {
        $menu[] = ['title' => 'Admin', 'url' => '/admin', 'permission' => 'admin.dashboard'];
    }
    
    // Filter menu items based on permissions
    return array_filter($menu, function($item) {
        return has_permission($item['permission']);
    });
}

/**
 * Get user role display name
 * @param string $role Role name
 * @return string Display name
 */
function get_role_display_name($role)
{
    $displayNames = [
        VRBAC::ROLE_GUEST => 'Guest',
        VRBAC::ROLE_MEMBER => 'Member',
        VRBAC::ROLE_VERIFIED => 'Verified User',
        VRBAC::ROLE_CREATOR => 'Content Creator',
        VRBAC::ROLE_MODERATOR => 'Moderator',
        VRBAC::ROLE_ADMIN => 'Administrator',
        VRBAC::ROLE_SUPER_ADMIN => 'Super Administrator'
    ];
    
    return $displayNames[$role] ?? ucfirst(str_replace('_', ' ', $role));
}

/**
 * Get available roles for assignment
 * @return array Available roles
 */
function get_assignable_roles()
{
    $roles = [
        VRBAC::ROLE_MEMBER => 'Member',
        VRBAC::ROLE_VERIFIED => 'Verified User',
        VRBAC::ROLE_CREATOR => 'Content Creator'
    ];
    
    // Add moderator and admin roles if user has permission
    if (has_permission('admin.users.manage')) {
        $roles[VRBAC::ROLE_MODERATOR] = 'Moderator';
        
        if (user_has_role(VRBAC::ROLE_SUPER_ADMIN)) {
            $roles[VRBAC::ROLE_ADMIN] = 'Administrator';
        }
    }
    
    return $roles;
}

/**
 * Check content ownership or permission
 * @param string $resourceType Resource type (video, channel, playlist)
 * @param string $resourceId Resource ID
 * @param string $permission Required permission
 * @return bool True if user owns resource or has permission
 */
function can_access_resource($resourceType, $resourceId, $permission)
{
    $context = [
        'resource_type' => $resourceType,
        'resource_id' => $resourceId
    ];
    
    return has_permission($permission, $context);
}

/**
 * Get user's highest role
 * @param int $userId User ID (optional)
 * @return string Highest role
 */
function get_highest_role($userId = null)
{
    $roles = get_user_roles($userId);
    
    $roleHierarchy = [
        VRBAC::ROLE_SUPER_ADMIN => 7,
        VRBAC::ROLE_ADMIN => 6,
        VRBAC::ROLE_MODERATOR => 5,
        VRBAC::ROLE_CREATOR => 4,
        VRBAC::ROLE_VERIFIED => 3,
        VRBAC::ROLE_MEMBER => 2,
        VRBAC::ROLE_GUEST => 1
    ];
    
    $highestRole = VRBAC::ROLE_GUEST;
    $highestLevel = 0;
    
    foreach ($roles as $role) {
        $level = $roleHierarchy[$role] ?? 0;
        if ($level > $highestLevel) {
            $highestLevel = $level;
            $highestRole = $role;
        }
    }
    
    return $highestRole;
}

/**
 * Create permission middleware for routes
 * @param string $permission Required permission
 * @param array $context Permission context
 * @return callable Middleware function
 */
function permission_middleware($permission, $context = [])
{
    return function() use ($permission, $context) {
        if (!has_permission($permission, $context)) {
            http_response_code(403);
            
            if (isset($_SESSION['USER_ID'])) {
                // Logged in user without permission
                include _FPATH . 'f_templates/tpl_frontend/tpl_error/tpl_403.tpl';
            } else {
                // Not logged in - redirect to login
                header('Location: /signin?redirect=' . urlencode($_SERVER['REQUEST_URI']));
            }
            exit;
        }
    };
}

/**
 * Get permission-based upload limits
 * @return array Upload limits
 */
function get_upload_limits()
{
    $limits = [
        'max_file_size' => 50 * 1024 * 1024, // 50MB default
        'max_duration' => 600, // 10 minutes default
        'allowed_formats' => ['mp4', 'avi', 'mov'],
        'max_uploads_per_day' => 5
    ];
    
    if (has_permission('user.upload.advanced')) {
        $limits['max_file_size'] = 500 * 1024 * 1024; // 500MB
        $limits['max_duration'] = 3600; // 1 hour
        $limits['allowed_formats'] = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'webm', 'mkv'];
        $limits['max_uploads_per_day'] = 20;
    }
    
    if (user_has_role(VRBAC::ROLE_CREATOR)) {
        $limits['max_file_size'] = 2 * 1024 * 1024 * 1024; // 2GB
        $limits['max_duration'] = 7200; // 2 hours
        $limits['max_uploads_per_day'] = 50;
    }
    
    if (is_admin()) {
        $limits['max_file_size'] = -1; // Unlimited
        $limits['max_duration'] = -1; // Unlimited
        $limits['max_uploads_per_day'] = -1; // Unlimited
    }
    
    return $limits;
}

/**
 * Log security event
 * @param string $event Event description
 * @param array $context Event context
 */
if (!function_exists('log_security_event')) {
    function log_security_event($event, $context = [])
    {
        VSecurity::logSecurityEvent($event, $context);
    }
}