import type { RemoveGroupPrefix } from "../client/types";
import type { KeyAndValue, KeyAndValueToObject } from "../internal/type-utils";
import { Controller, ResourceController, type ControllerMethods } from "./Controller";
import type { HttpRequest } from "./HttpRequest";
import type { MiddlewareReturnType } from "./Router";
type HttpMethod = "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
export type ApiRouterHandler<Input, Output, Params> = (req: HttpRequest<Input, Params>) => Output;
type CallbackHandler<Input, Output, Params> = (req: HttpRequest<Input, Params>) => Promise<Output> | Output;
type ParseRouteHandler<T extends new () => Controller, K extends ControllerMethods<T>, M extends HttpMethod> = InstanceType<T>[K] extends (req: HttpRequest<infer Input, infer Params>) => infer Output ? RouteHandler<M, Input, Output, Params> : never;
export declare class RouteHandler<M extends HttpMethod, Input, Output, Params> {
    method: M;
    private handler;
    private methodName?;
    __internal_brand: string;
    middlewares: string[];
    constructor(method: M, handler: CallbackHandler<Input, Output, Params> | (new () => Controller), methodName?: any);
    __internal_use(): {
        run: any;
        middlewares: string[];
    };
    run(_req: HttpRequest<Input, Params>): any;
    middleware(middlewareList: string[]): this;
}
export declare class FileHandler {
    constructor(...args: ConstructorParameters<typeof RouteHandler>);
}
export type RouteHandlers = Partial<{
    post: RouteHandler<"POST", any, any, any>;
    get: RouteHandler<"GET", any, any, any>;
    delete: RouteHandler<"DELETE", any, any, any>;
    put: RouteHandler<"PUT", any, any, any>;
}>;
export type ApiRoutes = Record<string, RouteHandler<any, any, any, any> | FileHandler | RouteHandlers | typeof ApiRouter | ResourceRoutes<any>>;
export type ResourceRoutes<T extends new () => ResourceController> = {
    first: {
        get: ParseRouteHandler<T, TestControllerMethod<T, "list">, "GET">;
        post: ParseRouteHandler<T, TestControllerMethod<T, "store">, "POST">;
    };
    second: {
        get: ParseRouteHandler<T, TestControllerMethod<T, "show">, "GET">;
        put: ParseRouteHandler<T, TestControllerMethod<T, "update">, "PUT">;
        delete: ParseRouteHandler<T, TestControllerMethod<T, "delete">, "DELETE">;
    };
};
export declare class ApiRouter {
    static __brand: string;
    routes: ApiRoutes;
    middlewares: string[];
    middleware(_req: HttpRequest<any, any>): MiddlewareReturnType;
    get<Input, Output, Params>(handler: CallbackHandler<Input, Output, Params>): RouteHandler<"GET", Input, Output, Params>;
    get<T extends new () => Controller, K extends ControllerMethods<T>>(handler: T, methodName: K): ParseRouteHandler<T, K, "GET">;
    post<Input, Output, Params>(handler: CallbackHandler<Input, Output, Params>): RouteHandler<"POST", Input, Output, Params>;
    post<T extends new () => Controller, K extends ControllerMethods<T>>(handler: T, methodName: K): ParseRouteHandler<T, K, "POST">;
    put<Input, Output, Params>(handler: CallbackHandler<Input, Output, Params>): RouteHandler<"PUT", Input, Output, Params>;
    put<T extends new () => Controller, K extends ControllerMethods<T>>(handler: T, methodName: K): ParseRouteHandler<T, K, "PUT">;
    patch<Input, Output, Params>(handler: CallbackHandler<Input, Output, Params>): RouteHandler<"PATCH", Input, Output, Params>;
    patch<T extends new () => Controller, K extends ControllerMethods<T>>(handler: T, methodName: K): ParseRouteHandler<T, K, "PATCH">;
    delete<Input, Output, Params>(handler: CallbackHandler<Input, Output, Params>): RouteHandler<"DELETE", Input, Output, Params>;
    delete<T extends new () => Controller, K extends ControllerMethods<T>>(handler: T, methodName: K): ParseRouteHandler<T, K, "DELETE">;
    resource<T extends new () => ResourceController>(Controller: T): ResourceRoutes<T>;
    file<Input, Output, Params>(handler: CallbackHandler<Input, Output, Params>): FileHandler;
    file<T extends new () => Controller, K extends ControllerMethods<T>>(handler: T, methodName: K): FileHandler;
}
type TestControllerMethod<T extends new () => Controller, K extends string> = K extends ControllerMethods<T> ? K : never;
type RouteHandlerParser<T, Prefix extends string = ""> = T extends RouteHandler<infer Method, infer Input, infer Output, infer Params> ? KeyAndValue<`${Method & string}:${Prefix & string}`, ApiRouterHandler<Input, Output, Params>> : never;
type RouteHandlersParser<T, Prefix extends string = ""> = T extends RouteHandlers ? {
    [K in keyof T]: T[K] extends RouteHandler<infer Method, infer Input, infer Output, infer Params> ? KeyAndValue<`${Method & string}:${Prefix & string}`, ApiRouterHandler<Input, Output, Params>> : never;
}[keyof T] : never;
type RouterInstanceParser<T extends new () => ApiRouter, Prefix extends string> = T extends new () => ApiRouter ? RouteParser<InstanceType<T>["routes"], `${Prefix & string}`> : 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 RemoveTrailingId<T> = T extends `${infer Head}/:${infer Tail}` ? Tail extends `${string}/:${string}` ? `${Head}/:${RemoveTrailingId<Tail>}` : Head extends `/:${string}` ? "X" : `${Head}` : T;
type ResourceRoutesParser<T extends ResourceRoutes<new () => ResourceController>, U extends PropertyKey> = RouteHandlersParser<T["first"], RemoveTrailingId<U & string>> | RouteHandlersParser<T["second"], `${U & string}`>;
type RouteParser<T extends ApiRoutes, Prefix extends PropertyKey = "", K extends keyof T = keyof T> = K extends any ? T[K] extends ResourceRoutes<any> ? ResourceRoutesParser<T[K], ParsePrefixAndKey<Prefix, K>> : T[K] extends RouteHandler<any, any, any, any> ? RouteHandlerParser<T[K], ParsePrefixAndKey<Prefix, K>> : T[K] extends new () => ApiRouter ? RouterInstanceParser<T[K], ParsePrefixAndKey<Prefix, K>> : T[K] extends RouteHandlers ? RouteHandlersParser<T[K], `${Prefix & string}${K extends "/" ? "" : K & string}`> : never : never;
export type CreateRPC<T extends ApiRouter, Prefix extends PropertyKey = ""> = KeyAndValueToObject<RouteParser<T["routes"], Prefix>>;
declare class ProductsController extends ResourceController {
    list(): Promise<void>;
    show(): Promise<void>;
    store(): Promise<void>;
    update(): Promise<void>;
    delete(): Promise<void>;
}
declare class OrgRouter extends ApiRouter {
    routes: {
        "/:orgId/products/:productId": ResourceRoutes<typeof ProductsController>;
    };
}
declare class RootRouter extends ApiRouter {
    middlewares: string[];
    routes: {
        "/org": typeof OrgRouter;
    };
}
export type RootRPC = CreateRPC<RootRouter>;
export {};
//# sourceMappingURL=ApiRouter.d.ts.map