<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;

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: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->validateCsrfTokens(except: [
            'chat_post',
            'chat_post/*',
        ]);

        $middleware->web(append: [
            \App\Http\Middleware\RedirectLegacyProfileSubdomain::class,
            \App\Http\Middleware\UpdateLastVisit::class,
            \App\Http\Middleware\HandleInertiaRequests::class,
            // Runs on every web request; no-ops for guests, redirects authenticated
            // users who have not finished onboarding (e.g. OAuth users awaiting username).
            \App\Http\Middleware\EnsureOnboardingComplete::class,
            \App\Http\Middleware\EnsureEmailLoginUpgradeComplete::class,
        ]);

        $middleware->alias([
            'artwork.maturity.access'    => \App\Http\Middleware\EnsureArtworkMaturityAccess::class,
            'admin.moderation'          => \App\Http\Middleware\EnsureAdminOrModerator::class,
            'creator.access'            => \App\Http\Middleware\EnsureCreatorAccess::class,
            'ensure.email.login.upgrade'=> \App\Http\Middleware\EnsureEmailLoginUpgradeComplete::class,
            'ensure.onboarding.complete'=> \App\Http\Middleware\EnsureOnboardingComplete::class,
            'forum.ai.moderation'       => \App\Http\Middleware\ForumAIModerationMiddleware::class,
            'forum.bot.protection'      => \App\Http\Middleware\ForumBotProtectionMiddleware::class,
            'forum.spam.detection'      => \App\Http\Middleware\ForumSpamDetectionMiddleware::class,
            'forum.security.firewall'   => \App\Http\Middleware\ForumSecurityFirewallMiddleware::class,
            'forum.rate_limit'          => \App\Http\Middleware\ForumRateLimitMiddleware::class,
            'onboarding'                => \App\Http\Middleware\EnsureOnboardingComplete::class,
            'normalize.username'        => \App\Http\Middleware\NormalizeUsername::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions): void {

        // ── 404 / 410 / 403 — web HTML responses only ─────────────────────────
        $exceptions->render(function (
            \Symfony\Component\HttpKernel\Exception\HttpException $e,
            \Illuminate\Http\Request $request
        ) {
            if ($request->expectsJson()) {
                return null; // Let Laravel produce the default JSON response.
            }

            $status = $e->getStatusCode();

            // 403 and 401 use their generic Blade views — no extra data needed.
            if ($status === 403) {
                return response(view('errors.403', ['message' => $e->getMessage() ?: null]), 403);
            }
            if ($status === 401) {
                return response(view('errors.401'), 401);
            }
            if ($status === 410) {
                return response(view('errors.410'), 410);
            }

            // Generic 404 — smart URL-pattern routing to contextual views.
            if ($status === 404) {
                return app(\App\Http\Controllers\Web\ErrorController::class)
                    ->handleNotFound($request);
            }

            return null; // Fallback to Laravel's default.
        });

        // ── ModelNotFoundException → contextual 404 on web ───────────────────
        $exceptions->render(function (
            \Illuminate\Database\Eloquent\ModelNotFoundException $e,
            \Illuminate\Http\Request $request
        ) {
            if ($request->expectsJson()) {
                return null;
            }

            return app(\App\Http\Controllers\Web\ErrorController::class)
                ->handleNotFound($request);
        });

        // ── 500 server errors — log with correlation ID ───────────────────────
        $exceptions->render(function (
            \Throwable $e,
            \Illuminate\Http\Request $request
        ) {
            if ($request->expectsJson()) {
                return null;
            }

            if ($e instanceof \Illuminate\Validation\ValidationException) {
                return null;
            }

            // Only handle truly unexpected server errors (not HTTP exceptions already handled above).
            if ($e instanceof \Symfony\Component\HttpKernel\Exception\HttpException) {
                return null;
            }

            // In debug mode let Laravel/Ignition render the full error page.
            if (config('app.debug')) {
                return null;
            }

            try {
                $correlationId = app(\App\Services\NotFoundLogger::class)->log500($e, $request);
            } catch (\Throwable) {
                $correlationId = 'UNKNOWN';
            }

            return response(view('errors.500', ['correlationId' => $correlationId]), 500);
        });

    })->create();
