<?php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Spatie\Permission\Middleware\PermissionMiddleware;
use Spatie\Permission\Middleware\RoleMiddleware;
use Spatie\Permission\Middleware\RoleOrPermissionMiddleware;
use App\Http\Middleware\ProductToken;
use App\Http\Middleware\ApiRequestLogger;
use App\Http\Middleware\ThrottleApiRequests;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        // Middlewares de Spatie Permission
        $middleware->alias([
            'role' => RoleMiddleware::class,
            'permission' => PermissionMiddleware::class,
            'role_or_permission' => RoleOrPermissionMiddleware::class,
            'product_token' => ProductToken::class,
            'api_request_logger' => ApiRequestLogger::class,
            'api_throttle' => ThrottleApiRequests::class,
        ]);
    })

    ->withExceptions(function (Exceptions $exceptions): void {
        // Para rutas API, siempre devolver JSON en lugar de vistas HTML
        $exceptions->shouldRenderJsonWhen(function ($request, \Throwable $e) {
            return $request->is('api/*');
        });

        /**
         * El fichero pasa de `post_max_size`: se dice, en vez de un 413 pelado.
         *
         * **Esta es la capa intermedia de PRODSECU-156.** Cuando el cuerpo de la petición
         * supera `post_max_size`, PHP descarta `$_POST` y `$_FILES` enteros y Laravel lanza
         * `PostTooLargeException` desde `ValidatePostSize`, **antes de que ninguna regla de
         * validación se ejecute**. Así que el mensaje bonito de «la imagen no puede superar
         * los X» no llega nunca: sale la página de error genérica del framework, y quien
         * sube la imagen no tiene forma de saber que el problema es el tamaño.
         *
         * Se distingue de la capa de nginx —que corta antes y **no es detectable desde
         * PHP**, ver `resources/js/subidas.js`— y de la validación, que es la única que da
         * un mensaje por sí sola.
         *
         * El número que se dice sale de `LimiteDeSubida`, o sea de la configuración real de
         * la máquina, no de una constante: es el punto de todo el ticket.
         */
        $exceptions->render(function (\Illuminate\Http\Exceptions\PostTooLargeException $e, $request) {
            $mensaje = 'El archivo es demasiado grande: el máximo que admite este servidor es '
                . \App\Support\LimiteDeSubida::comoTexto() . '.';

            // Las subidas de Livewire y del editor van por XHR y esperan JSON; una vista
            // les llegaría como texto que no saben interpretar.
            if ($request->expectsJson() || $request->is('livewire/*')) {
                return response()->json(['message' => $mensaje], 413);
            }

            return back()
                ->withInput($request->except(['thumbnail_image', 'header_image', 'image']))
                ->with('error', $mensaje);
        });
    })->create();
