import { type NextRequest, NextResponse } from "next/server";

import { RunpodError } from "@/lib/server/runpod/client";
import { rpDetect } from "@/lib/server/runpod/endpoints";

import { guard } from "../_guard";

export const runtime = "nodejs";
export const maxDuration = 60;
export const dynamic = "force-dynamic";

/**
 * Object-detection proxy for the RunPod YOLO construction-material classifier (#1).
 * The key + endpoint URL stay server-side. The client calls this only when
 * NEXT_PUBLIC_APG_RUNPOD_DETECT is on; otherwise detection runs fully in-browser
 * (COCO-SSD) with no server round-trip. Returns the SDK's DetectedObject[] shape
 * (box as 0..1 fractions) so it drops straight into the Objects browser / smart
 * albums / search.
 *
 * POST { imageBase64, width, height } -> { objects: [{ label, confidence, box }] }
 * Auth: session-gated (see lib/server/session.ts). Rate limit: 30/min.
 */

const MAX_BASE64 = 4_000_000; // ~3 MB decoded — under serverless body limits

export async function POST(req: NextRequest) {
  const gate = await guard(req, "classify");
  if (!gate.ok) return gate.response;

  if (!process.env.RUNPOD_API_KEY || !process.env.RUNPOD_YOLO_URL) {
    return NextResponse.json(
      { error: "RunPod detection is not configured (set RUNPOD_API_KEY + RUNPOD_YOLO_URL)." },
      { status: 503 },
    );
  }

  let body: unknown;
  try {
    body = await req.json();
  } catch {
    return NextResponse.json({ error: "Invalid request body." }, { status: 400 });
  }

  const { imageBase64, width, height } = (body ?? {}) as {
    imageBase64?: unknown;
    width?: unknown;
    height?: unknown;
  };
  if (
    typeof imageBase64 !== "string" ||
    imageBase64.length === 0 ||
    imageBase64.length > MAX_BASE64
  ) {
    return NextResponse.json({ error: "Invalid or oversized image." }, { status: 400 });
  }
  const w = Number(width);
  const h = Number(height);

  try {
    const objects = await rpDetect(
      imageBase64,
      Number.isFinite(w) && w > 0 ? w : 1,
      Number.isFinite(h) && h > 0 ? h : 1,
    );
    return NextResponse.json({ objects });
  } catch (err) {
    const message = err instanceof Error ? err.message : "Detection failed.";
    const status = err instanceof RunpodError ? err.status : 502;
    return NextResponse.json({ error: message }, { status });
  }
}
