<?php

namespace App\Http\Middleware;

use App\Models\Admin;
use App\Models\SystemSetting;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

/**
 * Replaces Laravel's default 'verified' middleware.
 * Checks the admin setting 'require_email_verification' — if OFF, skips verification.
 */
class EnsureEmailIsVerified
{
    public function handle(Request $request, Closure $next, ?string $redirectToRoute = null): Response
    {
        // Check admin setting — if verification is disabled, skip entirely
        $required = SystemSetting::get('require_email_verification', 'true');

        if ($required !== 'true' && $required !== true && $required !== '1') {
            return $next($request);
        }

        $user = $request->user();

        // Skip the verification check entirely for admin-guard users.
        // The Admin model lives in the `admins` table which has NO
        // `email_verified_at` column. The old auto-verify branch below
        // crashed with "Unknown column 'email_verified_at'" when an
        // admin hit /admin/dashboard, because markEmailAsVerified()
        // tries to update that non-existent column. Admins are created
        // by an admin process (seeder / reset controller) and don't
        // need email verification.
        if ($user instanceof Admin) {
            return $next($request);
        }

        // Verification is enabled — check if user has verified.
        //
        // Previously this branch silently auto-marked the user as verified
        // (`$user->markEmailAsVerified()`) and let them straight through,
        // which made the admin's "Require email verification" toggle a
        // no-op: every customer was instantly verified the first time
        // they hit any protected route, and spam signups piled up
        // because nothing actually gated the dashboard behind a real
        // click on the email link.
        //
        // Now we honor the toggle: unverified users are redirected to the
        // Fortify verification.notice page ("/email/verify"). They stay
        // there until they click the link in the email — at which point
        // Fortify's VerifyEmailController marks them verified and bounces
        // them to fortify.redirects.email-verification (we route that to
        // /onboarding/step-1 so brand-new users land in the onboarding
        // flow instead of an empty /dashboard).
        if (
            $user &&
            method_exists($user, 'hasVerifiedEmail') &&
            !$user->hasVerifiedEmail()
        ) {
            if ($request->expectsJson()) {
                return response()->json(['message' => 'Your email address is not verified.'], 403);
            }

            // Standard Fortify route name. If the route hasn't been
            // registered (e.g. Features::emailVerification() turned off),
            // fall back to /email/verify so the user at least lands on
            // a sensible URL instead of a route-not-found 500.
            try {
                return redirect()->route('verification.notice');
            } catch (\Throwable $e) {
                return redirect('/email/verify');
            }
        }

        return $next($request);
    }
}
