<?php

use App\Http\Middleware\AssignRequestId;
use App\Http\Middleware\AuthenticateApiKey;
use App\Http\Middleware\BindCurrentMerchant;
use App\Http\Middleware\EnsureApiEnvironment;
use App\Http\Middleware\EnsureApiScope;
use App\Http\Middleware\EnsureOperator;
use App\Http\Middleware\RequireActiveMerchant;
use App\Http\Middleware\RequireApiMerchantVerified;
use App\Http\Middleware\RequirePayoutStepUp;
use App\Http\Middleware\RequireVerifiedMerchant;
use App\Support\ApiResponse;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\Exception\TooManyRequestsHttpException;

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): void {
        $middleware->api(prepend: [AssignRequestId::class]);
        $middleware->alias([
            'api.key' => AuthenticateApiKey::class,
            'api.environment' => EnsureApiEnvironment::class,
            'api.scope' => EnsureApiScope::class,
            'operator' => EnsureOperator::class,
            'merchant.bind' => BindCurrentMerchant::class,
            'merchant.verified' => RequireVerifiedMerchant::class,
            'payout.stepup' => RequirePayoutStepUp::class,
            'merchant.active' => RequireActiveMerchant::class,
            'api.merchant.verified' => RequireApiMerchantVerified::class,
        ]);
    })
    ->withExceptions(function (Exceptions $exceptions): void {
        $exceptions->shouldRenderJsonWhen(fn (Request $request, Throwable $e) => $request->is('api/*'));
        $exceptions->render(fn (AuthenticationException $e, Request $request) => $request->is('api/*')
            ? ApiResponse::error('UNAUTHENTICATED', 'A valid bearer token is required.', 401)
            : null);
        $exceptions->render(fn (ValidationException $e, Request $request) => $request->is('api/*')
            ? ApiResponse::error('VALIDATION_ERROR', 'Invalid request fields.', 400, $e->errors())
            : null);
        $exceptions->render(fn (TooManyRequestsHttpException $e, Request $request) => $request->is('api/*')
            ? ApiResponse::error('RATE_LIMITED', 'API key exceeded its request quota.', 429)
            : null);
        $exceptions->render(fn (MethodNotAllowedHttpException $e, Request $request) => $request->is('api/*')
            ? ApiResponse::error('METHOD_NOT_ALLOWED', 'Use the correct HTTP method for this endpoint.', 405)
            : null);
        $exceptions->render(fn (NotFoundHttpException $e, Request $request) => $request->is('api/*')
            ? ApiResponse::error('RESOURCE_NOT_FOUND', 'The requested resource does not exist.', 404)
            : null);
    })
    ->create();