import { NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { getLatestAudit, createAudit, IssueSeverity, IssueCategory } from "@/lib/services/technical-audit";
import { trackEvent } from "@/lib/services/platform-telemetry";

/**
 * GET /api/technical-audit?brandId=xxx&severity=critical&category=metadata&sort=affected
 */
export const dynamic = "force-dynamic";

export async function GET(req: Request) {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  const { searchParams } = new URL(req.url);
  const brandId = searchParams.get("brandId");
  if (!brandId) return NextResponse.json({ error: "brandId required" }, { status: 400 });

  const brand = await prisma.brand.findUnique({
    where: { id: brandId },
    include: { organization: { include: { memberships: true } } },
  });
  if (!brand || !brand.organization.memberships.some((m) => m.userId === user.id)) {
    return NextResponse.json({ error: "Access denied" }, { status: 403 });
  }

  // Check if there is a currently running or recently failed audit (last 30 min only)
  const recentCutoff = new Date(Date.now() - 30 * 60000);
  const pendingAudit = await prisma.technicalAudit.findFirst({
    where: { brandId, status: { in: ["running", "failed"] }, createdAt: { gte: recentCutoff } },
    orderBy: { createdAt: "desc" },
    select: { id: true, status: true, errorMessage: true, createdAt: true },
  });

  // Auto-fail stale "running" audits (process died or timed out without cleanup).
  // The runner writes a "stage: X" heartbeat into errorMessage as it moves
  // through phases — when the Vercel function gets SIGKILL'd mid-run the
  // heartbeat survives and we surface it here so operators know WHICH
  // stage died ("stalled at stage: crawling pages") instead of the
  // generic "no response" copy.
  if (pendingAudit?.status === "running") {
    const ageMinutes = (Date.now() - new Date(pendingAudit.createdAt).getTime()) / 60000;
    if (ageMinutes > 5) {
      const stageHint = pendingAudit.errorMessage?.startsWith("stage:")
        ? ` Last active stage: ${pendingAudit.errorMessage.slice("stage:".length).trim()}.`
        : "";
      const failureMessage = `Audit stalled — no response after ${Math.round(ageMinutes)} minutes.${stageHint} The process may have timed out. Try running again.`;
      await prisma.technicalAudit.update({
        where: { id: pendingAudit.id },
        data: {
          status: "failed",
          errorMessage: failureMessage,
          completedAt: new Date(),
        },
      });
      pendingAudit.status = "failed";
      pendingAudit.errorMessage = failureMessage;
    }
  }

  // Get the latest completed audit for display
  const audit = await getLatestAudit(
    brandId,
    {
      severity: searchParams.get("severity") as IssueSeverity | undefined,
      category: searchParams.get("category") as IssueCategory | undefined,
      status: searchParams.get("status") ?? undefined,
    },
    searchParams.get("sort") ?? undefined
  );

  return NextResponse.json({
    audit,
    running: pendingAudit?.status === "running" ? pendingAudit.id : null,
    runError: pendingAudit?.status === "failed" ? (pendingAudit.errorMessage || "Audit failed") : null,
  });
}

/**
 * POST /api/technical-audit
 */
export async function POST(req: Request) {
  const user = await getCurrentUser();
  if (!user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });

  try {
    const body = await req.json();
    if (!body.brandId) return NextResponse.json({ error: "brandId required" }, { status: 400 });
    const audit = await createAudit(body.brandId, body);
    // Engagement telemetry — fire-and-forget after the main work is done.
    trackEvent({
      userId: user.id,
      brandId: body.brandId,
      action: "run_technical_audit",
      category: "technical",
      metadata: { auditId: audit?.id ?? null },
      request: req,
    });
    return NextResponse.json(audit, { status: 201 });
  } catch {
    return NextResponse.json({ error: "Something went wrong" }, { status: 500 });
  }
}
