import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
import { validateEnv } from "./lib/env";
import log from "./lib/logger";

// Validate environment variables on server startup
try {
  validateEnv();
  log.info("Environment validation passed");
} catch (error) {
  log.error("Environment validation failed", error);
  // Re-throw to prevent server from starting with invalid config
  throw error;
}

// Define routes that should be publicly accessible (no auth required)
const isPublicRoute = createRouteMatcher([
  "/sign-in(.*)",
  "/sign-up(.*)",
  "/api/webhooks(.*)",
  "/api/health(.*)",
]);

// Define API routes that need auth but should be handled in the route itself
// This prevents auth.protect() from blocking before the route handler runs
const isApiRoute = createRouteMatcher(["/api/(.*)"]);

export default clerkMiddleware(async (auth, req) => {
  // Log for debugging
  const authHeader = req.headers.get("authorization");
  if (authHeader) {
    log.debug("Authorization header present", {
      preview: authHeader.substring(0, 20) + "...",
    });
  }

  // Don't protect public routes
  if (isPublicRoute(req)) {
    log.debug("Public route, skipping auth");
    return;
  }

  // For API routes, let the route handler check auth
  // This allows API routes to handle both web sessions and mobile Bearer tokens
  if (isApiRoute(req)) {
    log.debug("API route, auth will be checked in handler");
    return;
  }

  // For all other routes (web pages), enforce authentication
  log.debug("Protected route, requiring auth");
  await auth.protect();
});

export const config = {
  matcher: [
    // Skip Next.js internals and all static files, unless found in search params
    "/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
    // Always run for API routes
    "/(api|trpc)(.*)",
  ],
};
