import * as next_server from 'next/server';
import { NextRequest, NextResponse, NextFetchEvent } from 'next/server';

/**
 * Type definitions for Next Route Guard
 *
 * This module defines the TypeScript interfaces and types used throughout the package.
 */

/**
 * Type alias for a Next.js middleware function
 * This is the standard signature for Next.js middleware
 */
type NextMiddleware = (request: NextRequest) => Promise<NextResponse | undefined> | NextResponse | undefined;
/**
 * Route map for protected and public routes
 *
 * This interface represents the structure of the JSON file generated during build time
 * that contains the lists of protected and public routes based on directory conventions.
 */
interface RouteMap {
    /**
     * Array of paths that are protected and require authentication
     * These paths will trigger authentication checks when accessed
     */
    protected: string[];
    /**
     * Array of paths that are public and don't require authentication
     * These paths are freely accessible without authentication
     */
    public: string[];
}
/**
 * Configuration options for creating a route guard middleware
 *
 * These options control how the middleware behaves, including how to check
 * authentication, how to handle unauthenticated requests, and which routes
 * to protect or exclude.
 */
interface RouteGuardOptions {
    /**
     * Function to determine if a user is authenticated
     *
     * This function is called for protected routes to check if the user is authenticated.
     * You should implement this function based on your authentication system (JWT, cookies, etc.)
     *
     * @example
     * isAuthenticated: (request) => {
     *   const token = request.cookies.get('auth-token')?.value;
     *   return !!token;
     * }
     */
    isAuthenticated: (request: NextRequest) => Promise<boolean> | boolean;
    /**
     * Function to handle unauthenticated requests
     *
     * This function is called when a user tries to access a protected route
     * without being authenticated. The default behavior redirects to /login.
     *
     * @default Redirects to /login with the original URL as a 'from' parameter
     *
     * @example
     * onUnauthenticated: (request) => {
     *   if (request.nextUrl.pathname.startsWith('/api/')) {
     *     return new NextResponse(
     *       JSON.stringify({ error: 'Authentication required' }),
     *       { status: 401, headers: { 'Content-Type': 'application/json' } }
     *     );
     *   }
     *
     *   // Default login redirect for non-API routes
     *   const url = request.nextUrl.clone();
     *   url.pathname = '/login';
     *   url.searchParams.set('from', request.nextUrl.pathname);
     *   return NextResponse.redirect(url);
     * }
     */
    onUnauthenticated?: (request: NextRequest) => Promise<NextResponse> | NextResponse;
    /**
     * Map of protected and public routes
     *
     * This is the route map generated during build time by the CLI tools.
     * It contains the lists of protected and public routes based on directory conventions.
     *
     * This must be generated at build time to work with Edge runtime since it can't
     * scan the filesystem during execution.
     *
     * @example
     * // Import the generated route map
     * import routeMap from './app/route-map.json';
     */
    routeMap: RouteMap;
    /**
     * Default behavior for routes not explicitly marked in the route map
     *
     * When set to true (default), routes are protected unless explicitly marked as public.
     * When set to false, routes are public unless explicitly marked as protected.
     *
     * @default true - Routes are protected by default
     */
    defaultProtected?: boolean;
    /**
     * URLs to exclude from authentication checks
     *
     * These URLs will bypass the authentication check entirely, regardless of
     * whether they are in the protected routes list.
     *
     * Can be strings with glob-style wildcards or RegExp objects.
     *
     * @default ['/api/(.*)'] - Excludes all API routes
     *
     * @example
     * excludeUrls: [
     *   '/api/(.*)',        // All API routes
     *   '/static/(.*)',     // Static assets
     *   '/public/(.*)'      // Anything under /public/
     * ]
     */
    excludeUrls?: (string | RegExp)[];
}

/**
 * Core implementation of Next Route Guard middleware.
 * This module contains the runtime logic for checking if a route should be protected
 * and enforcing authentication based on the route map generated at build time.
 */

/**
 * Creates a Next.js middleware function that enforces route authentication
 * based on the directory structure conventions in the app router.
 *
 * This is the main entry point for the runtime middleware that checks if a user
 * is authenticated and handles redirection for protected routes.
 *
 * @param options - Configuration options for the middleware
 * @returns A Next.js middleware function
 */
declare function createRouteGuardMiddleware(options: RouteGuardOptions): (request: NextRequest) => Promise<NextResponse<unknown>>;

/**
 * A middleware function that takes a request and returns a response.
 * This is compatible with Next.js middleware system.
 */
type Middleware = (request: next_server.NextRequest, event?: NextFetchEvent) => Promise<next_server.NextResponse | undefined> | next_server.NextResponse | undefined;
/**
 * A middleware factory that wraps a middleware.
 * This is used to create reusable middleware components that can be chained together.
 */
type MiddlewareFactory = (middleware: Middleware) => Middleware;
/**
 * Chain multiple middleware factories together.
 *
 * This allows you to compose multiple middleware functions into a single middleware pipeline.
 * Each middleware in the chain can choose to call the next middleware or short-circuit the chain.
 *
 * @param functions - Array of middleware factories to chain together
 * @param index - Current index in the chain (used internally for recursion)
 * @returns A middleware function representing the entire chain
 *
 * @example
 * ```ts
 * // Create middleware factories
 * const withLogging: MiddlewareFactory = (next) => {
 *   return (request) => {
 *     console.log(`Request: ${request.method} ${request.url}`);
 *     return next(request);
 *   };
 * };
 *
 * const withAuth: MiddlewareFactory = (next) => {
 *   return (request) => {
 *     if (!isAuthenticated(request)) {
 *       return NextResponse.redirect('/login');
 *     }
 *     return next(request);
 *   };
 * };
 *
 * // Use the chain
 * export default function middleware(req: NextRequest, ev: NextFetchEvent) {
 *   return chain([withLogging, withAuth])(req, ev);
 * }
 * ```
 */
declare function chain(functions: MiddlewareFactory[], index?: number): Middleware;
/**
 * Generate a route map based on the Next.js app directory structure.
 *
 * This function analyzes the directory structure to identify routes and their protection status.
 * It's used by the CLI tools to generate the route map at build time or during development.
 *
 * Routes are classified as protected or public based on their directory context:
 * - Routes inside a "(public)" directory group are marked as public
 * - Routes inside a "(protected)" directory group are marked as protected
 * - Routes inherit protection status from their parent directories
 * - Routes are protected by default if not explicitly marked
 *
 * @param appDir - Path to the Next.js app directory
 * @param publicPatterns - Array of directory name patterns that indicate public routes
 * @param protectedPatterns - Array of directory name patterns that indicate protected routes
 * @returns Object containing either the generated route map or an error message
 */
declare function generateRouteMap(appDir: string, publicPatterns?: string[], protectedPatterns?: string[]): {
    error?: string;
    routeMap?: {
        public: string[];
        protected: string[];
    };
};

export { type Middleware, type MiddlewareFactory, type NextMiddleware, type RouteGuardOptions, type RouteMap, chain, createRouteGuardMiddleware, generateRouteMap };
