<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Request;
use Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        api: __DIR__ . '/../routes/api.php',
        commands: __DIR__ . '/../routes/console.php',
        channels: __DIR__ . '/../routes/channels.php',
        health: '/health',
    )
    ->withMiddleware(function (Middleware $middleware) {
        // Stateful API for the SPA — Sanctum cookie auth.
        $middleware->statefulApi();

        $middleware->api(prepend: [EnsureFrontendRequestsAreStateful::class]);

        $middleware->throttleApi();

        // Skip CSRF for API routes. SPA cookie auth still works because the
        // session cookie is samesite=lax (browsers reject cross-site POSTs
        // that would carry it). Bearer-token API routes don't need CSRF at
        // all. Avoids the "CSRF token mismatch" class of issues that bite
        // when the client and server disagree on cookie domain / encoding.
        $middleware->validateCsrfTokens(except: [
            'api/*',
        ]);

        // Aliases used in routes/api.php
        $middleware->alias([
            'agent.auth' => \App\Http\Middleware\AuthenticateAgent::class,
            'auth.api-key' => \App\Http\Middleware\AuthenticateApiKey::class,
            // Hybrid: API-key bearer OR Sanctum cookie. Use this on routes
            // that need to serve both the SPA frontend and external clients.
            'auth.api-or-sanctum' => \App\Http\Middleware\ApiKeyOrSanctum::class,
        ]);

        // Trust the load balancer on production.
        $middleware->trustProxies(at: '*', headers:
            Request::HEADER_X_FORWARDED_FOR |
            Request::HEADER_X_FORWARDED_HOST |
            Request::HEADER_X_FORWARDED_PORT |
            Request::HEADER_X_FORWARDED_PROTO
        );
    })
    ->withExceptions(function (Exceptions $exceptions) {
        $exceptions->render(function (\Illuminate\Auth\AuthenticationException $e, Request $request) {
            if ($request->expectsJson()) {
                return response()->json(['message' => 'Unauthenticated.'], 401);
            }
        });
        $exceptions->render(function (\Illuminate\Auth\Access\AuthorizationException $e, Request $request) {
            if ($request->expectsJson()) {
                return response()->json(['message' => $e->getMessage() ?: 'Forbidden.'], 403);
            }
        });
    })
    ->create();
