/**
 * POST /api/public-audit/resend-code
 * Issues a fresh OTP for the given email. Rate-limited to 1 send per 60s per email.
 *
 * Body: { email: string }
 * Returns: { sent: true }
 */

import { NextResponse } from "next/server";
import { randomInt } from "crypto";
import bcrypt from "bcryptjs";
import { prisma } from "@/lib/prisma";
import { extractClientIp } from "@/lib/user-agent";
import { normalizeEmail } from "@/lib/audit/normalize";
import { sendVerificationCode } from "@/lib/email/send-verification";

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

const RESEND_COOLDOWN_MS = 60 * 1000;

export async function POST(req: Request) {
  const ip = extractClientIp(req) ?? "unknown";

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

  const rawEmail = (body.email ?? "").trim().toLowerCase();
  if (!rawEmail || !rawEmail.includes("@")) {
    return NextResponse.json({ error: "Valid email required" }, { status: 400 });
  }

  const normEmail = normalizeEmail(rawEmail);

  // Rate limit: check if a code was sent in the last 60s
  const recent = await prisma.emailVerification.findFirst({
    where: {
      email: normEmail,
      verifiedAt: null,
      createdAt: { gt: new Date(Date.now() - RESEND_COOLDOWN_MS) },
    },
    orderBy: { createdAt: "desc" },
    select: { createdAt: true },
  });

  if (recent) {
    const waitSec = Math.ceil((RESEND_COOLDOWN_MS - (Date.now() - recent.createdAt.getTime())) / 1000);
    return NextResponse.json(
      { error: `Please wait ${waitSec} seconds before requesting a new code.`, waitSec },
      { status: 429 },
    );
  }

  // Invalidate previous codes
  await prisma.emailVerification.deleteMany({
    where: { email: normEmail, verifiedAt: null },
  });

  const code = String(randomInt(100000, 999999));
  const codeHash = await bcrypt.hash(code, 10);
  const expiresAt = new Date(Date.now() + 10 * 60 * 1000);

  await prisma.emailVerification.create({
    data: { email: normEmail, codeHash, expiresAt, ipAddress: ip },
  });

  const sent = await sendVerificationCode(rawEmail, code);
  if (!sent) {
    return NextResponse.json(
      { error: "Failed to send email. Please try again." },
      { status: 500 },
    );
  }

  console.log(`[public-audit/resend-code] new code sent email=${rawEmail} ip=${ip}`);
  return NextResponse.json({ sent: true });
}
