<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Inverse of GuardInstaller: when `storage/installed.lock` does NOT exist,
 * redirect every non-install request to `/install` so a buyer who's just
 * unzipped the release can't accidentally land on `/login` or `/register`
 * (which would 500 on missing DB tables, or worse — write garbage state
 * to a half-configured DB).
 *
 * Allows through:
 *  - Anything under `/install/*` (the wizard itself)
 *  - Asset routes (`/build/*`, `/favicon.ico`, `/up` health check)
 *  - Webhooks (`/webhooks/billing`) — bypassed because they shouldn't
 *    fire pre-install anyway, but if they did, redirect-to-html would
 *    confuse the provider; let them 404 quietly via the missing route.
 *
 * Registered globally on the `web` middleware group so it runs before
 * any controller. Skips for non-Inertia/non-HTML requests so it doesn't
 * intercept JSON API calls with a redirect.
 */
class RequireInstall
{
    public function handle(Request $request, Closure $next): Response
    {
        // Lock file written by InstallerController::finalize on wizard
        // completion. GuardInstaller checks the same path to 404 the
        // wizard once installed.
        if (file_exists(storage_path('installed.lock'))) {
            return $next($request);
        }

        // Already on the install wizard — let it through.
        if ($request->is('install') || $request->is('install/*')) {
            return $next($request);
        }

        // Build assets, health check, anything served from /public/build
        // or other static paths we don't want to gate.
        if (
            $request->is('build/*')
            || $request->is('favicon.ico')
            || $request->is('up')
            || $request->is('robots.txt')
        ) {
            return $next($request);
        }

        // Webhook deliveries — let them 404 quietly through normal
        // routing rather than redirect-to-HTML, which would confuse
        // the upstream provider.
        if ($request->is('webhooks/*')) {
            return $next($request);
        }

        // JSON / fetch callers (Inertia partial reloads, AJAX) — return
        // 503 so they don't follow a redirect into install HTML and try
        // to render it. Plain GET browsers get the redirect.
        if ($request->expectsJson() || $request->ajax()) {
            return response()->json([
                'message' => 'Application not yet installed.',
                'install_url' => route('installer.requirements'),
            ], 503);
        }

        return redirect()->route('installer.requirements');
    }
}
