import { createServerClient } from "@supabase/ssr";
import { NextResponse, type NextRequest } from "next/server";

export async function middleware(request: NextRequest) {
  // Skip API routes entirely (webhook, cron, etc.)
  if (request.nextUrl.pathname.startsWith("/api/")) {
    return NextResponse.next();
  }

  let supabaseResponse = NextResponse.next({ request });

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

  const publicPaths = ["/login", "/forgot-password", "/reset-password", "/auth/callback"];
  const isLocalPreview =
    process.env.NODE_ENV === "development" &&
    request.nextUrl.pathname.startsWith("/reportes-preview");
  const isPublic = publicPaths.some((p) =>
    request.nextUrl.pathname.startsWith(p)
  ) || isLocalPreview;

  // Race supabase.auth.getUser() against a 3s timeout to avoid edge timeouts
  let user = null;
  try {
    const result = await Promise.race([
      supabase.auth.getUser(),
      new Promise<null>((_, reject) =>
        setTimeout(() => reject(new Error("auth timeout")), 3000)
      ),
    ]);
    user = (result as Awaited<ReturnType<typeof supabase.auth.getUser>>).data.user;
  } catch {
    // On timeout or error: if already on a public path, let through; else redirect to login
    if (!isPublic) {
      return NextResponse.redirect(new URL("/login", request.url));
    }
    return supabaseResponse;
  }

  if (!user && !isPublic) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return supabaseResponse;
}

export const config = {
  matcher: [
    "/((?!_next/static|_next/image|favicon.ico|api/).*)",
  ],
};
