import NextAuth from "next-auth";
import { NextResponse } from "next/server";
import { authConfig } from "@/lib/auth/auth.config";
import { lookupCachedRedirect, bumpRedirectHit } from "@/lib/redirects-cache";

// Next.js 16 renamed `middleware.ts` to `proxy.ts` and defaults to the
// Node.js runtime. We import the slim `authConfig` (no DB, no Argon2) for
// session-only work; the redirects-cache module imports drizzle, which is
// Node-safe at this runtime.
const { auth } = NextAuth(authConfig);

export default auth(async (req) => {
  const { pathname } = req.nextUrl;

  // 1) Admin-editable redirects. Applied before auth checks so retired URLs
  //    always resolve, even for logged-in users.
  if (!pathname.startsWith("/_next") && !pathname.startsWith("/api/")) {
    const match = await lookupCachedRedirect(pathname);
    if (match) {
      // Non-blocking hit counter bump.
      void bumpRedirectHit(match.id);
      const url = match.destination.startsWith("http")
        ? match.destination
        : new URL(match.destination, req.url).toString();
      return NextResponse.redirect(url, match.kind === "permanent" ? 308 : 307);
    }
  }

  const session = req.auth;
  const role = (session?.user as { role?: string } | undefined)?.role;

  if (pathname.startsWith("/admin")) {
    if (!session?.user || role !== "admin") {
      return NextResponse.redirect(new URL("/login", req.url));
    }
  }
  if (pathname.startsWith("/account")) {
    if (!session?.user) {
      return NextResponse.redirect(new URL("/login", req.url));
    }
  }

  // OrthoPrep is members-only — every interactive sub-path is gated. The
  // marketing landing (/products/orthoprep exactly) stays public for SEO
  // and prospective members. Admins always pass through (support + QA).
  if (
    pathname.startsWith("/products/orthoprep/question-bank") ||
    pathname.startsWith("/products/orthoprep/quiz") ||
    pathname.startsWith("/products/orthoprep/stats")
  ) {
    if (!session?.user) {
      const loginUrl = new URL("/login", req.url);
      loginUrl.searchParams.set(
        "callbackUrl",
        pathname + (req.nextUrl.search || ""),
      );
      return NextResponse.redirect(loginUrl);
    }
    // session.user only exists for active members + admins (the session
    // callback in auth.ts strips user when status!=active), so no further
    // status check is needed here.
  }

  return NextResponse.next();
});

export const config = {
  // Match everything except static assets + image optimisation, so admin
  // redirects can apply to any public page. Admin + account routes are
  // still protected by the session check above.
  matcher: ["/((?!_next/static|_next/image|favicon\\.ico|brand|uploads).*)"],
};
