import { RawAxiosRequestHeaders, AxiosInstance, AxiosResponse, AxiosRequestConfig } from 'axios';
import { ILogger } from '../logging/logger.js';
import { Interceptor } from './interceptor.js';
import { Token } from './token.js';

type ClientOptions = {
    /**
     * The client name
     */
    readonly name?: string;
    /**
     * The authorization token to use
     */
    readonly token?: Token;
    /**
     *: ILogger instance to use
     */
    readonly logger?: ILogger;
    /**
     * The baseUrl to prefix all client requests with
     */
    readonly baseUrl?: string;
    /**
     * Default request timeout (ms)
     */
    readonly timeout?: number;
    /**
     * Default headers
     */
    readonly headers?: RawAxiosRequestHeaders;
    /**
     * Default interceptors to register
     */
    readonly interceptors?: Array<Interceptor>;
};
type RequestConfig<D = any> = AxiosRequestConfig<D> & {
    /**
     * If provided, this token will be used instead of
     * the default token provided in the `ClientOptions`
     */
    token?: Token;
};
type InterceptorRegistry = {
    readonly requestId?: number;
    readonly responseId?: number;
    readonly interceptor: Interceptor;
};
declare class Client {
    token?: Token;
    readonly name: string;
    protected options: ClientOptions;
    protected log: ILogger;
    protected http: AxiosInstance;
    protected seq: number;
    protected interceptors: Map<number, InterceptorRegistry>;
    constructor(options?: ClientOptions);
    get<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: RequestConfig<D>): Promise<R>;
    post<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: RequestConfig<D>): Promise<R>;
    put<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: RequestConfig<D>): Promise<R>;
    patch<T = any, R = AxiosResponse<T>, D = any>(url: string, data?: D, config?: RequestConfig<D>): Promise<R>;
    delete<T = any, R = AxiosResponse<T>, D = any>(url: string, config?: RequestConfig<D>): Promise<R>;
    request<T = any, R = AxiosResponse<T>, D = any>(config: RequestConfig<D>): Promise<R>;
    /**
     * Register an interceptor to use
     * as middleware for the request/response/error
     */
    use(interceptor: Interceptor): number;
    /**
     * Eject an interceptor
     */
    eject(id: number): void;
    /**
     * Clear (Eject) all interceptors
     */
    clear(): void;
    /**
     * Create a copy of the client
     */
    clone(options?: ClientOptions): Client;
    protected withConfig(config?: RequestConfig): Promise<RequestConfig<any>>;
}

export { Client, type ClientOptions, type RequestConfig };
