<?php

namespace App\Http\Middleware;

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

class CheckPermission
{
    public function handle(Request $request, Closure $next, string $permission): Response
    {
        $user = $request->user();

        if (! $user) {
            abort(403, "Missing required permission: {$permission}");
        }

        if (! $user->hasPermissionTo($permission)) {
            // Only a denied coarse-grained ".access" permission on a GET gets
            // the softer "redirect to a safe landing page" treatment — that's
            // a user landing on a whole section they can't see at all (e.g. a
            // stale bookmark), so bouncing them somewhere safe is good UX.
            // Anything finer-grained (.view, .export, .reject, .void, etc. —
            // the user CAN see the section but not this record/action) and
            // every non-GET request must hard 403: silently redirecting a
            // denied write or a denied record view looks like it maybe
            // succeeded, which is worse than an explicit block.
            if ($request->isMethod('GET') && str_ends_with($permission, '.access')) {
                $landing = UserLanding::urlFor($user);

                if ($landing !== $request->url()) {
                    return redirect($landing)->with('warning', "You don't have access to that page.");
                }
            }

            abort(403, "Missing required permission: {$permission}");
        }

        return $next($request);
    }
}
