import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

// Routes that require authentication
const PROTECTED_PREFIXES = ['/agent', '/customer', '/agency', '/developer', '/dashboard'];

// Role → allowed path prefix mapping
const ROLE_ROUTES: Record<string, string> = {
  agent: '/agent',
  customer: '/customer',
  agency: '/agency',
  developer: '/developer',
  super_admin: '/admin',
};

// Decode JWT payload without verifying signature (verification happens on the API)
function decodeJwtPayload(token: string): Record<string, any> | null {
  try {
    const parts = token.split('.');
    if (parts.length !== 3) return null;
    const payload = Buffer.from(parts[1], 'base64url').toString('utf-8');
    return JSON.parse(payload);
  } catch {
    return null;
  }
}

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  // Only intercept protected routes
  const isProtected = PROTECTED_PREFIXES.some((prefix) => pathname.startsWith(prefix));
  if (!isProtected) return NextResponse.next();

  // Read token — stored in cookie 'access_token' (set by auth context on login)
  const token = request.cookies.get('access_token')?.value;

  if (!token) {
    const loginUrl = new URL('/login', request.url);
    loginUrl.searchParams.set('redirect', pathname);
    return NextResponse.redirect(loginUrl);
  }

  const payload = decodeJwtPayload(token);

  if (!payload || !payload.role) {
    const loginUrl = new URL('/login', request.url);
    loginUrl.searchParams.set('redirect', pathname);
    return NextResponse.redirect(loginUrl);
  }

  // Check token expiry
  if (payload.exp && payload.exp * 1000 < Date.now()) {
    const loginUrl = new URL('/login', request.url);
    loginUrl.searchParams.set('redirect', pathname);
    return NextResponse.redirect(loginUrl);
  }

  const role: string = payload.role;

  // /dashboard → redirect to role-specific dashboard
  if (pathname === '/dashboard' || pathname === '/dashboard/') {
    const rolePath = ROLE_ROUTES[role] || '/dashboard';
    if (rolePath !== '/dashboard') {
      return NextResponse.redirect(new URL(rolePath, request.url));
    }
    return NextResponse.next();
  }

  // Enforce role-based access for role-specific routes
  for (const [routeRole, routePrefix] of Object.entries(ROLE_ROUTES)) {
    if (pathname.startsWith(routePrefix) && routePrefix !== '/dashboard') {
      if (role !== routeRole && role !== 'super_admin') {
        // Redirect to their own dashboard
        const ownPath = ROLE_ROUTES[role] || '/dashboard';
        return NextResponse.redirect(new URL(ownPath, request.url));
      }
      break;
    }
  }

  return NextResponse.next();
}

export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - api (API routes)
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     */
    '/((?!api|_next/static|_next/image|favicon.ico).*)',
  ],
};
