import { cache } from 'hono/cache';
import { Context } from 'hono';
import { cors } from 'hono/cors';
import { ExecutionContext } from 'hono';
import { ipRestriction } from 'hono/ip-restriction';
import { JSONParsed } from 'hono/utils/types';
import { JSONValue } from 'hono/utils/types';
import { OpenAPIHono } from '@hono/zod-openapi';
import { SimplifyDeepArray } from 'hono/utils/types';
import { TypedResponse } from 'hono';
import { z } from '@hono/zod-openapi';

/**
 * Represents an application with configuration options and methods
 * for managing routes, OpenAPI documentation, and error handling.
 * @example
 * const app = new App({
 *   version: '1.0.0',
 *   title: 'BACKAN Example app',
 *   description: 'API documentation for BACKAN Example',
 *   cors: {
 *     origin: '*',
 *     allowMethods: ['GET'],
 *   },
 * });
 * @see https://backan.pigeonposse.com/guide/core/app
 */
export declare class App<Env extends object> extends AppSuper<Env> {
    #private;
    /**
     * The version of the application.
     */
    version: string;
    /**
     * The title of the application.
     */
    title: string;
    /**
     * A brief description of the application.
     */
    description: string;
    /**
     * Contact information for the application.
     */
    contact: {
        url?: string;
        mail?: string;
    } | undefined;
    constructor(data?: AppParameters);
    setIpRestriction({ pattern, getIP, rules, onError, }: {
        pattern?: string;
        getIP: Parameters<typeof ipRestriction>[0];
        rules?: Parameters<typeof ipRestriction>[1];
        onError?: Parameters<typeof ipRestriction>[2];
    }): void;
    /**
     * The fetch method for the application.
     *
     * Will be entry point of your application..
     * @type {Function}
     */
    fetch: (request: Request, Env?: {} | Env["Bindings"] | undefined, executionCtx?: ExecutionContext) => Response | Promise<Response>;
    /**
     * Generates the full URL for the OpenAPI documentation endpoint.
     * @param   {Context}            c - The Hono context object.
     * @returns {string | undefined}   - The full URL for the OpenAPI documentation, or undefined if not configured.
     */
    getDocUrl(c: Context): string | undefined;
    /**
     * Retrieves the OpenAPI configuration object.
     * @returns {object} - The OpenAPI document object.
     */
    getOpenApiObject(): OpenApiObject<Env>;
}

/**
 * Parameters for configuring the App.
 */
export declare type AppParameters = {
    /** The version of the application. */
    version: string;
    /** The title of the application. */
    title: string;
    /** A brief description of the application. */
    description: string;
    /** Contact information for the application. */
    contact?: {
        /** The URL for contact information. */
        url?: string;
        /** The email address for contact. */
        mail?: string;
    };
    /**
     * Whether to format JSON responses prettily. If is a string, it will be used as a query parameter for pretty printing.
     * @default true
     */
    jsonPretty?: boolean | string;
    /**
     * CORS (Cross-Origin Resource Sharing) configuration.
     *
     * This extends from `hono` cors params.
     * @see https://hono.dev/docs/middleware/builtin/cors
     * @example
     * {
     *   origin       : '*',
     *   allowMethods : [ 'GET'],
     * }
     */
    cors?: Parameters<typeof cors>[0];
    /**
     * Cache Opts.
     * @see {@link https://hono.dev/docs/middleware/builtin/cache}
     * @example
     * ```{
     *     cacheName: 'my-app',
     *     cacheControl: 'max-age=3600',
     *   }
     * ```
     */
    cache?: Parameters<typeof cache>[0];
    /**
     * Controls the behavior of the trailing slash in a URL.
     *
     * - `'trim'`    → Removes the trailing slash if it exists.
     * - `'append'`  → Adds a trailing slash if it does not exist.
     * - `false`     → Leaves the URL unchanged.
     * @default false
     */
    trailingSlash?: 'trim' | 'append' | false;
    /**
     * The value for X-Powered-By header.
     * @default backan
     */
    poweredBy?: string | false;
    /** Documentation configuration. */
    docs?: {
        /**
         * The path where documentation is served.
         * @default '/docs'
         */
        path?: string;
        /**
         * Whether the documentation is active.
         * @default true
         */
        active?: boolean;
    };
    /** Health check route configuration. */
    health?: {
        /** The path where the health check route is served. */
        path?: string;
        /** Whether the health check route is active. */
        active?: boolean;
        /** Additional options for the health route. */
        opts?: HealthRouteOptions;
    };
    /** Add hooks */
    hook?: {
        /** Hook before all */
        beforeAll?: <E extends object>(app: AppSuper<E>['app']) => void;
    };
};

