import { NextRequest, NextFetchEvent, NextResponse } from 'next/server';
import { Path } from 'path-to-regexp';

/**
 * A middleware that uses a `next()` callback for async control flow, like Express.
 * @param req The `NextRequest` object.
 * @param event The `NextFetchEvent` object.
 * @param next A callback to pass control to the next middleware.
 * @returns A `Promise` resolving to a `NextResponse` or `undefined`.
 */
type NextMiddlewareMulti = (req: NextRequest, event: NextFetchEvent, next: (req?: NextRequest, event?: NextFetchEvent) => Promise<NextResponse | undefined>) => Promise<NextResponse | undefined>;
/**
 * A standard Next.js middleware.
 * @param req The `NextRequest` object.
 * @param event The `NextFetchEvent` object.
 * @returns A `NextResponse`, `undefined`, or `void`.
 */
type StandardNextMiddleware = (req: NextRequest, event: NextFetchEvent) => Promise<NextResponse | undefined | void> | NextResponse | undefined | void;
/**
 * An error-handling middleware, executed when a preceding middleware throws an error.
 * It receives the error and a `next` callback to proceed to the next error handler.
 * @param error The thrown error.
 * @param req The `NextRequest` object.
 * @param event The `NextFetchEvent` object.
 * @param next A callback to pass control to the next error-handling middleware.
 * @returns A `Promise` resolving to a `NextResponse` to handle the error.
 */
type ErrorMiddleware = (error: Error, req: NextRequest, event: NextFetchEvent, next: (error?: Error, req?: NextRequest, event?: NextFetchEvent) => Promise<NextResponse | undefined>) => Promise<NextResponse | undefined>;
/** A union of all possible middleware handler types. */
type MiddlewareHandler = NextMiddlewareMulti | StandardNextMiddleware | ErrorMiddleware;
/** A path pattern or array of patterns compatible with `path-to-regexp`. */
type NextJsMatcher = Path;
/** A function that returns `true` if the middleware should be executed. */
type PredicateMatcher = (req: NextRequest) => boolean;
/** A union of all possible matcher types. */
type MiddlewareMatcher = NextJsMatcher | PredicateMatcher;
/**
 * Configuration object for a single middleware in the chain.
 */
interface MiddlewareConfig {
    /** The middleware handler function. */
    handler: MiddlewareHandler;
    /** An optional matcher to control when the middleware runs. */
    matcher?: MiddlewareMatcher;
}
/** A union of a `MiddlewareConfig` object or a raw handler function. */
type Middleware = MiddlewareConfig | MiddlewareHandler;
/**
 * Options for configuring the behavior of the `chain` function.
 */
interface ChainOptions {
    /** If `true`, logs the execution flow of the middleware chain. Defaults to `false`. */
    debug?: boolean;
}
/**
 * Chains multiple Next.js middlewares, supporting sequential execution, route matching,
 * and error handling.
 *
 * @param middlewares An array of middleware handlers or config objects.
 * @param options Optional configuration for the chain's behavior.
 * @returns A single Next.js-compatible middleware.
 */
declare function chain(middlewares: Middleware[], options?: ChainOptions): (req: NextRequest, event: NextFetchEvent) => Promise<NextResponse>;

export { type ChainOptions, type ErrorMiddleware, type Middleware, type MiddlewareConfig, type MiddlewareHandler, type MiddlewareMatcher, type NextJsMatcher, type NextMiddlewareMulti, type PredicateMatcher, type StandardNextMiddleware, chain };
