<?php
/**
 * RBAC permissions helpers.
 *
 * Modules: dashboard, products, vendors, clients, purchases, purchase_returns,
 *          sales, sales_returns, inventory, reports, ledgers, settings
 * Actions: view, create, edit, delete, export, finalize
 *
 * Admin users (role = 'admin') always bypass all permission checks.
 */

/**
 * Load this user's permissions from DB into $_SESSION['permissions'].
 * Call once after company is resolved (login + company-switch).
 */
function loadPermissions(mysqli $conn): void
{
    // Admins never need a permission matrix
    if (($_SESSION['user_role'] ?? '') === 'admin') {
        $_SESSION['permissions'] = [];   // empty = "admin bypass" sentinel
        return;
    }

    $roleId = $_SESSION['user_role_id'] ?? null;
    if (!$roleId) {
        $_SESSION['permissions'] = null; // no role assigned → no access
        return;
    }

    $rid  = (int)$roleId;
    $rows = $conn->query("SELECT module, can_view, can_create, can_edit,
                                 can_delete, can_export, can_finalize
                          FROM role_permissions
                          WHERE role_id = $rid");

    $perms = [];
    while ($r = $rows->fetch_assoc()) {
        $perms[$r['module']] = [
            'view'     => (bool)$r['can_view'],
            'create'   => (bool)$r['can_create'],
            'edit'     => (bool)$r['can_edit'],
            'delete'   => (bool)$r['can_delete'],
            'export'   => (bool)$r['can_export'],
            'finalize' => (bool)$r['can_finalize'],
        ];
    }
    $_SESSION['permissions'] = $perms;
}

/**
 * Check if the current user has a specific permission.
 *
 * @param  string $module  e.g. 'sales'
 * @param  string $action  view|create|edit|delete|export|finalize
 * @return bool
 */
function hasPermission(string $module, string $action = 'view'): bool
{
    // Admin always has full access
    if (($_SESSION['user_role'] ?? '') === 'admin') {
        return true;
    }

    $perms = $_SESSION['permissions'] ?? null;

    // null means permissions not loaded or no role assigned
    if ($perms === null) {
        return false;
    }

    return (bool)($perms[$module][$action] ?? false);
}

/**
 * Halt execution with HTTP 403 if the user lacks the given permission.
 *
 * @param  string $module
 * @param  string $action
 * @param  string $redirect  Optional URL to redirect instead of showing error.
 */
function requirePermission(string $module, string $action = 'view', string $redirect = ''): void
{
    if (!hasPermission($module, $action)) {
        if ($redirect) {
            header('Location: ' . $redirect);
            exit;
        }
        http_response_code(403);
        $base = defined('BASE_URL') ? BASE_URL : '/abc';
        include __DIR__ . '/403.php';
        exit;
    }
}

/**
 * Return the URL of the first module the current user can view.
 * Used to redirect users who have no dashboard access after login.
 */
function getDefaultLandingUrl(): string
{
    $base = defined('BASE_URL') ? BASE_URL : '/abc';

    $map = [
        'dashboard'        => $base . '/dashboard.php',
        'sales'            => $base . '/sales/index.php',
        'purchases'        => $base . '/purchases/index.php',
        'clients'          => $base . '/clients/index.php',
        'vendors'          => $base . '/vendors/index.php',
        'products'         => $base . '/products/index.php',
        'purchase_returns' => $base . '/purchase_returns/index.php',
        'sales_returns'    => $base . '/sales_return/index.php',
        'inventory'        => $base . '/inventory/stocks.php',
        'reports'          => $base . '/reports/index.php',
        'ledgers'          => $base . '/client_ledger/index.php',
    ];

    foreach ($map as $module => $url) {
        if (hasPermission($module)) return $url;
    }

    // No module access at all — log them out
    return $base . '/logout.php?no_access=1';
}
