// middleware.ts
import { NextRequest, NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";
import { isInstalled } from "./lib/install-state";

// Route prefixes that require a valid admin session. Reads included — this
// is an admin-only surface, not a public API. The inbound-mail webhook and
// cron purge route are intentionally excluded since they authenticate via
// HMAC signature / cron secret instead of a user session (see their
// individual route handlers).
const PROTECTED_PREFIXES = [
  "/dashboard",
  "/api/domains",
  "/api/emails",
  "/api/inbox",
  "/api/stats",
];

export async function middleware(req: NextRequest) {
  const { pathname } = req.nextUrl;
  const isInstallPath = pathname === "/install" || pathname.startsWith("/api/install");
  // NextAuth's own routes must always be reachable — SessionProvider fetches
  // /api/auth/session on every page load, including /install itself (via
  // the root layout), and that should resolve to an empty session rather
  // than get redirected mid-flight.
  const isNextAuthPath = pathname.startsWith("/api/auth");

  // --- 1. Install gate (checked before anything else, including auth) -----
  if (!isInstalled()) {
    // Pre-install, only the wizard itself (page + its API routes) and
    // NextAuth's own endpoints are reachable; everything else bounces to
    // /install.
    if (isInstallPath || isNextAuthPath) {
      return NextResponse.next();
    }
    return NextResponse.redirect(new URL("/install", req.url));
  }

  // Once installed, the wizard is permanently locked — re-running it could
  // let someone repoint the database or recreate the admin account.
  if (isInstallPath) {
    return NextResponse.redirect(new URL("/login", req.url));
  }

  // --- 2. Session auth gate for protected routes --------------------------
  const needsAuth = PROTECTED_PREFIXES.some((prefix) => pathname.startsWith(prefix));
  if (needsAuth) {
    const token = await getToken({ req, secret: process.env.NEXTAUTH_SECRET });
    if (!token) {
      return NextResponse.redirect(new URL("/login", req.url));
    }
  }

  return NextResponse.next();
}

// Run on every route except Next's own static asset paths — the function
// body above decides per-path what (if anything) to enforce.
export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};
