<?php

namespace App\Http\Middleware;

use App\Services\Installer\InstallerService;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureApplicationInstalled
{
    public function __construct(private readonly InstallerService $installer) {}

    /**
     * @param  Closure(Request): Response  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        if (app()->environment('testing')) {
            return $next($request);
        }

        if (! (bool) config('installer.enabled', true)) {
            return $next($request);
        }

        $this->installer->bootForInstaller();

        if (! $this->installer->isInstalled()) {
            if ($this->isInstallerRoute($request) || $request->is('up')) {
                return $next($request);
            }

            if ($request->expectsJson()) {
                return response()->json([
                    'message' => 'RemoteMatch has not been installed yet.',
                ], Response::HTTP_SERVICE_UNAVAILABLE);
            }

            return redirect()->route('install.index');
        }

        if (! $this->installer->isCurrentDomainAllowed($request)) {
            return response()->view('errors.domain-lock', [
                'currentDomain' => $request->getHost(),
                'installedDomain' => $this->installer->installationRecord()['domain'] ?? 'the licensed domain',
            ], Response::HTTP_LOCKED);
        }

        if ($this->isInstallerRoute($request) && ! $request->is('install/complete')) {
            return redirect('/admin');
        }

        return $next($request);
    }

    private function isInstallerRoute(Request $request): bool
    {
        return $request->is('install') || $request->is('install/*');
    }
}
