import { NextResponse } from "next/server";
import { eq } from "drizzle-orm";
import { db } from "@/db";
import { messengerLoginRequests } from "@/db/schema";
import { createSession, resolvePhoneIdentity, SESSION_COOKIE } from "@/lib/auth";
import { getBotLoginClaim } from "@/lib/bot-api";
import { normalizePhone } from "@/lib/sms-pin";
import { adminCookieOptions, ADMIN_CSRF_COOKIE, ADMIN_SESSION_COOKIE, beginProviderAdminLogin, csrfCookieOptions, newCsrfToken, resumeProviderAdminLogin } from "@/lib/admin-auth";

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.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 trustedPhone = claim.phone_confirmed && claim.phone ? normalizePhone(claim.phone) : null;
  if (!trustedPhone) return NextResponse.json({ status: "phone_required" }, { status: 403, headers: { "Cache-Control": "no-store" } });
  const user = await resolvePhoneIdentity(claim.messenger, claim.messenger_user_id, trustedPhone, claim.display_name);
  const phoneAttached = true;
  await db.update(messengerLoginRequests).set({
    claimedAt: loginRequest.claimedAt || new Date(),
    claimedMessengerUserId: claim.messenger_user_id,
    claimedDisplayName: null,
    claimedPhone: null,
    phoneConfirmed: Boolean(phoneAttached || loginRequest.phoneConfirmed)
  }).where(eq(messengerLoginRequests.id, loginRequest.id));
  const admin = loginRequest.purpose === "admin" ? await beginProviderAdminLogin(user.id, claim.messenger, claim.messenger_user_id) : null;
  const adminSession = admin?.status === "approved" ? admin.session : loginRequest.purpose !== "admin" ? await resumeProviderAdminLogin(user.id, claim.messenger, claim.messenger_user_id) : null;
  const token = await createSession(user.id);
  const response = NextResponse.json(admin?.status === "pending" ? { status: "approval_pending", approvalId: admin.publicId, name: user.displayName, phoneAttached } : { status: "ok", admin: Boolean(adminSession), name: user.displayName, phoneAttached }, { headers: { "Cache-Control": "no-store" } });
  response.cookies.set(SESSION_COOKIE, token, sessionCookie(token));
  if (adminSession) { response.cookies.set(ADMIN_SESSION_COOKIE, adminSession, adminCookieOptions()); response.cookies.set(ADMIN_CSRF_COOKIE, newCsrfToken(), csrfCookieOptions()); }
  return response;
}