declare class AppSuper<Env extends object> {
    /**
     * Method to add route with OpenAPI configuration.
     */
    add: AppSuper<Env>['app']['openapi'];
    constructor();
    /**
     * Validation option works with zod library.
     * @see https://zod.dev/
     * @example const stringSchema = validation.string()
     */
    validation: typeof z;
    RESPONSE_MESSAGES: {
        ERROR_500: string;
        ERROR_404: string;
        ERROR_400: string;
        NO_DATA_ERROR: string;
        HELP_500: string;
        HELP_400: string;
        SUCCESS_FETCH: string;
        ERROR_PAGE_NOT_FOUND: string;
        ERROR_VALIDATION: string;
    };
    /**
     * Predefined error IDs used for consistent error identification in responses.
     * These are used throughout the application to ensure uniform error handling.
     *
     */
    ERROR_ID: {
        readonly PAGE_NOT_FOUND: "PAGE-NOT-FOUND";
        readonly BAD_REQUEST: "BAD-REQUEST";
        readonly SERVER_FETCH: "SERVER-FETCH";
        readonly VALIDATION: "VALIDATION";
        readonly NO_DOCS_PROVIDED: "NO-DOCS-PROVIDED";
    };
    /**
     * Contains methods to generate and handle responses, including error handling.
     *
     * This object allows adding success responses, 500 errors, and 400 errors with predefined structures.
     */
    response: {
        addSuccessResponse: <Data extends object>(c: Context, data: Data) => Response & TypedResponse<SimplifyDeepArray<Data> extends JSONValue ? JSONValue extends JSONValue & SimplifyDeepArray<Data> ? never : JSONParsed<Data> : never, 200, "json">;
        add500ErrorObject: (data: {
            id: string;
            error?: unknown;
        }) => {
            message: string;
            error: {};
            help: string;
            id: string;
            status: 500;
        };
        add500Error: (c: Context, e: unknown) => Response & TypedResponse<    {
        message: string;
        error: {};
        help: string;
        id: string;
        status: 500;
        }, 500, "json">;
        add400ErrorObject: (e: unknown) => {
            error: {};
            help: string;
            id: string;
            message: string;
            status: 400;
        };
        add400Error: (c: Context, e: unknown) => Response & TypedResponse<    {
        error: {};
        help: string;
        id: string;
        message: string;
        status: 400;
        }, 400, "json">;
        add404Error: (c: Context, data: {
            id: string;
            message: string;
            help: string;
        }) => Response & TypedResponse<    {
        id: string;
        message: string;
        help: string;
        status: 404;
        }, 404, "json">;
        addSuccess201Response: <Data extends object>(c: Context, data: Data) => Response & TypedResponse<SimplifyDeepArray<Data> extends JSONValue ? JSONValue extends JSONValue & SimplifyDeepArray<Data> ? never : JSONParsed<Data> : never, 201, "json">;
        addSuccess202Response: <Data extends object>(c: Context, data: Data) => Response & TypedResponse<SimplifyDeepArray<Data> extends JSONValue ? JSONValue extends JSONValue & SimplifyDeepArray<Data> ? never : JSONParsed<Data> : never, 202, "json">;
        schemaError500: z.ZodObject<{
            status: z.ZodLiteral<500>;
            id: z.ZodString;
            message: z.ZodString;
            error: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
            help: z.ZodString;
        }, "strip", z.ZodTypeAny, {
            message: string;
            status: 500;
            id: string;
            error: {};
            help: string;
        }, {
            message: string;
            status: 500;
            id: string;
            error: {};
            help: string;
        }>;
        schemaError404: z.ZodObject<{
            status: z.ZodLiteral<404>;
            id: z.ZodString;
            message: z.ZodString;
            error: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
            help: z.ZodString;
        }, "strip", z.ZodTypeAny, {
            message: string;
            status: 404;
            id: string;
            error: {};
            help: string;
        }, {
            message: string;
            status: 404;
            id: string;
            error: {};
            help: string;
        }>;
        schemaError400: z.ZodObject<{
            status: z.ZodLiteral<400>;
            id: z.ZodString;
            message: z.ZodString;
            error: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
            help: z.ZodString;
        }, "strip", z.ZodTypeAny, {
            message: string;
            status: 400;
            id: string;
            error: {};
            help: string;
        }, {
            message: string;
            status: 400;
            id: string;
            error: {};
            help: string;
        }>;
        responseJSONSuccess: <OBJ extends z.ZodTypeAny>(schema: OBJ, more?: object) => {
            description: string;
            content: {
                'application/json': {
                    schema: OBJ;
                };
            };
        };
        responseStreamSuccess: <OBJ extends z.ZodTypeAny>(schema: OBJ, more?: object) => {
            description: string;
            content: {
                'text/plain': {
                    schema: OBJ;
                };
            };
        };
        responseJSONError500: {
            description: string;
            content: {
                'application/json': {
                    schema: z.ZodObject<{
                        status: z.ZodLiteral<500>;
                        id: z.ZodString;
                        message: z.ZodString;
                        error: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
                        help: z.ZodString;
                    }, "strip", z.ZodTypeAny, {
                        message: string;
                        status: 500;
                        id: string;
                        error: {};
                        help: string;
                    }, {
                        message: string;
                        status: 500;
                        id: string;
                        error: {};
                        help: string;
                    }>;
                };
            };
        };
        responseJSONError404: {
            description: string;
            content: {
                'application/json': {
                    schema: z.ZodObject<{
                        status: z.ZodLiteral<404>;
                        id: z.ZodString;
                        message: z.ZodString;
                        error: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
                        help: z.ZodString;
                    }, "strip", z.ZodTypeAny, {
                        message: string;
                        status: 404;
                        id: string;
                        error: {};
                        help: string;
                    }, {
                        message: string;
                        status: 404;
                        id: string;
                        error: {};
                        help: string;
                    }>;
                };
            };
        };
        responseJSONError400: {
            description: string;
            content: {
                'application/json': {
                    schema: z.ZodObject<{
                        status: z.ZodLiteral<400>;
                        id: z.ZodString;
                        message: z.ZodString;
                        error: z.ZodObject<{}, "strip", z.ZodTypeAny, {}, {}>;
                        help: z.ZodString;
                    }, "strip", z.ZodTypeAny, {
                        message: string;
                        status: 400;
                        id: string;
                        error: {};
                        help: string;
                    }, {
                        message: string;
                        status: 400;
                        id: string;
                        error: {};
                        help: string;
                    }>;
                };
            };
        };
    };
    protected app: OpenAPIHono<Env, {}, "/">;
    /**
     * Hono app instace for add hono custom routes or middlewars or etc
     */
    honoInstance: OpenAPIHono<Env, {}, "/">;
    /**
     * Logs a string of data, determining if it's JSON and formatting accordingly.
     * This method can be overridden to customize how logging is handled within the application.
     * By default, it logs data to the console, parsing JSON strings if necessary.
     * @param {string} data - The string to log. If it's JSON, it will be parsed and logged as an object.
     * @example
     *
     * // Customizing logger
     * app.logger = (data: string) => {
     *   // Custom logging logic, e.g., writing to a file
     *   fs.appendFileSync('app.log', data + '\n');
     * };
     */
    logger: (data: string) => void;
    /**
     * Adds a route to the BACKAN application instance.
     * @param {Route} app - The route to add, containing the path and the associated app.
     * @param route
     * @deprecated
     */
    addRoute<R extends Route<Env, string>>(route: R): void;
    /**
     * Adds a route to the BACKAN application instance.
     * @param {AppSuper} app - The route to add, containing the path and the associated app.
     * @param path
     * @param route
     */
    route<R extends AppSuper<Env>>(path: string, route: R): void;
    /**
     * Registers an OpenAPI component within the app's OpenAPI registry.
     * @returns {void}
     */
    addComponent<T extends Parameters<typeof AppSuper.app.openAPIRegistry.registerComponent>[0]>(type: T, name: string, component: Parameters<typeof AppSuper.app.openAPIRegistry.registerComponent<T>>[2]): {
        name: string;
        ref: {
            $ref: string;
        };
    };
    /**
     * Retrieves a list of unique paths from the application's routes.
     * @returns {string[]} - An array of unique paths as strings.
     */
    getPaths(): string[];
}

