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);
  const jar = await cookies();
  const adminIntent = jar.get(`${STATE_COOKIE_PREFIX}yandex-intent`)?.value === "admin";
  if (!(await isSettingEnabled("auth_enabled")) || !(await isSettingEnabled("auth_yandex_enabled"))) return NextResponse.redirect(new URL("/?auth=disabled", publicUrl));
  if (!url.searchParams.get("state") || url.searchParams.get("state") !== jar.get(`${STATE_COOKIE_PREFIX}yandex`)?.value) return NextResponse.redirect(new URL(adminIntent ? "/admin/panel?auth=error" : "/?auth=error", publicUrl));
  try {
    const redirectUri = process.env.YANDEX_REDIRECT_URI || `${publicUrl}/api/auth/yandex/callback`;
    const tokenResponse = await fetch("https://oauth.yandex.ru/token", { method: "POST", headers: { "content-type": "application/x-www-form-urlencoded", authorization: `Basic ${Buffer.from(`${process.env.YANDEX_CLIENT_ID}:${process.env.YANDEX_CLIENT_SECRET}`).toString("base64")}` }, body: new URLSearchParams({ grant_type: "authorization_code", code: url.searchParams.get("code") || "", redirect_uri: redirectUri }), cache: "no-store" });
    const token = await tokenResponse.json() as { access_token?: string; scope?: string };
    if (!token.access_token) throw new Error("Yandex token exchange failed");
    const profile = await fetch("https://login.yandex.ru/info?format=json", { headers: { authorization: `OAuth ${token.access_token}` }, cache: "no-store" }).then((r) => r.json()) as { id?: string; display_name?: string; real_name?: string; default_phone?: { number?: string } };
    if (!profile.id || !profile.default_phone?.number) throw new Error("Yandex verified phone is unavailable");
    const user = await resolvePhoneIdentity("yandex", profile.id, profile.default_phone.number, profile.real_name || profile.display_name);
    console.info("Yandex OAuth profile received", {
      userId: user.id,
      grantedScopes: token.scope || null,
      hasDefaultPhone: true,
      phoneAttached: true
    });
    const session = await createSession(user.id);
    const requestedAdmin = adminIntent ? await beginProviderAdminLogin(user.id, "yandex", profile.id) : null;
    const adminSession = requestedAdmin?.status === "approved" ? requestedAdmin.session : !adminIntent ? await resumeProviderAdminLogin(user.id, "yandex", profile.id) : 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}yandex`);
    response.cookies.delete(`${STATE_COOKIE_PREFIX}yandex-intent`);
    return response;
  } catch (error) {
    const phoneMissing = error instanceof Error && error.message.includes("verified phone");
    console.warn("Yandex 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=yandex" : "/account?auth=error", publicUrl));
  }
}
