import { NextResponse } from "next/server";
import { auth } from "./server/auth-edge.js";

// Paths that are accessible without a session.
// Everything else requires a valid JWT session.
const PUBLIC_PREFIXES = [
  "/auth/",       // signin, forgot-password, reset-password
  "/api/",        // tRPC, health, auth endpoints — these manage their own auth
  "/invite/",     // public invite acceptance flow
];

function isPublicPath(pathname: string): boolean {
  return PUBLIC_PREFIXES.some((prefix) => pathname.startsWith(prefix));
}

function buildCsp(nonce: string, isProd: boolean): string {
  const scriptSrc = isProd
    ? `'self' 'nonce-${nonce}'`
    : `'self' 'unsafe-eval' 'unsafe-inline'`;

  const imgSrc = isProd ? "'self' data: blob:" : "'self' data: blob: https:";

  return [
    "default-src 'self'",
    `script-src ${scriptSrc}`,
    "style-src 'self' 'unsafe-inline'",
    `img-src ${imgSrc}`,
    "font-src 'self' data:",
    "connect-src 'self' https://generativelanguage.googleapis.com https://*.openai.com https://*.azure.com",
    "frame-ancestors 'none'",
    "base-uri 'self'",
    "form-action 'self'",
  ].join("; ");
}

export default auth(function middleware(request) {
  const { pathname } = request.nextUrl;

  // Redirect unauthenticated requests for protected routes to signin
  if (!isPublicPath(pathname) && !request.auth) {
    const signInUrl = new URL("/auth/signin", request.url);
    signInUrl.searchParams.set("callbackUrl", request.url);
    return NextResponse.redirect(signInUrl);
  }

  // Generate a cryptographically random nonce for this request
  const nonceBytes = new Uint8Array(16);
  crypto.getRandomValues(nonceBytes);
  const nonce = btoa(String.fromCharCode(...nonceBytes));

  const isProd = process.env.NODE_ENV === "production";
  const csp = buildCsp(nonce, isProd);

  // Forward nonce to server components via request header
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set("x-nonce", nonce);
  requestHeaders.set("Content-Security-Policy", csp);

  const response = NextResponse.next({ request: { headers: requestHeaders } });
  response.headers.set("Content-Security-Policy", csp);

  return response;
});

export const config = {
  matcher: [
    // Apply to all routes except Next.js internals and static assets
    "/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)",
  ],
};