/**
 * Options for configuring the health check route.
 */
declare type HealthRouteOptions = {
    /** Custom message for a 400 Bad Request error during the health check. */
    error400?: string;
    /** Summary of the health check endpoint. */
    summary?: string;
    /** Detailed description of the health check endpoint. */
    description?: string;
    /**
     * Additional response parameters that can be included in the health check response.
     */
    additionalResponseValues?: Record<string, boolean>;
};

declare type OpenApiObject<Env extends object> = ReturnType<App<Env>['app']['getOpenAPIDocument']>;

/**
 * Represents a route in the application.
 * Provides methods to add and create routes with OpenAPI integration.
 * @description Add and manage routes with OpenAPI validation and configuration.
 * @example
 * const route = class Route({
 *   path: 'id'
 * })
 * route.add(
 * 	// configuration
 * )
 * route.create(
 * 	// configuration
 * )
 * console.log(
 * 	route.path,
 * 	route.validation
 * )
 * @example https://github.com/BimaAdi/Integrate-hono-with-openapi/blob/main/src/index.ts
 * @see  https://backan.pigeonposse.com/guide/core/route
 * @deprecated
 */
export declare class Route<Env extends object, Path extends string> extends AppSuper<Env> {
    /**
     * The path of the route.
     */
    readonly path: Path;
    /**
     * Method to add OpenAPI configuration to the route.
     */
    add: AppSuper<Env>['app']['openapi'];
    constructor(params: RouteParams<Path>);
}

export declare type RouteParams<Path extends string> = {
    /**
     * The path of the route.
     * @example 'users'
     */
    path: Path;
};

export { }
