/**
 * POST /api/public-audit/verify
 * Verifies the 6-digit OTP, then creates Lead + Audit and fires the runner.
 *
 * Body: { email, code, formData: { firstName, lastName, email, companyName, phoneNumber, websiteUrl } }
 * Returns: { auditId, statusUrl, leadId }
 */

import { NextResponse } from "next/server";
import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";
import { extractClientIp } from "@/lib/user-agent";
import { normalizeEmail } from "@/lib/audit/normalize";
import { createLeadAndTriggerAudit } from "@/lib/audit/create-public-audit";

export const dynamic = "force-dynamic";
export const maxDuration = 800;

const MAX_ATTEMPTS = 5;

export async function POST(req: Request) {
  const ip = extractClientIp(req) ?? "unknown";
  const ua = req.headers.get("user-agent") ?? "";

  let body: {
    email?: string;
    code?: string;
    formData?: {
      firstName?: string;
      lastName?: string;
      email?: string;
      companyName?: string;
      phoneNumber?: string;
      websiteUrl?: string;
    };
  };
  try {
    body = await req.json();
  } catch {
    return NextResponse.json({ error: "Invalid request" }, { status: 400 });
  }

  const rawEmail = (body.email ?? "").trim().toLowerCase();
  const code = (body.code ?? "").trim().replace(/\D/g, "");
  const fd = body.formData;

  if (!rawEmail || !code || code.length !== 6 || !fd) {
    return NextResponse.json({ error: "email, code (6 digits), and formData are required" }, { status: 400 });
  }

  const normEmail = normalizeEmail(rawEmail);
  const emailDomain = rawEmail.split("@")[1] ?? "";

  // Fetch the most recent unexpired verification for this email
  const verification = await prisma.emailVerification.findFirst({
    where: {
      email: normEmail,
      verifiedAt: null,
      expiresAt: { gt: new Date() },
    },
    orderBy: { createdAt: "desc" },
  });

  if (!verification) {
    return NextResponse.json(
      { error: "Verification code expired or not found. Request a new code." },
      { status: 410 },
    );
  }

  // Increment attempts atomically
  const updated = await prisma.emailVerification.update({
    where: { id: verification.id },
    data: { attempts: { increment: 1 } },
    select: { attempts: true, codeHash: true },
  });

  if (updated.attempts > MAX_ATTEMPTS) {
    prisma.platformEvent.create({
      data: {
        userId: null, brandId: null,
        action: "public_audit.verification_failed",
        category: "audit",
        metadata: { emailDomain, reason: "max_attempts" },
        ipAddress: ip,
      },
    }).catch(() => {/* non-fatal */});

    return NextResponse.json(
      { error: "Too many attempts. Request a new code.", tooManyAttempts: true },
      { status: 429 },
    );
  }

  const match = await bcrypt.compare(code, updated.codeHash);

  if (!match) {
    const remaining = MAX_ATTEMPTS - updated.attempts;
    prisma.platformEvent.create({
      data: {
        userId: null, brandId: null,
        action: "public_audit.verification_failed",
        category: "audit",
        metadata: { emailDomain, reason: "wrong_code", attemptsUsed: updated.attempts },
        ipAddress: ip,
      },
    }).catch(() => {/* non-fatal */});

    console.log(`[public-audit/verify] wrong code email=${rawEmail} attempts=${updated.attempts}`);

    return NextResponse.json(
      { error: "Incorrect code. Please try again.", remaining: Math.max(0, remaining) },
      { status: 422 },
    );
  }

  // Code matched — mark verified
  await prisma.emailVerification.update({
    where: { id: verification.id },
    data: { verifiedAt: new Date() },
  });

  const email = (fd.email ?? rawEmail).trim().toLowerCase();
  const companyName = (fd.companyName ?? "").trim();

  console.log(`[public-audit/verify] verified email=${email} ip=${ip}`);

  const result = await createLeadAndTriggerAudit({
    formData: {
      firstName: (fd.firstName ?? "").trim(),
      lastName: (fd.lastName ?? "").trim(),
      email,
      companyName,
      phoneNumber: (fd.phoneNumber ?? "").trim(),
      websiteUrl: (fd.websiteUrl ?? "").trim(),
    },
    ipAddress: ip,
    userAgent: ua,
    bypass: false,
  });

  console.log(`[public-audit/verify] created leadId=${result.leadId} auditId=${result.auditId}`);

  prisma.platformEvent.create({
    data: {
      userId: null, brandId: null,
      action: "public_audit.verification_succeeded",
      category: "audit",
      metadata: { auditId: result.auditId, leadId: result.leadId, emailDomain },
      ipAddress: ip,
    },
  }).catch(() => {/* non-fatal */});

  return NextResponse.json({ auditId: result.auditId, statusUrl: result.statusUrl, leadId: result.leadId }, { status: 202 });
}
