import { NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';

/**
 * Object-level authorization for incident WRITES (create/update).
 *
 * The incident GET path scopes a non-ADMIN user to incidents linked to their
 * assigned countries/regions, but the POST/PUT paths historically gated on ROLE
 * only (`ADMIN`/`EDITOR`) — so an EDITOR could create or re-target an incident
 * to regions they don't manage (a latent IDOR). This enforces the same
 * region-ownership rule on writes: a non-ADMIN may only attach regions within
 * their assigned set. ADMIN / ADMIN_READ_ONLY are unscoped (global).
 */

/** True iff every requested region id is in the allowed set (empty request is vacuously allowed). */
export function regionIdsWithinAllowed(requested: number[], allowed: number[]): boolean {
    const allowedSet = new Set(allowed);
    return requested.every((id) => allowedSet.has(id));
}

/** Roles that may act across all regions without an ownership check. */
const GLOBAL_ROLES = ['ADMIN', 'ADMIN_READ_ONLY'];

/**
 * Guard for incident create/update. Returns a 403 NextResponse to short-circuit
 * the handler, or null to proceed.
 *
 *   const denied = await assertIncidentRegionAccess(userId, role, regionIds);
 *   if (denied) return denied;
 */
export async function assertIncidentRegionAccess(
    userId: number,
    role: string,
    regionIds: number[] | undefined,
): Promise<NextResponse | null> {
    if (GLOBAL_ROLES.includes(role)) return null; // global roles bypass region scoping
    const requested = regionIds ?? [];

    const user = await prisma.user.findUnique({
        where: { id: userId },
        include: { countries: { select: { id: true } } },
    });
    const allowed = user?.countries.map((c) => c.id) ?? [];

    if (!regionIdsWithinAllowed(requested, allowed)) {
        return NextResponse.json(
            { success: false, error: 'Forbidden: incident references a region outside your assigned scope' },
            { status: 403 },
        );
    }
    return null;
}
