<?php

use App\Http\Middleware\AllowLivewireUpdateDuringSystemUpdateMaintenance;
use App\Http\Middleware\AssignDberpAuditCorrelation;
use App\Http\Middleware\EnsureDBErpIsInstalled;
use App\Http\Middleware\EnsureDBErpIsNotInstalled;
use App\Http\Middleware\EnsureHostPluginSettingsAccess;
use App\Http\Middleware\ForceInstallFileSession;
use App\Services\Install\WebInstallUserMessages;
use Filament\Notifications\Notification;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Http\Request;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: [
            __DIR__.'/../routes/web.php',
            __DIR__.'/../routes/install.php',
            __DIR__.'/../routes/well-known.php',
        ],
        api: __DIR__.'/../routes/api.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware): void {
        $middleware->replace(
            PreventRequestsDuringMaintenance::class,
            AllowLivewireUpdateDuringSystemUpdateMaintenance::class,
        );

        $middleware->prependToGroup('web', ForceInstallFileSession::class);
        $middleware->appendToGroup('web', AssignDberpAuditCorrelation::class);
        $middleware->alias([
            'dberp.installed' => EnsureDBErpIsInstalled::class,
            'dberp.not_installed' => EnsureDBErpIsNotInstalled::class,
            'host_plugin.settings' => EnsureHostPluginSettingsAccess::class,
        ]);
    })
    ->withSchedule(function (Schedule $schedule): void {
        $schedule->command('dberp:audit-logs-prune')->dailyAt('03:30');
        $schedule->command('dberp:plugin-operation-logs-prune')->dailyAt('03:35');
        $schedule->command('dberp:inventory-exceptions-sync')
            ->everyMinutes(max(1, (int) config('dberp.workbench.inventory_exception_sync_interval_minutes', 5)))
            ->withoutOverlapping();
    })
    ->withExceptions(function (Exceptions $exceptions): void {
        $exceptions->render(function (AuthenticationException $exception, Request $request) {
            if ($request->expectsJson() || ! $request->is('oauth', 'oauth/*')) {
                return null;
            }

            return redirect()->guest(route('filament.admin.auth.login'));
        });

        $exceptions->render(function (AuthorizationException|AccessDeniedHttpException $exception, Request $request) {
            $message = (string) __('dberp.messages.admin_access_denied');

            if ($request->expectsJson()) {
                return response()->json([
                    'message' => $message,
                ], 403);
            }

            if (! $request->routeIs('filament.admin.*')) {
                return null;
            }

            Notification::make()
                ->title($message)
                ->body((string) __('dberp.messages.admin_access_contact_super_admin'))
                ->danger()
                ->send();

            return response()->view('errors.403', [
                'title' => $message,
                'message' => (string) __('dberp.messages.admin_access_contact_super_admin'),
            ], 403);
        });

        $exceptions->render(function (Throwable $e, Request $request) {
            if (! $request->is('install', 'install/*') || $request->expectsJson()) {
                return null;
            }

            if ($e instanceof ValidationException
                || $e instanceof AuthenticationException
                || $e instanceof HttpResponseException) {
                return null;
            }

            if ($e instanceof HttpExceptionInterface && $e->getStatusCode() === 404) {
                return null;
            }

            $status = $e instanceof HttpExceptionInterface ? $e->getStatusCode() : 500;

            return response()->view('errors.install', [
                'title' => '安装向导遇到问题',
                'message' => config('app.debug')
                    ? WebInstallUserMessages::sanitizeFailureDetail($e->getMessage())
                    : '系统暂时无法完成安装向导请求。请稍后重试，或联系技术支持并提供下方软件版本信息。',
                'showDebugDetails' => (bool) config('app.debug'),
                'httpStatus' => $status,
                'exception' => config('app.debug') ? $e : null,
            ], $status);
        });
    })->create();
