import { NextRequest, NextResponse } from "next/server";
import { getToken } from "next-auth/jwt";
import { protectedRoutes } from "@/lib/protectedRoutes";

// Settings paths that are allowed without a specific permission (nav visible to all; page can enforce edit separately)
const SETTINGS_PATHS_ALLOWED_WITHOUT_PERMISSION = [
  "/settings/calling-whatsapp",
];

// Public paths that don't require authentication
const PUBLIC_PATHS = [
  "/login",
  "/404",
  "/unauthorized",
  "/api/auth",
  "/resetPassword",
  "/forgotPassword",
  "/public",
  "/maintenance",
  "/under-maintenance",
];

const middleware = async (request: NextRequest) => {
  const { pathname } = request.nextUrl;

  console.log(`[Middleware] Processing: ${pathname}`);

  // Skip middleware for static files and API routes (except auth)
  if (
    pathname.startsWith("/_next") ||
    (pathname.startsWith("/api") && !pathname.startsWith("/api/auth")) ||
    pathname.includes(".")
  ) {
    console.log(`[Middleware] Skipping static/api: ${pathname}`);
    return NextResponse.next();
  }

  // Allow public paths
  if (PUBLIC_PATHS.some((path) => pathname.startsWith(path))) {
    console.log(`[Middleware] Public path allowed: ${pathname}`);
    return NextResponse.next();
  }

  try {
    // Get session token
    const token = await getToken({
      req: request,
      secret: process.env.NEXTAUTH_SECRET,
    });

    console.log(`[Middleware] Token exists: ${!!token}`);

    // If no token, redirect to login
    if (!token) {
      console.log(
        `[Middleware] No token, redirecting to login from: ${pathname}`
      );
      const loginUrl = new URL("/login", request.url);
      // Only add callbackUrl if it's not the root path
      if (pathname !== "/") {
        loginUrl.searchParams.set("callbackUrl", pathname);
      }
      return NextResponse.redirect(loginUrl);
    }

    // Extract permissions from token
    const userPermissions = (token.permissions as string[]) || [];

    // Find the most specific matching protected route
    const matchedRoute = protectedRoutes
      .filter((route) => pathname.startsWith(route.path))
      .sort((a, b) => b.path.length - a.path.length)[0]; // Get most specific match

    // If not a protected route, allow access
    if (!matchedRoute) {
      return NextResponse.next();
    }

    // Allow access for settings paths that don't require a specific permission
    if (SETTINGS_PATHS_ALLOWED_WITHOUT_PERMISSION.some((p) => pathname.startsWith(p))) {
      return NextResponse.next();
    }

    // Check if user has the required permission
    const hasPermission = userPermissions.some(
      (permission) =>
        permission === matchedRoute.permission ||
        permission === matchedRoute.permission.replace(":read", ":*") || // Admin wildcard
        permission.endsWith(":*") // Global admin
    );

    // If no permission, redirect to unauthorized page
    if (!hasPermission) {
      console.log(
        `Access denied for ${pathname}. Required: ${
          matchedRoute.permission
        }, User has: ${userPermissions.join(", ")}`
      );
      return NextResponse.rewrite(new URL("/unauthorized", request.url));
    }

    // Add permission info to headers for debugging (optional)
    const response = NextResponse.next();
    response.headers.set("x-user-permissions", userPermissions.join(","));
    response.headers.set("x-required-permission", matchedRoute.permission);

    return response;
  } catch (error) {
    console.error("Middleware error:", error);
    // On error, redirect to login for safety
    return NextResponse.redirect(new URL("/login", request.url));
  }
};

export default middleware;

// This ensures the middleware runs only on application routes, not static files
export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api/auth (NextAuth API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico, favicon.svg
     * - public folder files (images, etc.)
     * - files with extensions
     */
    "/((?!api/(?!auth)|_next/static|_next/image|favicon|.*\\..*|firebase-messaging-sw\\.js).*)",
  ],
};
