import { NextResponse, NextRequest } from "next/server";

// Inline cookie name to avoid importing next/headers (Server Component API)
// in proxy context. Must stay in sync with lib/admin/auth.ts SESSION_COOKIE_NAME.
const SESSION_COOKIE_NAME = "quto_admin_session";

// ============================================================
// Admin route protection — cookie-presence guard only.
// Full session validation (expiry, revocation, user status)
// happens inside each server component / API route via
// getAdminSession() / requireAuth(). This guard is fast (no DB)
// and prevents unauthenticated browsers from loading admin HTML.
// ============================================================
const ADMIN_PUBLIC_PATHS = [
  "/admin/login",
  "/admin/change-password",
];

function isAdminPath(pathname: string) {
  return pathname.startsWith("/admin");
}

function isAdminPublicPath(pathname: string) {
  return ADMIN_PUBLIC_PATHS.some(
    (p) => pathname === p || pathname.startsWith(p + "/")
  );
}

export async function proxy(request: NextRequest) {
  const { pathname } = request.nextUrl;
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set("x-pathname", pathname);

  // ── Admin route guard ──────────────────────────────────────
  if (isAdminPath(pathname) && !isAdminPublicPath(pathname)) {
    const sessionCookie = request.cookies.get(SESSION_COOKIE_NAME);
    if (!sessionCookie?.value) {
      const loginUrl = new URL("/admin/login", request.url);
      loginUrl.searchParams.set("reason", "unauthorized");
      return NextResponse.redirect(loginUrl);
    }
  }

  // ── Dynamic redirect lookup (from CMS) ────────────────────
  // Skip static assets, API calls, admin paths, and internal Next.js files.
  if (
    pathname.startsWith("/_next") ||
    pathname.startsWith("/api") ||
    pathname.startsWith("/admin") ||
    pathname.includes(".")
  ) {
    return NextResponse.next({ request: { headers: requestHeaders } });
  }

  try {
    const lookupUrl = new URL(
      `/api/redirects/lookup?source=${encodeURIComponent(pathname)}`,
      request.url
    );
    const res = await fetch(lookupUrl, { cache: "no-store" });
    if (res.ok) {
      const data = await res.json();
      if (data.redirect && data.redirect.destination) {
        const method =
          Number(data.redirect.method) ||
          (data.redirect.permanent ? 301 : 302);
        const destination = data.redirect.destination.startsWith("http")
          ? data.redirect.destination
          : new URL(data.redirect.destination, request.url).toString();

        return NextResponse.redirect(destination, method);
      }
    }
  } catch {
    // Graceful fallback: continue request
  }

  return NextResponse.next({ request: { headers: requestHeaders } });
}

export const config = {
  matcher: [
    /*
     * Match all request paths except for:
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     * - images, uploads, static extensions
     */
    "/((?!_next/static|_next/image|images|uploads|favicon.ico).*)",
  ],
};
