import { eq } from "drizzle-orm";
import { type NextRequest, NextResponse } from "next/server";
import { auditJob, auditReport, db } from "@/db";
import { type Teaser, teaserOf, vetReport } from "@/lib/report";
import { corsHeaders, isAllowedOrigin } from "@/lib/sites";

/**
 * What the form polls while the audit runs.
 *
 * It answers a status and, once there is one, a teaser — never the report. The
 * full document is not reachable from any API route at all: it is read
 * server-side in `/dashboard/[id]`, after the session and the ownership check.
 * That is the whole point of the product, so the boundary is a missing route
 * rather than a condition somebody could get wrong later.
 *
 * The id is a v4 UUID, which is not guessable, so no cookie is required to poll
 * one — the visitor was handed it, and the teaser gives nothing away that the
 * visitor's own site would not.
 */
export async function GET(
  request: NextRequest,
  context: { params: Promise<{ id: string }> },
): Promise<NextResponse> {
  const origin = request.headers.get("origin");
  const headers = isAllowedOrigin(origin) ? corsHeaders(origin) : {};
  const { id } = await context.params;

  // A malformed id must not reach the driver as a failed uuid cast.
  if (!/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id)) {
    return NextResponse.json({ error: "unknown audit" }, { status: 404, headers });
  }

  const [row] = await db
    .select({
      status: auditJob.status,
      error: auditJob.error,
      report: auditReport.report,
    })
    .from(auditJob)
    .leftJoin(auditReport, eq(auditReport.jobId, auditJob.id))
    .where(eq(auditJob.id, id))
    .limit(1);

  if (!row) return NextResponse.json({ error: "unknown audit" }, { status: 404, headers });

  let teaser: Teaser | null = null;
  if (row.status === "done" && row.report) {
    const report = vetReport(row.report);
    if (report) teaser = teaserOf(report);
  }

  return NextResponse.json(
    {
      status: row.status,
      // The failure reason is ours, not the site's: it says the run broke, and
      // says nothing about what was found.
      error: row.status === "failed" ? (row.error ?? "the audit failed") : null,
      teaser,
    },
    { headers },
  );
}

export function OPTIONS(request: NextRequest): NextResponse {
  const origin = request.headers.get("origin");
  if (!isAllowedOrigin(origin)) return new NextResponse(null, { status: 403 });
  return new NextResponse(null, { status: 204, headers: corsHeaders(origin) });
}
