import { NextResponse } from "next/server";
import { eq } from "drizzle-orm";
import { db } from "@/db";
import { messengerLoginRequests, userPhones } from "@/db/schema";
import { createSession, getOrCreateUser, SESSION_COOKIE } from "@/lib/auth";
import { getBotLoginClaim } from "@/lib/bot-api";
import { normalizePhone } from "@/lib/sms-pin";

export const dynamic = "force-dynamic";

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

/**
 * Polls the bot claim (contract §2в). On claim: creates/links the messenger
 * account, attaches the bot-confirmed phone as verified when present, and
 * opens a site session. Subscription in the messenger stays opt-in.
 */
export async function GET(request: Request) {
  const nonce = new URL(request.url).searchParams.get("ref") || new URL(request.url).searchParams.get("nonce") || "";
  if (!/^[A-Za-z0-9_-]{8,64}$/.test(nonce)) return NextResponse.json({ status: "unknown" }, { status: 404, headers: { "Cache-Control": "no-store" } });
  if (!db) return NextResponse.json({ status: "unavailable" }, { status: 503 });
  const [loginRequest] = await db.select().from(messengerLoginRequests).where(eq(messengerLoginRequests.nonce, nonce)).limit(1);
  if (!loginRequest) return NextResponse.json({ status: "unknown" }, { status: 404, headers: { "Cache-Control": "no-store" } });
  if (loginRequest.claimedAt) return NextResponse.json({ status: "ok" }, { headers: { "Cache-Control": "no-store" } });
  if (loginRequest.expiresAt < new Date()) return NextResponse.json({ status: "expired" }, { headers: { "Cache-Control": "no-store" } });

  let claim;
  try {
    claim = await getBotLoginClaim(nonce);
  } catch {
    // Bot unreachable — keep waiting until the nonce expires.
    return NextResponse.json({ status: "pending" }, { headers: { "Cache-Control": "no-store" } });
  }
  if (claim.status !== "claimed") return NextResponse.json({ status: "pending" }, { headers: { "Cache-Control": "no-store" } });
  if (claim.messenger !== "telegram" && claim.messenger !== "max") return NextResponse.json({ status: "expired" }, { headers: { "Cache-Control": "no-store" } });

  const user = await getOrCreateUser(claim.messenger, claim.messenger_user_id, { displayName: claim.display_name || "Гость", avatarUrl: null });
  let phoneAttached = false;
  if (claim.phone_confirmed && claim.phone) {
    const phone = normalizePhone(claim.phone);
    if (phone) {
      // The bot verified this phone with its own SMS cycle; attach as verified
      // unless it already belongs to another account.
      const [existing] = await db.select().from(userPhones).where(eq(userPhones.phone, phone)).limit(1);
      if (!existing || existing.userId === user.id) {
        if (existing) await db.update(userPhones).set({ verifiedAt: new Date(), updatedAt: new Date() }).where(eq(userPhones.id, existing.id));
        else await db.insert(userPhones).values({ userId: user.id, phone, verifiedAt: new Date() });
        phoneAttached = true;
      }
    }
  }
  await db.update(messengerLoginRequests).set({
    claimedAt: new Date(),
    claimedMessengerUserId: claim.messenger_user_id,
    claimedDisplayName: claim.display_name,
    claimedPhone: phoneAttached && claim.phone ? claim.phone : null,
    phoneConfirmed: phoneAttached
  }).where(eq(messengerLoginRequests.id, loginRequest.id));
  const token = await createSession(user.id);
  const response = NextResponse.json({ status: "ok", name: user.displayName, phoneAttached }, { headers: { "Cache-Control": "no-store" } });
  response.cookies.set(SESSION_COOKIE, token, sessionCookie(token));
  return response;
}
