import type { NextRequest } from 'next/server';
import { NextResponse } from 'next/server';
import { SessionGateway } from '@/lib/gateways/SessionGateway';
import { handleAuthFlow } from '@/lib/auth/AuthFlowRouter';
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
import { routeMatchers } from '@/lib/routing/RouteConfig';
import { SearchParamBuilder } from '@/lib/routing/search-params/SearchParamBuilder';

const logger = new ConsoleLogger();

/**
 * Server-side route protection middleware
 *
 * Uses UnifiedLoginStateMachine for deterministic, type-safe authentication flow
 */
export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  const cookieHeader = request.headers.get('cookie') || '';
  
  // logger.info('[MIDDLEWARE] ========== REQUEST START ==========');
  // logger.info('[MIDDLEWARE] Request details', {
  //   pathname,
  //   method: request.method,
  //   url: request.url,
  //   cookieHeaderLength: cookieHeader.length,
  //   cookiePreview: cookieHeader.substring(0, 100) + (cookieHeader.length > 100 ? '...' : '')
  // });
  
  // Set x-pathname header for layout-level protection
  const response = NextResponse.next();
  response.headers.set('x-pathname', pathname);

  // Get session
  // logger.info('[MIDDLEWARE] Fetching session...');
  const sessionGateway = new SessionGateway();
  const session = await sessionGateway.getSessionFromRequest(request);
  
  // logger.info('[MIDDLEWARE] Session fetched', {
  //   hasSession: !!session,
  //   userId: session?.user?.userId,
  //   role: session?.user?.role,
  //   sessionData: session ? JSON.stringify(session, null, 2) : 'null'
  // });
  
  // Convert session to state machine format
  const authSession = session ? {
    userId: session.user?.userId || '',
    role: session.user?.role || 'driver',
    roles: session.user?.role ? [session.user.role] : ['driver']
  } : null;

  // logger.info('[MIDDLEWARE] Auth session converted', {
  //   authSession: authSession ? JSON.stringify(authSession, null, 2) : 'null'
  // });

  // Debug: Log route classification
  const isPublic = routeMatchers.isPublic(pathname);
  const requiresRole = routeMatchers.requiresRole(pathname);
  // logger.info('[MIDDLEWARE] Route classification', {
  //   path: pathname,
  //   isPublic,
  //   requiresRole
  // });

  // Use state machine to determine action
  let result;
  try {
    // logger.info('[MIDDLEWARE] Calling handleAuthFlow...');
    result = handleAuthFlow(authSession, pathname);
    // logger.info('[MIDDLEWARE] handleAuthFlow result', {
    //   result: JSON.stringify(result, null, 2)
    // });
  } catch (error) {
    logger.error('[MIDDLEWARE] Error in auth flow', error instanceof Error ? error : new Error(String(error)));
    // Fallback: redirect to login if there's an error
    return NextResponse.redirect(new URL(`/auth/login${SearchParamBuilder.auth(pathname)}`, request.url));
  }
  
  // logger.info('[MIDDLEWARE] Decision summary', {
  //   pathname,
  //   hasSession: !!authSession,
  //   role: authSession?.role,
  //   shouldRedirect: result.shouldRedirect,
  //   redirectUrl: result.redirectUrl
  // });

  if (result.shouldRedirect && result.redirectUrl) {
    const redirectUrl = new URL(result.redirectUrl, request.url);
    // logger.info('[MIDDLEWARE] REDIRECTING', {
    //   from: pathname,
    //   to: redirectUrl.toString()
    // });
    const redirectResponse = NextResponse.redirect(redirectUrl);
    // logger.info('[MIDDLEWARE] ========== REQUEST END (REDIRECT) ==========');
    return redirectResponse;
  }

  // Handle /sponsor root redirect (preserves cookies)
  // Only reached if authenticated and allowed
  if (pathname === '/sponsor') {
    // logger.info('[MIDDLEWARE] Redirecting /sponsor → /sponsor/dashboard');
    return NextResponse.redirect(new URL('/sponsor/dashboard', request.url));
  }

  // All checks passed
  // logger.info('[MIDDLEWARE] ALLOWING ACCESS', { pathname });
  // logger.info('[MIDDLEWARE] ========== REQUEST END (ALLOW) ==========');
  return response;
}

/**
 * Configure which routes the middleware should run on
 */
export const config = {
  matcher: [
    /*
     * Match all request paths except:
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - _next/data (Next.js data requests)
     * - favicon.ico (favicon file)
     * - health (health check endpoint)
     * - media (media assets)
     * - Files with extensions (static assets)
     */
    '/((?!_next/static|_next/image|_next/data|favicon.ico|health|media|.*\\.(?:svg|png|jpg|jpeg|gif|webp|mp4|webm|mov|avi)$).*)',
  ],
};
