<?php
declare(strict_types=1);

// --------------------------------------------------
// Permission Middleware
// --------------------------------------------------

require_once __DIR__ . '/response.php';
require_once __DIR__ . '/auth.php';
require_once __DIR__ . '/../../config/database.php';

/**
 * Load permissions assigned via role + user overrides
 *
 * @param int $userId
 * @return array<string>
 */
function loadUserPermissions(int $userId): array
{
    $db = Database::connect();
    $permissions = [];

    // --------------------------------------------------
    // Role-based permissions
    // --------------------------------------------------
    $stmt = $db->prepare(
        'SELECT p.permission_key
         FROM permissions p
         JOIN role_permissions rp ON rp.permission_id = p.id
         JOIN users u ON u.role_id = rp.role_id
         WHERE u.id = ?'
    );
    $stmt->execute([$userId]);

    while ($row = $stmt->fetch()) {
        $permissions[$row['permission_key']] = true;
    }

    // --------------------------------------------------
    // Optional user-specific overrides
    // --------------------------------------------------
    $stmt = $db->prepare(
        'SELECT p.permission_key
         FROM permissions p
         JOIN user_permissions up ON up.permission_id = p.id
         WHERE up.user_id = ?'
    );
    $stmt->execute([$userId]);

    while ($row = $stmt->fetch()) {
        $permissions[$row['permission_key']] = true;
    }

    return array_keys($permissions);
}

/**
 * Require a specific permission to access an endpoint
 *
 * @param string $permissionKey
 * @param int|null $companyId
 */
function requirePermission(string $permissionKey, ?int $companyId = null): void
{
    $user = getAuthenticatedUser();

    if (!$user) {
        jsonResponse([
            'error' => 'Unauthorized',
            'code'  => 'AUTH_REQUIRED'
        ], 401);
    }

    // Permissions should already be loaded at login
    $permissions = $user['permissions'] ?? [];

    if (!in_array($permissionKey, $permissions, true)) {
        jsonResponse([
            'error' => 'Forbidden',
            'code'  => 'INSUFFICIENT_PERMISSION',
            'required' => $permissionKey
        ], 403);
    }

    // Optional company scope check
    if ($companyId !== null) {
        if (
            !isset($user['company_id']) ||
            (int)$user['company_id'] !== (int)$companyId
        ) {
            jsonResponse([
                'error' => 'Forbidden',
                'code'  => 'COMPANY_SCOPE_VIOLATION'
            ], 403);
        }
    }
    
    //Permission Context Validation
        if (!isset($user['permissions']) || !is_array($user['permissions'])
        ) {
            jsonResponse([
                'error' => 'Permission context missing',
                'code'  => 'PERMISSION_CONTEXT_INVALID'
            ], 500);
        }
}

/**
 * Module-level permission override
 * No row = allow (RBAC applies)
 */
function requireModulePermission(
    PDO $pdo,
    int $userId,
    string $moduleKey,
    string $permissionKey
): void {
    $stmt = $pdo->prepare("
        SELECT granted
        FROM user_module_permissions
        WHERE user_id = ?
          AND module_key = ?
          AND permission_key = ?
        LIMIT 1
    ");
    $stmt->execute([$userId, strtoupper($moduleKey), $permissionKey]);

    $granted = $stmt->fetchColumn();

    // No override row → allow
    if ($granted === false) {
        return;
    }

    if ((int)$granted !== 1) {
        jsonResponse([
            'error' => 'Forbidden',
            'code'  => 'MODULE_PERMISSION_DENIED',
            'module'=> $moduleKey,
            'permission' => $permissionKey
        ], 403);
    }
}

