<?php

declare(strict_types=1);

namespace BotGuard\Middleware;

use BotGuard\Core\Request;
use BotGuard\Core\Response;
use BotGuard\Models\ApiKey;
use Closure;

/**
 * Authenticates public REST API requests via an API key.
 *
 * Accepts the key as `Authorization: Bearer <key>` or the `X-API-Key` header.
 * On success the owning user id is attached to the request as the `api_user_id`
 * attribute for downstream controllers; on failure a 401 JSON error is returned.
 */
final class ApiKeyAuthMiddleware implements MiddlewareInterface
{
    public function __construct(private ApiKey $keys)
    {
    }

    public function handle(Request $request, Closure $next): Response
    {
        $presented = $this->extractKey($request);

        if ($presented === null) {
            return Response::json(['error' => 'Missing API key.'], 401);
        }

        $row = $this->keys->resolve($presented);
        if ($row === null) {
            return Response::json(['error' => 'Invalid or revoked API key.'], 401);
        }

        $request->setAttribute('api_user_id', (int) $row['user_id']);
        $request->setAttribute('api_key_id', (int) $row['id']);

        return $next($request);
    }

    private function extractKey(Request $request): ?string
    {
        $header = $request->header('Authorization');
        if ($header !== null && stripos($header, 'bearer ') === 0) {
            return trim(substr($header, 7));
        }

        $x = $request->header('X-API-Key');

        return $x !== null && $x !== '' ? trim($x) : null;
    }
}
