import { NextResponse } from "next/server";
import { consumeVerificationToken } from "@/lib/auth/accounts";
import { ensureDatabaseInitialized } from "@/lib/db/init";
import { clientIp, rateLimit } from "@/lib/auth/rateLimit";
import {
  logSecurityEventAsync,
  SecurityEventType,
} from "@/lib/auth/securityEvents";

export const runtime = "nodejs";
export const dynamic = "force-dynamic";

/**
 * Target of the emailed confirmation link.
 *
 * Consumes the token and hands off to the `/auth/verified` page. Deliberately
 * does *not* sign the visitor in: mail security scanners follow links before the
 * recipient does, and a session should only ever be created by a deliberate act.
 */
export async function GET(request: Request) {
  // Redirects resolve against the request's own origin, so this keeps working on
  // whatever host or port the app happens to be served from.
  const redirectTo = (status: string) =>
    NextResponse.redirect(new URL(`/auth/verified?status=${status}`, request.url));

  const token = new URL(request.url).searchParams.get("token");
  if (!token) return redirectTo("invalid");

  // Tokens are single-use and cryptographically random, so replay is impossible;
  // this limit only stops a scripted caller from using the credential-free GET
  // as a free token-lookup loop against the database. 60/h per IP is far above
  // what any real recipient — or the mail-security scanner that fetched the link
  // first — could ever need. On breach the client lands on the verified page
  // with `status=rate_limited` (rendered as "invalid" until the UI grows a
  // dedicated state), keeping the redirect contract intact.
  const ipLimit = rateLimit(`verify:ip:${clientIp(request)}`, 60, 60 * 60 * 1000);
  if (!ipLimit.allowed) return redirectTo("rate_limited");

  if (!(await ensureDatabaseInitialized())) return redirectTo("unavailable");

  try {
    const outcome = await consumeVerificationToken(token);
    if (outcome.status === "success") {
      logSecurityEventAsync({
        type: SecurityEventType.EMAIL_VERIFIED,
        userId: outcome.user.id,
        email: outcome.user.email,
        ip: clientIp(request),
        userAgent: request.headers.get("user-agent"),
        metadata: { route: "/api/auth/verify" },
      });
    }
    return redirectTo(outcome.status);
  } catch (error) {
    console.error("[auth] verification failed", error);
    return redirectTo("error");
  }
}
