<?php

declare(strict_types=1);

namespace App\Http\Middleware;

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

class DemoModeMiddleware
{
    /**
     * Routes that are always allowed even in demo mode (login & logout).
     */
    protected array $allowedRoutes = [
        'login',
        'logout',
        'password.request',
        'password.email',
        'register',
        'password.reset',
        'password.store',
        'settings.qz-tray.generate',
        'settings.qz-tray.regenerate',
        'settings.qz-tray.destroy',
        'qz-tray.sign',
    ];

    /**
     * URL path patterns always allowed in demo mode.
     */
    protected array $allowedPaths = [
        'login',
        'admin/login',
        'logout',
        'admin/logout',
        'forgot-password',
        'admin/forgot-password',
        'register',
        'admin/register',
        'reset-password',
        'admin/reset-password',
        'reset-password/*',
        'admin/reset-password/*',
        'admin/settings/qz-tray/generate',
        'admin/settings/qz-tray/regenerate',
        'admin/settings/qz-tray',
        'admin/qz-tray/sign',
    ];

    /**
     * Handle an incoming request.
     * In demo mode, only GET and HEAD requests are allowed.
     * POST to login/logout/register/password-reset paths is always allowed.
     */
    public function handle(Request $request, Closure $next): Response
    {
        if (app()->environment('demo')) {
            // Allow file upload requests in demo mode (handled specifically by controllers)
            if (count($request->allFiles()) > 0) {
                return $next($request);
            }

            // ✅ Perbaikan: Menggunakan $request->method() agar tidak memicu Undefined Variable
            if (in_array($request->method(), ['GET', 'HEAD'], true)) {
                return $next($request);
            }

            // Allow login, logout, register, reset-password by URL path
            if ($request->is(...$this->allowedPaths)) {
                return $next($request);
            }

            // Also check route name as fallback
            if ($request->routeIs(...$this->allowedRoutes)) {
                return $next($request);
            }

            // If it is an Inertia request, we redirect back with a flash message
            if ($request->header('X-Inertia')) {
                return back()->with('error', 'Mode Demo Aktif: Operasi tulis, ubah, dan hapus tidak diizinkan di mode demo.');
            }

            // For any other AJAX, JSON, or fetch requests, return a JSON response
            if ($request->ajax() || $request->expectsJson() || $request->wantsJson() || $request->isJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Mode Demo Aktif: Operasi tulis, ubah, dan hapus tidak diizinkan.',
                    'demo_mode' => true,
                ], 403);
            }

            // Fallback redirect for traditional form submissions
            return back()->with('error', 'Mode Demo Aktif: Operasi tulis, ubah, dan hapus tidak diizinkan di mode demo.');
        }

        return $next($request);
    }
}