import { NextRequest, NextResponse } from "next/server";
import { SESSION_COOKIE, isValidSessionToken } from "@/lib/auth";

const MUTATING_METHODS = new Set(["POST", "PATCH", "PUT", "DELETE"]);

export function middleware(req: NextRequest) {
  const { pathname } = req.nextUrl;

  const isPublic =
    pathname === "/login" ||
    pathname === "/api/auth/login" ||
    pathname.startsWith("/_next") ||
    pathname === "/favicon.ico";

  if (isPublic) return NextResponse.next();

  const token = req.cookies.get(SESSION_COOKIE)?.value;
  if (!isValidSessionToken(token)) {
    if (pathname.startsWith("/api")) {
      return NextResponse.json({ error: "Not authenticated" }, { status: 401 });
    }
    const loginUrl = new URL("/login", req.url);
    loginUrl.searchParams.set("next", pathname);
    return NextResponse.redirect(loginUrl);
  }

  // CSRF defense-in-depth: the SameSite=Lax cookie already stops most
  // cross-site requests, but multipart/form-data POSTs (attachment uploads)
  // don't trigger a CORS preflight the way JSON POSTs do. Requiring this
  // custom header on every mutating request closes that gap — a plain
  // cross-site <form> submit can't set custom headers, only same-origin
  // fetch() calls (like this app's own) can.
  if (pathname.startsWith("/api") && MUTATING_METHODS.has(req.method)) {
    if (req.headers.get("x-midhub-crm") !== "1") {
      return NextResponse.json({ error: "Missing required request header" }, { status: 403 });
    }
  }

  return NextResponse.next();
}

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