import { NextResponse } from "next/server";
import { currentUser } from "@/lib/auth";
import { checkRateLimit, readJson } from "@/lib/api-security";
import { EmailVerificationError, normalizeEmail, requestEmailChallenge } from "@/lib/email-pin";
import { db } from "@/db";
import { authUsers, userEmails } from "@/db/schema";
import { and, eq, isNull, sql } from "drizzle-orm";
import { getVerifiedPhone } from "@/lib/sms-pin";

export async function POST(request: Request) {
  try {
    // Works both for login (no session) and attaching an email to a cabinet.
    const user = await currentUser();
    // §10.2 analogy: at most 3 sends per hour per IP besides per-address limits.
    checkRateLimit(request, "email-pin", 3, 60 * 60 * 1000);
    const body = await readJson<{ email?: unknown }>(request, 4 * 1024);
    const email = normalizeEmail(typeof body.email === "string" ? body.email : "", user ? "strip" : "reject");
    if (!email) return NextResponse.json({ error: "bad_request", message: "Проверьте адрес почты." }, { status: 400 });
    if (user && !(await getVerifiedPhone(user.id))) return NextResponse.json({ error: "phone_required", message: "Сначала подтвердите номер телефона." }, { status: 403 });
    let targetUserId = user?.id;
    if (!targetUserId && db) {
      const [linked] = await db.select({ userId: userEmails.userId }).from(userEmails)
        .innerJoin(authUsers, eq(authUsers.id, userEmails.userId))
        .where(and(eq(userEmails.email, email), isNull(userEmails.archivedAt), sql`${userEmails.verifiedAt} IS NOT NULL`, eq(authUsers.state, "active"), sql`EXISTS (SELECT 1 FROM user_phones p WHERE p.user_id = ${userEmails.userId} AND p.verified_at IS NOT NULL AND p.archived_at IS NULL)`)).limit(1);
      targetUserId = linked?.userId;
    }
    if (targetUserId) await requestEmailChallenge({ email, userId: targetUserId, ip: request.headers.get("x-forwarded-for")?.split(",")[0]?.trim() || undefined });
    // Never disclose whether the address already exists in the system.
    return NextResponse.json({ ok: true, message: "Если эта почта привязана к номеру телефона, код отправлен." }, { headers: { "Cache-Control": "no-store" } });
  } catch (error) {
    if (error instanceof EmailVerificationError) return NextResponse.json({ error: "rate_limited", message: error.message }, { status: error.status });
    return NextResponse.json({ error: "email_unavailable", message: "Не удалось отправить письмо. Попробуйте позже." }, { status: 502 });
  }
}
