<?php

namespace App\Http\Middleware;

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

class PreventAdminWritesInDemoMode
{
    /**
     * @param  Closure(Request): Response  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        if (! (bool) config('admin.demo_mode')) {
            return $next($request);
        }

        if (in_array($request->method(), ['GET', 'HEAD', 'OPTIONS'], true)) {
            return $next($request);
        }

        if ($request->is('admin/login') || $request->is('admin/logout')) {
            return $next($request);
        }

        $referer = (string) $request->headers->get('referer', '');

        if (str_contains($referer, '/admin/login') || str_contains($referer, '/admin/logout')) {
            return $next($request);
        }

        if (! $this->isAdminRequest($request)) {
            return $next($request);
        }

        if ($request->expectsJson() || $request->is('livewire/*')) {
            return response()->json([
                'message' => 'Demo mode is enabled. Admin write actions are disabled.',
            ], 423);
        }

        return back()->with('demo_mode_blocked', 'Demo mode is enabled. Admin write actions are disabled.');
    }

    private function isAdminRequest(Request $request): bool
    {
        if ($request->is('admin/*')) {
            return true;
        }

        $referer = (string) $request->headers->get('referer', '');

        return $request->is('livewire/*') && str_contains($referer, '/admin');
    }
}
