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

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

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();
    }

    // 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).*)",
  ],
};