<?php

declare(strict_types=1);

namespace App\Middleware;

use App\Core\MiddlewareInterface;
use App\Core\Request;
use App\Core\Response;
use App\Helpers\AjaxResponse;
use App\Models\ApiKeyModel;

/**
 * ApiKeyAuthMiddleware
 *
 * For the external API (routes/api.php, /api/v1/external/*) — a
 * separate auth path from the session-cookie `auth` middleware used
 * by the app's own frontend, since a third-party integration has no
 * browser session. Reads `Authorization: Bearer sk_live_...`, hashes
 * and looks it up, and rejects with a 401 envelope (matching
 * AuthMiddleware's AJAX response shape) if missing, malformed, or
 * revoked. On success, stashes the validated key row on the request
 * (`_api_key`) so controllers can check scopes via
 * ApiKeyModel::hasScope().
 */
final class ApiKeyAuthMiddleware implements MiddlewareInterface
{
    public function handle(Request $request, callable $next): Response
    {
        $header = $request->header('Authorization');

        if ($header === null || !str_starts_with($header, 'Bearer ')) {
            return AjaxResponse::error('Missing or malformed Authorization header. Expected: Bearer <api_key>', 401);
        }

        $token = trim(substr($header, 7));
        $keyRow = (new ApiKeyModel())->validate($token);

        if ($keyRow === null) {
            return AjaxResponse::error('Invalid or revoked API key.', 401);
        }

        $request->setAttribute('_api_key', $keyRow);

        return $next($request);
    }
}
