import { AxiosRequestConfig, AxiosInstance, AxiosResponse } from 'axios';
import { IAxiosRetryConfig, AxiosRetry } from 'axios-retry';

declare enum RequestType {
    GET = "GET",
    POST = "POST",
    PUT = "PUT",
    PATCH = "PATCH",
    DELETE = "DELETE"
}
type BackoffOptions = 'exponential' | 'linear' | 'none';
interface AxiosRetryClientRetryConfig extends IAxiosRetryConfig {
    delayFactor?: number;
    backoff?: BackoffOptions;
}
interface AxiosRetryClientRequestConfig extends AxiosRequestConfig {
    retryConfig?: AxiosRetryClientRetryConfig;
}
interface AxiosRetryClientResponse<T> {
    request: AxiosResponse;
    data: T;
}
interface AxiosRetryClientOptions extends IAxiosRetryConfig {
    /**
     * Configuration for the underlying axios instance
     */
    axiosConfig?: Omit<AxiosRequestConfig, 'baseURL'>;
    /**
     * Base URL for the API
     */
    baseURL: string;
    /**
     * Whether to log request and response details
     */
    debug?: boolean;
    /**
     * Debug level. 'normal' will log request and response data. 'verbose' will
     * log all axios properties for the request and response
     */
    debugLevel?: 'normal' | 'verbose';
    /**
     * Name of the client. Used for logging
     */
    name?: string;
    /**
     * Our extended configuration for the axios-retry plugin. See [axios-retry](https://www.npmjs.com/package/axios-retry) for more details.
     * The default configuration is `{ retries: 3, retryDelay: axiosRetry.exponentialDelay } with a 500ms initial retry delay`.
     */
    retryConfig?: AxiosRetryClientRetryConfig;
}
declare class AxiosRetryClient {
    axios: AxiosInstance;
    axiosConfig: AxiosRetryClientOptions['axiosConfig'];
    axiosRetry: AxiosRetry;
    baseURL: AxiosRetryClientOptions['baseURL'];
    debug: AxiosRetryClientOptions['debug'];
    debugLevel: AxiosRetryClientOptions['debugLevel'];
    name: AxiosRetryClientOptions['name'];
    retryConfig: AxiosRetryClientRetryConfig;
    constructor(config: AxiosRetryClientOptions);
    private getRetryDelay;
    private _request;
    get<T = any>(url: string, config?: AxiosRetryClientRequestConfig): Promise<AxiosRetryClientResponse<T>>;
    post<T = any>(url: string, data: any, config?: AxiosRetryClientRequestConfig): Promise<AxiosRetryClientResponse<T>>;
    put<T = any>(url: string, data: any, config?: AxiosRetryClientRequestConfig): Promise<AxiosRetryClientResponse<T>>;
    patch<T = any>(url: string, data: any, config?: AxiosRetryClientRequestConfig): Promise<AxiosRetryClientResponse<T>>;
    delete<T = any>(url: string, config?: AxiosRetryClientRequestConfig): Promise<AxiosRetryClientResponse<T>>;
    /**
     * Override this method in your extending class to modify the request data or
     * config before the request is sent.
     *
     * @deprecated Use preRequestFilter instead. This will be removed in a future version.
     * @param requestType - The request type (GET, POST, PUT, PATCH, DELETE)
     * @param url - The request URL
     * @param data - The request data
     * @param config - The request config
     * @returns The modified request parameters
     */
    protected beforeRequestFilter(requestType: RequestType, url: string, data: any, config: AxiosRequestConfig): Promise<{
        data: any;
        config: AxiosRequestConfig;
    }>;
    /**
     * Define this requestType in your extending class to globally modify the
     * request data or config before the request is sent.
     *
     * @param requestType - The request type (GET, POST, PUT, PATCH, DELETE)
     * @param url - The request URL
     * @param data - The request data
     * @param config - The request config
     * @returns The modified request parameters
     */
    protected preRequestFilter(requestType: RequestType, url: string, data: any, config: AxiosRequestConfig): Promise<{
        data: any;
        config: AxiosRequestConfig;
    }>;
    /**
     * Override this method in your extending class to perform any actions before
     * the request is sent such as logging the request details. By default, this will
     * log the request details if debug is enabled.
     *
     * @deprecated Use preRequestAction instead. This will be removed in a future version.
     * @param requestType - The request type (GET, POST, PUT, PATCH, DELETE)
     * @param url - The request URL
     * @param data - The request data
     * @param config - The request config
     */
    protected beforeRequestAction(requestType: RequestType, url: string, data: any, config: AxiosRequestConfig): Promise<void>;
    /**
     * Override this method in your extending class to perform any actions before
     * the request is sent such as logging the request details. By default, this will
     * log the request details if debug is enabled.
     * @param requestType - The request type (GET, POST, PUT, PATCH, DELETE)
     * @param url - The request URL
     * @param data - The request data
     * @param config - The request config
     */
    protected preRequestAction(requestType: RequestType, url: string, data: any, config: AxiosRequestConfig): Promise<void>;
    /**
     * Handles errors from the axios instance. Override this method for
     * custom error handling functionality specific to the API you are
     * consuming.
     * @param error - The error object
     * @param reqType - The request type
     * @param url - The request URL
     * @see https://axios-http.com/docs/handling_errors
     */
    protected errorHandler(error: any, reqType: RequestType, url: string): void;
    /**
     * Handles errors where a response is not received or other errors occur
     * @param error - The error object
     * @param reqType - The request type
     * @param url - The request URL
     */
    protected handleResponseNotReceivedOrOtherError(error: any, reqType: RequestType, url: string): void;
}
/**
 * Base class for API errors.
 * @extends Error
 */
declare class ApiResponseError extends Error {
    /**
     * The HTTP status code.
     */
    status: number;
    /**
     * The response text.
     */
    response: object | string;
    /**
     * The cause of the error. Usually an AxiosError.
     */
    cause?: any;
    /**
     * Creates an instance of ApiError.
     * @param {string} message - The error message.
     * @param {number} status - The HTTP status code.
     * @param {object|string} response - The response.
     * @param {any} cause - The cause of the error.
     */
    constructor(message: string, status: number, response: object | string, cause?: any);
}

export { ApiResponseError, AxiosRetryClient, type AxiosRetryClientOptions, type AxiosRetryClientRequestConfig, RequestType };
