import * as _dvcol_common_utils from '@dvcol/common-utils';
import { RecursiveRecord, Updater, Observer, CancellablePromise } from '@dvcol/common-utils';
import { BaseQuery, BaseSettings, BaseOptions, BaseTransformed } from '../models/base-client.model.cjs';
import { BaseTemplateOptions, BaseTemplate, BaseInit, BaseBody, BaseRequest } from '../models/base-template.model.cjs';
import { IApi, ClientEndpoint } from '../models/client-endpoint.model.cjs';

/**
 * Represents a client with common functionality.
 *
 * @class BaseClient
 */
declare abstract class BaseClient<QueryType extends BaseQuery = BaseQuery, ResponseType extends Response = Response, SettingsType extends BaseSettings = BaseSettings, AuthenticationType extends RecursiveRecord = RecursiveRecord> {
    private readonly _settings;
    private _cache;
    private _authentication;
    private _callListeners;
    get settings(): SettingsType;
    /**
     * Gets the authentication information.
     *
     * @readonly
     */
    get auth(): AuthenticationType;
    /**
     * Updates the authentication information.
     * @param auth - The new authentication information.
     *
     * @protected
     */
    protected updateAuth(auth: Updater<AuthenticationType>): void;
    /**
     * Subscribes to changes in authentication information.
     * Emits the current authentication information on auth related changes (oAuth calls, token revocation, token refresh, etc.).
     *
     * @param observer - The observer function.
     * @returns A function to unsubscribe from changes.
     */
    onAuthChange(observer: Observer<AuthenticationType | undefined>): () => boolean;
    /**
     * Subscribes to  API queries.
     * Emits query information on every call to the API.
     *
     * @param observer - The observer function.
     * @returns A function to unsubscribe from queries.
     */
    onCall(observer: Observer<QueryType>): () => boolean;
    /**
     * Unsubscribes observers from authentication and call listeners.
     * If no observer is provided, unsubscribes all observers.
     *
     * @param observer - The observer to be removed.
     */
    unsubscribe(observer?: Observer<QueryType | AuthenticationType | undefined>): {
        auth: boolean;
        call: boolean;
    };
    /**
     * Clears the cache entry for the specified key.
     * If no key is provided, clears the entire cache.
     *
     * @param key - The cache key.
     * @param exact - If the key to be evicted needs to be an exact match or a regex pattern (defaults to true).
     */
    clearCache(key?: string, exact?: boolean): _dvcol_common_utils.SyncOrAsync<boolean> | _dvcol_common_utils.SyncOrAsync<void>;
    /**
     * Binds BaseTraktClient _call instance to the endpoint instance and the call method of the endpoint
     *
     * @private
     *
     * @param api - The TraktApi to bind to
     *
     * @example client.endpoints({ request })
     */
    protected bindToEndpoint(api: IApi): {
        [x: string]: ClientEndpoint<RecursiveRecord, unknown, boolean, BaseTemplateOptions> | IApi<RecursiveRecord, unknown, boolean>;
    };
    /**
     * Creates an instance of BaseClient.
     *
     * @param cacheStore - An optional cache store to manage cache read/write.
     * @param settings - The client settings.
     * @param authentication - The authentication information.
     * @param api - The API endpoints.
     */
    protected constructor({ cacheStore, ...settings }: BaseOptions<SettingsType, ResponseType>, authentication: AuthenticationType, api: IApi);
    /**
     * Calls the API with the given template and parameters.
     *
     * @template P - The type of the parameters.
     * @template R - The type of the response.
     *
     * @param {BaseTemplate<P>} template - The template for the API endpoint.
     * @param {P} [params={}] - The parameters for the API call.
     * @param {BaseInit} [init] - Additional initialization options.
     *
     * @returns {Promise<Response>} A promise that resolves to the API response.
     *
     * @protected
     */
    protected _call<P extends RecursiveRecord = RecursiveRecord, O extends BaseTemplateOptions = BaseTemplateOptions>(template: BaseTemplate<P, O>, params?: P, init?: BaseInit): CancellablePromise<ResponseType>;
    /**
     * Transforms the parameters templates or init before performing a request.
     *
     * @template T - The type of the parameters.
     *
     * @param {BaseTemplate<T>} template - The template for the API endpoint.
     * @param {T} params - The actual parameters.
     * @param {BaseInit} [init] - Additional initialization options.
     *
     * @returns {{ template: BaseTemplate<T>; params: T; init: BaseInit }} The transformed template.
     *
     * @protected
     */
    protected _transform?<T extends RecursiveRecord = RecursiveRecord>(template: BaseTemplate<T>, params: T, init?: BaseInit): BaseTransformed<T>;
    /**
     * Parses headers from a template and returns a {@link HeadersInit}
     *
     * @template T - The type of the parameters.
     *
     * @param {BaseTemplate<T>} template - The template for the API endpoint.
     * @param {T} params - The actual parameters.
     *
     * @returns {HeadersInit} The parsed request headers.
     *
     * @protected
     * @abstract
     */
    protected _parseHeaders?<T extends RecursiveRecord = RecursiveRecord>(template: BaseTemplate<T>, params: T): HeadersInit;
    /**
     * Parses the parameters and constructs the URL for a API request.
     *
     * @template T - The type of the parameters.
     *
     * @param {BaseTemplate<T>} template - The template for the API endpoint.
     * @param {T} params - The parameters for the API call.
     *
     * @returns {URL} The URL for the API request.
     *
     * @throws {Error} Throws an error if mandatory parameters are missing or if a filter is not supported.
     *
     * @protected
     * @abstract
     */
    protected _parseUrl<T extends RecursiveRecord = RecursiveRecord>(template: BaseTemplate<T>, params: T): URL;
    /**
     * Parses body from a template and stringifies a {@link BodyInit}
     *
     * @template T - The type of the parameters.
     *
     * @param body - The expected body structure.
     * @param {T} params - The actual parameters.
     * @param request - The base request information.
     *
     * @returns {BodyInit} The parsed request body.
     *
     * @protected
     * @abstract
     */
    protected _parseBody<T extends RecursiveRecord = RecursiveRecord>(body: BaseBody<string | keyof T>, params: T, request?: BaseRequest): BodyInit;
    /**
     * Parses the response from the API before returning from the call.
     * @param response - The response from the API.
     * @param request - The request information.
     * @param template - The template for the API endpoint.
     *
     * @returns {Response} The parsed response.
     *
     * @protected
     */
    protected _parseResponse?<T extends RecursiveRecord = RecursiveRecord>(response: Response, request?: BaseRequest, template?: BaseTemplate<T>): Response;
}

export { BaseClient };
