<?php
namespace Gestoreasy\Core\Auth;

use Gestoreasy\Core\Http\Request;
use Gestoreasy\Core\Http\Response;
use Gestoreasy\Core\Tenant\ConnectionManager;

class Rbac {
    private static function isSuperAdmin(Request $req): bool {
        $user = UserContext::get($req);
        if (!$user) return false;
        $email = (string)($user['email'] ?? '');
        if ($email === '') return false;
        // Fallback: admin@local sempre possui acesso em ambiente local
        if ($email === 'admin@local' && \Gestoreasy\Core\Config\Config::get('APP_ENV', 'local') === 'local') {
            return true;
        }
        // Verificar registro em superadmins (persistente por tenant)
        try {
            $pdo = ConnectionManager::forTenant();
            $stmt = $pdo->prepare('SELECT 1 FROM superadmins WHERE email = ? LIMIT 1');
            $stmt->execute([$email]);
            return (bool)$stmt->fetch();
        } catch (\Throwable $e) {
            return false;
        }
    }
    public static function requireRoles(array $roles): callable {
        return function (Request $req) use ($roles) {
            $user = UserContext::get($req);
            if (!$user) return new Response(401, ['error' => 'Unauthorized']);
            // Permitir tudo quando a sessão é de impersonação administrativa
            if (!empty($user['impersonated'])) {
                return null;
            }
            // Bypass para superadmin
            if (self::isSuperAdmin($req)) {
                return null;
            }
            $userRoles = $user['roles'] ?? [];
            foreach ($roles as $role) {
                if (in_array($role, $userRoles, true)) {
                    return null;
                }
            }
            return new Response(403, ['error' => 'Forbidden']);
        };
    }

    public static function requirePermissions(array $perms): callable {
        return function (Request $req) use ($perms) {
            $user = UserContext::get($req);
            if (!$user) return new Response(401, ['error' => 'Unauthorized']);
            // Permitir tudo quando a sessão é de impersonação administrativa
            if (!empty($user['impersonated'])) {
                return null;
            }
            // Bypass para superadmin
            if (self::isSuperAdmin($req)) {
                return null;
            }
            $userId = (int)($user['sub'] ?? 0);
            $pdo = ConnectionManager::forTenant();
            $sql = 'SELECT p.name FROM permissions p '
                . 'JOIN role_permissions rp ON rp.permission_id = p.id '
                . 'JOIN user_roles ur ON ur.role_id = rp.role_id '
                . 'WHERE ur.user_id = ?';
            $stmt = $pdo->prepare($sql);
            $stmt->execute([$userId]);
            $rows = $stmt->fetchAll();
            $names = array_map(fn($r) => $r['name'], $rows);
            foreach ($perms as $perm) {
                if (!in_array($perm, $names, true)) {
                    return new Response(403, ['error' => 'Forbidden']);
                }
            }
            return null;
        };
    }
}