<?php

declare(strict_types=1);

namespace ApiModel\Shared\Support;

use ApiModel\Service\AuthService;
use ApiModel\Shared\Exceptions\ForbiddenException;
use ApiModel\Shared\Exceptions\UnauthorizedException;
use Psr\Http\Message\ServerRequestInterface;

final class AuthContext
{
    /** @return array{userId: string, role: string, language: string} */
    public static function jwtUser(ServerRequestInterface $request): array
    {
        $h = $request->getHeaderLine('Authorization');
        if (! preg_match('/Bearer\s+(\S+)/i', $h, $m)) {
            throw new UnauthorizedException('No autorizado');
        }

        return AuthService::verifyBearer($m[1]);
    }

    /** @param array{userId: string, role: string, language: string} $u */
    public static function requireRoles(array $u, array $roles): void
    {
        $allowed = array_map(self::normalizeRole(...), $roles);
        $userRoles = array_map('trim', explode(',', $u['role']));

        foreach ($userRoles as $userRole) {
            if ($userRole === '') {
                continue;
            }
            if (in_array(self::normalizeRole($userRole), $allowed, true)) {
                return;
            }
        }

        throw new ForbiddenException();
    }

    public static function normalizeRole(string $role): string
    {
        $upper = strtoupper(trim($role));

        return match ($upper) {
            'ADMIN', 'ADMINISTRATOR', 'ADMINISTRADOR' => 'ADMINISTRADOR',
            'MANAGER', 'GERENTE' => 'MANAGER',
            'CLIENT', 'CLIENTE' => 'CLIENTE',
            default => $upper,
        };
    }
}
