import { NextRequest, NextResponse } from "next/server";
import { resolveGoogleAuth } from "@/lib/googleAuth";
import { resolveEmail } from "@/lib/users";
import { createSessionToken, SESSION_COOKIE } from "@/lib/session";
import { googleCallbackUrl, withBase } from "@/lib/basePath";

/** Complete Google OAuth: exchange the code, read the email, match the directory. */
export async function GET(req: NextRequest): Promise<NextResponse> {
  const fail = (e: string) => NextResponse.redirect(new URL(withBase(`/login?error=${e}`), req.url));

  const { clientId, clientSecret } = resolveGoogleAuth();
  if (!clientId || !clientSecret) return fail("google_off");

  const code = req.nextUrl.searchParams.get("code");
  const state = req.nextUrl.searchParams.get("state");
  if (!code || !state || state !== req.cookies.get("g_state")?.value) return fail("state");

  let email = "";
  try {
    const tokenResp = await fetch("https://oauth2.googleapis.com/token", {
      method: "POST",
      headers: { "content-type": "application/x-www-form-urlencoded" },
      body: new URLSearchParams({
        code,
        client_id: clientId,
        client_secret: clientSecret,
        redirect_uri: googleCallbackUrl(req),
        grant_type: "authorization_code",
      }),
    });
    const tok = await tokenResp.json();
    if (!tok.id_token) return fail("exchange");
    email = String(decodeJwtPayload(tok.id_token).email || "");
  } catch {
    return fail("exchange");
  }
  if (!email) return fail("no_email");

  const id = await resolveEmail(email);
  if (!id) return fail("not_allowed"); // not in the directory

  const res = NextResponse.redirect(new URL(withBase("/"), req.url));
  res.cookies.set(SESSION_COOKIE, await createSessionToken(id), {
    httpOnly: true,
    sameSite: "lax",
    path: "/",
    secure: process.env.NODE_ENV === "production",
    maxAge: 60 * 60 * 12,
  });
  res.cookies.delete({ name: "g_state", path: "/" });
  return res;
}

function decodeJwtPayload(jwt: string): Record<string, unknown> {
  try {
    const json = Buffer.from(jwt.split(".")[1].replace(/-/g, "+").replace(/_/g, "/"), "base64").toString("utf8");
    return JSON.parse(json);
  } catch {
    return {};
  }
}
