<?php

namespace App\Http\Middleware;

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

/**
 * Role write-gate (Team Workspaces P3c, Δ22/Δ24). Passes when the current
 * user can mutate their ACTIVE workspace; else 403.
 *
 * The capability decision lives entirely in `User::canEditActiveWorkspace()`
 * (mode-aware: SaaS reads the active-workspace pivot role ∈ {owner,admin,
 * editor}; self-hosted reads `users.role` — `is_admin` || role !== 'viewer').
 * This middleware is the single seam — applied to every mutating route
 * (projects/screens/media/edit-lock) so the Viewer read-only enforcement
 * stays auditable in one place instead of fanned across controllers.
 *
 * BOTH modes (not in the `saas-only` group): a self-hosted viewer's writes
 * 403 exactly like a SaaS viewer's. Solo buyers and editors pass.
 *
 * Deliberately NOT applied to read routes or the export route
 * (`POST /projects/{id}/exports` stays viewer-allowed — read-only output,
 * already plan-gated).
 */
class EnsureCanEdit
{
    public function handle(Request $request, Closure $next): Response
    {
        $user = $request->user();

        if ($user && $user->canEditActiveWorkspace()) {
            return $next($request);
        }

        $role = $this->activeRole($request);
        $message = "Viewers can't edit this workspace";

        // JSON / fetch callers (the editor autosave, screen mutations,
        // media upload) want a 403 JSON body with the role; Inertia page
        // actions (project create/delete from the gallery) want a flash
        // redirect so the SPA surfaces the error without a dead modal.
        if ($request->expectsJson() || ! $request->hasHeader('X-Inertia')) {
            abort(response()->json([
                'message' => $message,
                'role' => $role,
            ], 403));
        }

        return back()->with('error', $message);
    }

    private function activeRole(Request $request): ?string
    {
        $user = $request->user();
        if ($user === null) {
            return null;
        }

        if (\App\Support\AppMode::isSelfHosted()) {
            return $user->role;
        }

        $tenant = $user->tenant;

        return $tenant ? $user->roleIn($tenant) : null;
    }
}
