/**
 * Shared entry gate for every /api/gallery/ai/* route: authenticate, then
 * throttle. Lives in a `_`-prefixed file so the App Router never treats it as a
 * route (only `route.ts` defines an endpoint).
 *
 * Order matters: we authenticate FIRST so the rate limit can be keyed by
 * principal rather than by a spoofable `x-forwarded-for` hop wherever possible.
 * The session check is one cheap BFF round trip; the work it guards is a GPU
 * call, so paying it before throttling is the right trade.
 *
 * SERVER-ONLY.
 */

import { NextResponse } from "next/server";

import { limit } from "@/lib/server/rate-limit";
import { rateLimitKey, requireGallerySession } from "@/lib/server/session";

/** Per-minute budgets, per the Smart Gallery route contract. */
export const RATE_LIMITS = {
  classify: 30,
  edit: 12,
  tilt: 30,
  transcribe: 20,
  denoise: 20,
} as const;

const WINDOW_MS = 60_000;

export type GuardResult =
  | { ok: true; principalId?: string }
  /** Ready-to-return error response — the route should return it unchanged. */
  | { ok: false; response: NextResponse };

/**
 * @param route  Which budget to apply (also namespaces the limiter key so a
 *               caller's `edit` spend does not consume their `classify` budget).
 */
export async function guard(req: Request, route: keyof typeof RATE_LIMITS): Promise<GuardResult> {
  const session = await requireGallerySession(req);
  if (!session.ok) {
    return {
      ok: false,
      response: NextResponse.json({ error: session.error }, { status: session.status }),
    };
  }

  const key = `${route}:${rateLimitKey(req, session.principalId)}`;
  const { ok, retryAfter } = limit(key, RATE_LIMITS[route], WINDOW_MS);
  if (!ok) {
    return {
      ok: false,
      response: NextResponse.json(
        { error: "Too many requests — slow down." },
        { status: 429, headers: { "Retry-After": String(retryAfter) } },
      ),
    };
  }

  return { ok: true, principalId: session.principalId };
}
