import { createServerClient } from "@supabase/ssr";
import { type NextRequest, NextResponse } from "next/server";
import { isAuthDisabled } from "@/lib/app-auth";
import {
  createOnboardingVisitorId,
  getOnboardingVisitorCookieOptions,
  ONBOARDING_VISITOR_COOKIE,
} from "@/lib/onboarding-shared";
import { getSupabasePublishableKey, getSupabaseUrl } from "@/lib/supabase/config";

function isUuid(value: string) {
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(
    value,
  );
}

function ensureOnboardingVisitorCookie(
  request: NextRequest,
  response: NextResponse,
) {
  const existingVisitorId = request.cookies.get(ONBOARDING_VISITOR_COOKIE)?.value;

  if (existingVisitorId && isUuid(existingVisitorId)) {
    return;
  }

  const visitorId = createOnboardingVisitorId();

  request.cookies.set(ONBOARDING_VISITOR_COOKIE, visitorId);
  response.cookies.set(
    ONBOARDING_VISITOR_COOKIE,
    visitorId,
    getOnboardingVisitorCookieOptions(),
  );
}

function shouldRefreshAuthSession(pathname: string) {
  if (pathname === "/login") {
    return false;
  }

  if (pathname.startsWith("/auth")) {
    return false;
  }

  if (pathname.startsWith("/api/auth")) {
    return false;
  }

  return true;
}

export async function updateSession(request: NextRequest) {
  const response = NextResponse.next({
    request,
  });

  ensureOnboardingVisitorCookie(request, response);

  if (isAuthDisabled()) {
    return response;
  }

  if (!shouldRefreshAuthSession(request.nextUrl.pathname)) {
    return response;
  }

  const supabase = createServerClient(
    getSupabaseUrl(),
    getSupabasePublishableKey(),
    {
      cookies: {
        getAll() {
          return request.cookies.getAll();
        },
        setAll(cookiesToSet) {
          cookiesToSet.forEach(({ name, value, options }) => {
            request.cookies.set(name, value);
            response.cookies.set(name, value, options);
          });
        },
      },
    },
  );

  await supabase.auth.getClaims();

  return response;
}
