import type { RemoveGroupPrefix } from "../client/types";
import type { KeyAndValue, KeyAndValueToObject } from "../internal/type-utils";
import type { Controller } from "./Controller";
import type { HttpRequest } from "./HttpRequest";
type ControllerMethods<T extends new () => Controller> = {
    [K in keyof InstanceType<T>]: InstanceType<T>[K] extends Function ? K : never;
}[keyof InstanceType<T>];
export type ViewRoutes = Record<string, ViewRoute<any, any, any> | LayoutRoute<any, any, any, any> | RedirectRoute<any, any, any> | (new () => ViewRouter)>;
type CallbackHandler<Input, Output, Params> = (req: HttpRequest<Input, Params>) => Promise<Output> | Output;
export type ViewHandler<Input, Output, Params> = CallbackHandler<Input, Output, Params> | (new () => Controller);
type ParseViewControllerHandler<C extends new () => Controller, M extends ControllerMethods<C>> = InstanceType<C>[M] extends (req: HttpRequest<infer Input, infer Params>) => infer Output ? ViewRoute<Input, Output, Params> : never;
type ParseLayoutControllerHandler<T extends ViewRoutes, C extends new () => Controller, M extends ControllerMethods<C>> = InstanceType<C>[M] extends (req: HttpRequest<infer Input, infer Params>) => infer Output ? LayoutRoute<T, Input, Output, Params> : never;
type RedirectOutput = {
    destination: string;
    permanent?: boolean;
    status?: number;
};
export declare class RedirectRoute<Input, Output, Params> {
    kind: "redirect";
    viewPath: string;
    middlewares: string[];
    private handler;
    constructor(handler?: CallbackHandler<Input, RedirectOutput, Params> | [new () => Controller, ControllerMethods<any>]);
    run(req: HttpRequest<Input, Params>, path: string): Promise<{}>;
    middleware(middlewares: string[]): this;
}
export declare class ViewRoute<Input, Output, Params> {
    viewPath: string;
    middlewares: string[];
    private handler;
    constructor(viewPath: string, handler?: CallbackHandler<Input, Output, Params> | [new () => Controller, ControllerMethods<any>]);
    run(req: HttpRequest<Input, Params>, path: string): Promise<{
        FILE: Awaited<Output>;
    } | {
        [x: string]: Awaited<Output> & {
            breadcrumb: {
                label: any;
                href: string;
            };
        };
        FILE?: undefined;
    }>;
    middleware(middlewares: string[]): this;
}
export declare class LayoutRoute<T extends ViewRoutes, Input, Output, Params> {
    viewPath: string;
    children: new () => ViewRouter;
    middlewares: string[];
    private handler;
    constructor(viewPath: string, handlerOrRoutes: CallbackHandler<Input, Output, Params> | [new () => Controller, ControllerMethods<any>] | T, routes?: T);
    run(req: HttpRequest<Input, Params>, path: string): Promise<{
        [x: string]: Awaited<Output> & {
            breadcrumb: {
                label: any;
                href: string;
            };
        };
    }>;
    middleware(middlewares: string[]): this;
}
export declare class ViewRouter {
    middlewares: string[];
    routes: ViewRoutes;
    view<C extends new () => Controller, M extends ControllerMethods<C>>(viewPath: string, handler?: [C, M]): ParseViewControllerHandler<C, M>;
    view<Input, Output, Params>(viewPath: string, handler?: ViewHandler<Input, Output, Params>): ViewRoute<Input, Output, Params>;
    redirect<C extends new () => Controller, M extends ControllerMethods<C>>(handler?: [C, M]): ParseViewControllerHandler<C, M>;
    redirect<Input, Output, Params>(handler?: ViewHandler<Input, Output, Params>): ViewRoute<Input, Output, Params>;
    layout<T extends ViewRoutes>(viewPath: string, handlerOrRoutes: T, routes?: T): LayoutRoute<T, any, any, any>;
    layout<T extends ViewRoutes, C extends new () => Controller, M extends ControllerMethods<C>>(viewPath: string, handlerOrRoutes: [C, M], routes?: T): ParseLayoutControllerHandler<T, C, M>;
    layout<T extends ViewRoutes, Input, Output, Params>(viewPath: string, handlerOrRoutes: CallbackHandler<Input, Output, Params>, routes?: T): LayoutRoute<T, Input, Output, Params>;
}
type ViewRouteParser<T, Prefix extends PropertyKey = ""> = T extends ViewRoute<infer Input, infer Output, infer Params> ? KeyAndValue<`view:${Prefix & string}`, ViewHandler<Input, Output, Params>> : never;
type LayoutRouteParser<T, Prefix extends PropertyKey = ""> = T extends LayoutRoute<infer Routes, infer I, infer O, infer P> ? RoutesParser<Routes, Prefix> | KeyAndValue<`layout:${Prefix & string}`, ViewHandler<I, O, P>> : never;
type ParsePrefixAndKey<P extends PropertyKey, K extends PropertyKey, U extends string = `${P & string}${K & string}`> = U extends "//" ? "/" : U extends `${infer T1}//${infer T2}` ? `${RemoveGroupPrefix<T1>}/${RemoveGroupPrefix<T2>}` : U extends `${infer T1}/${infer T2}/` ? `${RemoveGroupPrefix<T1>}/${RemoveGroupPrefix<T2>}` : RemoveGroupPrefix<U>;
type RouterInstanceParser<T extends new () => ViewRouter, Prefix extends PropertyKey = ""> = RoutesParser<InstanceType<T>["routes"], Prefix>;
type RoutesParser<T extends ViewRoutes, Prefix extends PropertyKey = "", K extends keyof T = keyof T> = K extends any ? T[K] extends new () => ViewRouter ? RouterInstanceParser<T[K], ParsePrefixAndKey<Prefix, K>> : T[K] extends LayoutRoute<any, any, any, any> ? LayoutRouteParser<T[K], ParsePrefixAndKey<Prefix, K>> : T[K] extends ViewRoute<any, any, any> ? ViewRouteParser<T[K], ParsePrefixAndKey<Prefix, K>> : never : never;
export type CreateViewRPC<T extends ViewRouter, Prefix extends PropertyKey = ""> = KeyAndValueToObject<RoutesParser<T["routes"], Prefix>>;
export {};
//# sourceMappingURL=ViewRouter.d.ts.map