import { NextResponse } from "next/server";
import { eq } from "drizzle-orm";
import { db } from "@/db";
import { authUsers, userEmails } from "@/db/schema";
import { createSession, currentUser, SESSION_COOKIE } from "@/lib/auth";
import { checkRateLimit, readJson } from "@/lib/api-security";
import { EmailVerificationError, normalizeEmail, upsertUserEmail, verifyEmailChallenge } from "@/lib/email-pin";

function sessionCookie(token: string) {
  return { httpOnly: true, sameSite: "lax" as const, secure: process.env.NODE_ENV === "production", maxAge: 30 * 24 * 60 * 60, path: "/" };
}

/**
 * Email-PIN verify (§10.2 «email link/PIN»): with a session it attaches the
 * address to the cabinet; without a session it logs the user in — an account
 * is found by verified email or created.
 */
export async function POST(request: Request) {
  try {
    checkRateLimit(request, "email-verify", 20, 10 * 60 * 1000);
    const body = await readJson<{ email?: unknown; code?: unknown }>(request, 4 * 1024);
    const email = normalizeEmail(typeof body.email === "string" ? body.email : "");
    const code = typeof body.code === "string" ? body.code.replace(/\D/g, "") : "";
    if (!email || code.length < 4 || code.length > 10) return NextResponse.json({ error: "bad_request", message: "Проверьте адрес и код." }, { status: 400 });
    await verifyEmailChallenge({ email, pin: code });

    const current = await currentUser();
    if (current) {
      await upsertUserEmail(current.id, email);
      return NextResponse.json({ ok: true, attached: true }, { headers: { "Cache-Control": "no-store" } });
    }
    if (!db) return NextResponse.json({ error: "service_unavailable" }, { status: 503 });
    const [existing] = await db.select().from(userEmails).where(eq(userEmails.email, email)).limit(1);
    let userId: number;
    if (existing) {
      userId = existing.userId;
      if (!existing.verifiedAt) await db.update(userEmails).set({ verifiedAt: new Date() }).where(eq(userEmails.id, existing.id));
    } else {
      const [user] = await db.insert(authUsers).values({ displayName: email.split("@")[0].slice(0, 64), email }).returning({ id: authUsers.id });
      userId = user.id;
      await db.insert(userEmails).values({ userId, email, verifiedAt: new Date() });
    }
    const token = await createSession(userId);
    const response = NextResponse.json({ ok: true, login: true }, { headers: { "Cache-Control": "no-store" } });
    response.cookies.set(SESSION_COOKIE, token, sessionCookie(token));
    return response;
  } catch (error) {
    if (error instanceof EmailVerificationError) return NextResponse.json({ error: "verify_failed", message: error.message }, { status: 400 });
    return NextResponse.json({ error: "verify_failed", message: "Не удалось проверить код. Попробуйте позже." }, { status: 503 });
  }
}
