import { NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
import { hashOtp, safeEqual, OTP_MAX_ATTEMPTS, signStepToken, verifyStepToken } from "@/lib/reset-otp";

/** Step 2b — check the 6-digit code; success returns the reset token. */
export async function POST(req: Request) {
  const body = (await req.json().catch(() => ({}))) as { token?: string; code?: string };
  const uid = await verifyStepToken(body.token ?? "", "identify");
  const code = (body.code ?? "").trim();
  if (!uid || !/^\d{6}$/.test(code)) {
    return NextResponse.json({ error: "SESSION_EXPIRED" }, { status: 401 });
  }

  const otp = await prisma.passwordResetOtp.findFirst({
    where: { userId: uid, consumedAt: null },
    orderBy: { createdAt: "desc" },
  });
  if (!otp) return NextResponse.json({ error: "OTP_EXPIRED" }, { status: 400 });

  if (otp.expiresAt.getTime() < Date.now()) {
    await prisma.passwordResetOtp.update({ where: { id: otp.id }, data: { consumedAt: new Date() } });
    return NextResponse.json({ error: "OTP_EXPIRED" }, { status: 400 });
  }

  if (otp.attempts >= OTP_MAX_ATTEMPTS) {
    await prisma.passwordResetOtp.update({ where: { id: otp.id }, data: { consumedAt: new Date() } });
    return NextResponse.json({ error: "TOO_MANY_ATTEMPTS" }, { status: 429 });
  }

  if (!safeEqual(otp.codeHash, hashOtp(code))) {
    await prisma.passwordResetOtp.update({
      where: { id: otp.id },
      data: { attempts: { increment: 1 } },
    });
    return NextResponse.json(
      { error: "INVALID_CODE", attemptsLeft: OTP_MAX_ATTEMPTS - otp.attempts - 1 },
      { status: 400 },
    );
  }

  await prisma.passwordResetOtp.update({ where: { id: otp.id }, data: { consumedAt: new Date() } });
  const resetToken = await signStepToken(uid, "reset");
  return NextResponse.json({ resetToken });
}
