import { createServerClient } from "@supabase/ssr";
import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import { buildAuthPolicyPreview, syncOrganizationAccessForUser } from "@/lib/organization-auth";

function mapProviderToAuthMethod(provider: string | undefined | null) {
  if (provider === "google" || provider === "github" || provider === "azure") {
    return provider;
  }

  if (provider === "email") {
    return "magic_link";
  }

  return null;
}

export async function GET(request: Request) {
  const requestUrl = new URL(request.url);
  const code = requestUrl.searchParams.get("code");
  const nextPath = requestUrl.searchParams.get("next") || "/";
  const safeNextPath = nextPath.startsWith("/") ? nextPath : "/";
  const errorDescription = requestUrl.searchParams.get("error_description");

  if (errorDescription) {
    const loginUrl = new URL("/login", requestUrl.origin);
    loginUrl.searchParams.set("error", errorDescription);
    return NextResponse.redirect(loginUrl);
  }

  if (!code) {
    const loginUrl = new URL("/login", requestUrl.origin);
    loginUrl.searchParams.set("error", "Authentication could not be completed.");
    return NextResponse.redirect(loginUrl);
  }

  const cookieStore = await cookies();
  const redirectUrl = new URL(safeNextPath, requestUrl.origin);
  const response = NextResponse.redirect(redirectUrl);

  const supabase = createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll();
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) =>
            response.cookies.set(name, value, options)
          );
        },
      },
    }
  );

  const { error } = await supabase.auth.exchangeCodeForSession(code);
  if (error) {
    const loginUrl = new URL("/login", requestUrl.origin);
    loginUrl.searchParams.set("error", error.message);
    return NextResponse.redirect(loginUrl);
  }

  const {
    data: { user },
  } = await supabase.auth.getUser();

  if (user) {
    const provider = mapProviderToAuthMethod(user.app_metadata?.provider);
    const preview = user.email ? await buildAuthPolicyPreview(user.email) : null;

    if (provider && preview && !preview.allowedMethods.includes(provider)) {
      await supabase.auth.signOut();
      const loginUrl = new URL("/login", requestUrl.origin);
      loginUrl.searchParams.set(
        "error",
        `This workspace requires a different sign-in method for ${user.email}.`
      );
      return NextResponse.redirect(loginUrl);
    }

    await syncOrganizationAccessForUser({
      userId: user.id,
      email: user.email,
    });
  }

  return response;
}
