import { NextResponse } from "next/server";
import { cookies } from "next/headers";
import { createSession, isSettingEnabled, resolvePhoneIdentity, SESSION_COOKIE, siteUrl, STATE_COOKIE_PREFIX } from "@/lib/auth";
import { adminCookieOptions, ADMIN_CSRF_COOKIE, ADMIN_SESSION_COOKIE, beginProviderAdminLogin, csrfCookieOptions, newCsrfToken, resumeProviderAdminLogin } from "@/lib/admin-auth";

export async function GET(request: Request) {
  const url = new URL(request.url);
  const publicUrl = siteUrl(request);
  if (!(await isSettingEnabled("auth_enabled")) || !(await isSettingEnabled("auth_vk_enabled"))) return NextResponse.redirect(new URL("/?auth=disabled", publicUrl));
  const jar = await cookies();
  const stateCookie = jar.get(`${STATE_COOKIE_PREFIX}vk`)?.value;
  const verifier = jar.get(`${STATE_COOKIE_PREFIX}vk-verifier`)?.value;
  const adminIntent = jar.get(`${STATE_COOKIE_PREFIX}vk-intent`)?.value === "admin";
  if (!url.searchParams.get("state") || url.searchParams.get("state") !== stateCookie) return NextResponse.redirect(new URL(adminIntent ? "/admin/panel?auth=error" : "/?auth=error", publicUrl));
  try {
    if (!verifier) throw new Error("VK PKCE verifier is missing");
    const clientId = process.env.VK_APP_ID || "";
    const redirectUri = process.env.VK_REDIRECT_URI || `${publicUrl}/api/auth/vk/callback`;
    const deviceId = url.searchParams.get("device_id") || "";
    const tokenResponse = await fetch("https://id.vk.ru/oauth2/auth", { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ grant_type: "authorization_code", code: url.searchParams.get("code") || "", code_verifier: verifier, redirect_uri: redirectUri, client_id: clientId, device_id: deviceId, client_secret: process.env.VK_SECURE_KEY || "" }), cache: "no-store" });
    const token = await tokenResponse.json() as { access_token?: string; user_id?: string | number };
    if (!tokenResponse.ok || !token.access_token) throw new Error("VK ID token exchange failed");
    const infoResponse = await fetch("https://id.vk.ru/oauth2/user_info", { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ access_token: token.access_token, client_id: clientId }), cache: "no-store" });
    const info = await infoResponse.json() as { user?: { user_id?: string | number; phone?: string; first_name?: string; last_name?: string } };
    const vkUser = info.user;
    const externalId = vkUser?.user_id ?? token.user_id;
    if (!infoResponse.ok || !externalId || !vkUser?.phone) throw new Error("VK ID verified phone is unavailable");
    const suggestedName = [vkUser.first_name, vkUser.last_name].filter(Boolean).join(" ");
    const user = await resolvePhoneIdentity("vk", String(externalId), vkUser.phone, suggestedName);
    const session = await createSession(user.id);
    const requestedAdmin = adminIntent ? await beginProviderAdminLogin(user.id, "vk", String(externalId)) : null;
    const adminSession = requestedAdmin?.status === "approved" ? requestedAdmin.session : !adminIntent ? await resumeProviderAdminLogin(user.id, "vk", String(externalId)) : null;
    const target = requestedAdmin?.status === "pending" ? `/admin/panel?approval=${encodeURIComponent(requestedAdmin.publicId)}` : adminIntent && adminSession ? "/admin/panel?auth=success" : "/account?auth=success";
    const response = NextResponse.redirect(new URL(target, publicUrl));
    response.cookies.set(SESSION_COOKIE, session, { httpOnly: true, sameSite: "lax", secure: process.env.NODE_ENV === "production", maxAge: 30 * 24 * 60 * 60, path: "/" });
    if (adminSession) { response.cookies.set(ADMIN_SESSION_COOKIE, adminSession, adminCookieOptions()); response.cookies.set(ADMIN_CSRF_COOKIE, newCsrfToken(), csrfCookieOptions()); }
    response.cookies.delete(`${STATE_COOKIE_PREFIX}vk`);
    response.cookies.delete(`${STATE_COOKIE_PREFIX}vk-verifier`);
    response.cookies.delete(`${STATE_COOKIE_PREFIX}vk-intent`);
    return response;
  } catch (error) {
    const phoneMissing = error instanceof Error && error.message.includes("verified phone");
    console.warn("VK ID OAuth failed", { reason: phoneMissing ? "verified_phone_unavailable" : "oauth_error" });
    return NextResponse.redirect(new URL(adminIntent ? "/admin/panel?auth=error" : phoneMissing ? "/account?auth=phone-required&provider=vk" : "/account?auth=error", publicUrl));
  }
}
