import { NextResponse } from "next/server";
import { verifyOtp } from "@/lib/otp";
import { auditLog } from "@/lib/audit";
import { evaluateHuman, humanRejectResponse } from "@/lib/human";
import { requestMeta } from "@/lib/request-meta";
import {
  recordHumanCheckReject,
  withRegistrationSecurity,
} from "@/lib/security";
import { safeError } from "@/lib/safe-log";

export async function POST(req: Request) {
  return withRegistrationSecurity(
    req,
    {
      routeGroup: "registration",
      pathNorm: "/api/v1/registration/otp/verify",
    },
    async () => {
      const meta = requestMeta(req);
      try {
        const body = await req.json();
        const human = evaluateHuman(body.human);
        if (!human.ok) {
          await auditLog({
            step: "human_check",
            outcome: "reject",
            ip: meta.ip,
            userAgent: meta.userAgent,
            meta: {
              reason: human.reason,
              score: human.score,
              at: "otp_verify",
            },
          });
          recordHumanCheckReject({
            at: "otp_verify",
            reason: human.reason,
            score: human.score,
            sourceIp: meta.ip,
          });
          return NextResponse.json(humanRejectResponse(human.reason), {
            status: 403,
          });
        }

        const sessionId = String(body.session_id || "");
        const otp = String(body.otp || "").replace(/\s+/g, "");

        if (!sessionId || !/^\d{6}$/.test(otp)) {
          await auditLog({
            step: "otp_verify",
            outcome: "invalid_input",
            ip: meta.ip,
            userAgent: meta.userAgent,
          });
          return NextResponse.json(
            { ok: false, error: "Enter the 6-digit OTP." },
            { status: 400 },
          );
        }

        const result = await verifyOtp(sessionId, otp);
        await auditLog({
          step: "otp_verify",
          outcome: result.ok ? "ok" : "fail",
          ip: meta.ip,
          userAgent: meta.userAgent,
          meta: {
            human_score: human.score,
            ...(result.ok
              ? {
                  mobile_masked: result.mobile
                    ? `${result.mobile.slice(0, 2)}XXXXXX${result.mobile.slice(-2)}`
                    : undefined,
                }
              : { locked: result.locked || false }),
          },
        });

        if (!result.ok) {
          return NextResponse.json(
            {
              ok: false,
              error: result.error,
              locked: result.locked || false,
            },
            { status: 400 },
          );
        }

        return NextResponse.json({
          ok: true,
          token: result.token,
          mobile: result.mobile,
        });
      } catch (e) {
        safeError(e);
        return NextResponse.json(
          { ok: false, error: "Unable to verify OTP." },
          { status: 500 },
        );
      }
    },
  );
}
