import { auth } from "@/auth";
import { appUrl } from "@/lib/app-url";
import { NextResponse } from "next/server";

// /api/agents is machine-to-machine and carries its own bearer token, so it
// must bypass the interactive login redirect.
//
// /embed is exempt for a different reason: it is framed by
// accounts.sticknife.com, and Authentik refuses to be framed. Redirecting a
// signed-out visitor would render an X-Frame-Options error inside charon's
// panel -- a broken box with no explanation -- so the embed checks the session
// itself and offers a sign-in link that escapes the frame. It still shows
// nothing to an unauthenticated caller; see src/app/embed/profile/page.tsx.
//
// /api/profile is exempt for the same reason as /api/agents -- it accepts a
// bearer token as well as a session, and a 302 to a login page is a useless
// answer to a server-to-server GET. It authenticates every request itself and
// refuses with 401 rather than redirecting.
const PUBLIC_PATHS = ["/login", "/api/auth", "/api/agents", "/api/profile", "/embed"];
const PUBLIC_FILE = /\.(?:avif|gif|ico|jpg|jpeg|png|svg|webp)$/i;

export default auth((req) => {
  const { pathname } = req.nextUrl;
  const isPublic = PUBLIC_FILE.test(pathname) || PUBLIC_PATHS.some((p) => pathname.startsWith(p));

  if (!req.auth && !isPublic) {
    return NextResponse.redirect(appUrl("/login"));
  }
});

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\.(?:avif|gif|ico|jpg|jpeg|png|svg|webp)$).*)"],
};
