import { CacheStoreEntity, RecursiveRecord, CancellablePromise, HttpMethods } from '@dvcol/common-utils';
import { BaseInit, BaseTemplateOptions, BaseTemplate, BaseBody } from './base-template.model.cjs';

type CacheResponse<T> = {
    previous?: CacheStoreEntity<TypedResponse<T>>;
    current?: CacheStoreEntity<TypedResponse<T>>;
    isCache?: boolean;
    evict?: () => string | boolean | undefined | Promise<string | boolean | undefined>;
};
type TypedResponse<T> = Omit<Response, 'json'> & {
    json(): Promise<T>;
    cache?: CacheResponse<T>;
};
type ResponseOrTypedResponse<T = unknown> = T extends never ? Response : TypedResponse<T>;
type ClientEndpointCall<Parameter extends RecursiveRecord = Record<string, never>, Response = unknown> = (param?: Parameter, init?: BaseInit) => CancellablePromise<ResponseOrTypedResponse<Response>>;
type CacheKeyFunction<Parameter extends RecursiveRecord = RecursiveRecord> = (param?: Parameter, init?: BaseInit, cacheOption?: BaseCacheOption) => string;
type BaseCacheOption = {
    /** If true, the cache will be forcefully evicted */
    force?: boolean;
    /** The duration in milliseconds after which the cached values are ignored (computed from the cachedAt value). */
    retention?: number;
    /** If true, the eviction date will be persisted and enforce in subsequent calls, regardless or retention context. */
    saveRetention?: boolean;
    /** If true, the cache will be deleted if an error occurs. */
    evictOnError?: boolean;
    /** Overrides or complements the cache key computation. */
    cacheKey?: string | ((key: string) => string);
};
type ClientEndpointCache<Parameter extends RecursiveRecord = Record<string, never>, Response = unknown> = {
    evict: (param?: Parameter, init?: BaseInit, cacheOptions?: BaseCacheOption) => Promise<string | undefined>;
} & ((param?: Parameter, init?: BaseInit, cacheOptions?: BaseCacheOption) => CancellablePromise<TypedResponse<Response>>);
interface ClientEndpoint<Parameter extends RecursiveRecord = Record<string, never>, Response = unknown> {
    (param?: Parameter, init?: BaseInit): CancellablePromise<ResponseOrTypedResponse<Response>>;
}
declare class ClientEndpoint<Parameter extends RecursiveRecord = Record<string, never>, Response = unknown, Cache extends boolean = true, Option extends BaseTemplateOptions = BaseTemplateOptions> implements BaseTemplate<Parameter, Option> {
    method: HttpMethods;
    url: string;
    opts: Option;
    body?: BaseBody<string | keyof Parameter>;
    init?: BaseInit;
    seed?: Partial<Parameter>;
    transform?: (param: Parameter) => Parameter;
    validate?: (param: Parameter) => boolean;
    cached: Cache extends true ? Omit<this, 'cached'> & ClientEndpointCache<Parameter, Response> : never;
    resolve: (param?: Parameter) => URL;
    get config(): {
        method: "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE" | "CONNECT" | "OPTIONS" | "TRACE";
        url: string;
        opts: Option;
        init: BaseInit;
        body: Partial<Record<string | keyof Parameter, string | boolean | symbol>>;
    };
    constructor(template: BaseTemplate<Parameter, Option>);
}
type IApi<Parameter extends RecursiveRecord = RecursiveRecord, Response = unknown, Cache extends boolean = boolean> = {
    [key: string]: ClientEndpoint<Parameter, Response, Cache> | IApi<Parameter>;
};

export { type BaseCacheOption, type CacheKeyFunction, type CacheResponse, ClientEndpoint, type ClientEndpointCache, type ClientEndpointCall, type IApi, type ResponseOrTypedResponse, type TypedResponse };
