import { AxiosError, AxiosInstance } from 'axios';

/**
 * Represents a generic object in the APIs
 * Use for parameters like context, traits etc.
 */
interface ApiObject {
    [index: string]: string | number | boolean | undefined | ApiObject | Date | null | (string | number | boolean | ApiObject | Date | null | undefined)[];
}
/**
 * Represents the integration options object
 * Example usages:
 * IntegrationOptions { All: false, "Google Analytics": true, "Braze": true}
 * IntegrationOptions { All: true, "Chartbeat": false, "Customer.io": false}
 */
interface IntegrationOptions {
    All?: boolean;
    [index: string]: boolean | ApiObject | undefined;
}
/**
 * Represents the first argument object for flushOverride method
 */
type FlushOverrideMessage = {
    host: string;
    writeKey: string;
    data: {
        batch: Record<string, any>[];
        sentAt: Date;
    };
    headers: Record<string, string>;
    reqTimeout?: number;
    flush: (callback?: ApiCallback) => void;
    done: (error?: Error) => void;
    isErrorRetryable: (error: AxiosError) => boolean;
};
/**
 * Represents the constructor options object
 * Example usages:
 * ConstructorOptions { flushAt: 20, "flushInterval": 20000, "enable": true, "maxInternalQueueSize":20000, "logLevel": "info"/"debug"/"error"/"silly"/"off"}
 */
interface ConstructorOptions {
    timeout?: number;
    flushAt?: number;
    flushInterval?: number;
    enable?: boolean;
    maxInternalQueueSize?: number;
    logLevel?: 'silly' | 'debug' | 'info' | 'error' | 'off';
    flushOverride?: (message: FlushOverrideMessage) => void;
}
/**
 * Represents the callback in the APIs
 */
type ApiCallback = (err?: any, data?: any) => void;

interface IAnalytics {
    /**
     * Send an identify `message`.
     *
     * @param {Object} message
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.traits (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    identify(message: {
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        traits?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send a group `message`.
     *
     * @param {Object} message
     * @param {String} message.groupId
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.traits (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    group(message: {
        groupId: string;
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        traits?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send a track `message`.
     *
     * @param {Object} message
     * @param {String} message.event
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.properties (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    track(message: {
        event: string;
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        properties?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send a page `message`.
     *
     * @param {Object} message
     * @param {String} message.name
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.properties (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    page(message: {
        name: string;
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        properties?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send an alias `message`.
     *
     * @param {Object} message
     * @param {String} message.previousId
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.properties (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    alias(message: {
        previousId: string;
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        properties?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Flush the current queue
     *
     * @param {Function} [callback] (optional)
     * @return
     */
    flush(callback?: ApiCallback): void;
}

declare class Analytics implements IAnalytics {
    timeout?: number;
    flushAt: number;
    flushInterval?: number;
    enable?: boolean;
    maxInternalQueueSize: number;
    logLevel?: 'silly' | 'debug' | 'info' | 'error' | 'off';
    flushOverride?: (message: FlushOverrideMessage) => void;
    queue: {
        message: Record<string, any>;
        callback?: ApiCallback;
    }[];
    writeKey?: string;
    host: string;
    flushed: boolean;
    axiosInstance: AxiosInstance;
    logger: any;
    flushTimer?: null | any;
    timer?: null | any;
    /**
     * Initialize a new `Analytics` with your RudderStack source's `writeKey` and an
     * optional dictionary of `options`.
     *
     * @param {String} writeKey
     * @param {String} dataPlaneURL
     * @param {Object=} options (optional)
     * @param {Number=20} options.flushAt (default: 20)
     * @param {Number=20000} options.flushInterval (default: 20000)
     * @param {Boolean=true} options.enable (default: true)
     * @param {Number=20000} options.maxInternalQueueSize (default: 20000)
     * @param {Number} options.timeout (default: false)
     * @param {String=info} options.logLevel (default: info)
     * @param {Function} options.flushOverride (optional)
     */
    constructor(writeKey: string, dataPlaneURL: string, options?: ConstructorOptions);
    _validate(message: Record<string, any>, type?: string): void;
    /**
     * Send an identify `message`.
     *
     * @param {Object} message
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.traits (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    identify(message: {
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        traits?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send a group `message`.
     *
     * @param {Object} message
     * @param {String} message.groupId
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.traits (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    group(message: {
        groupId: string;
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        traits?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send a track `message`.
     *
     * @param {Object} message
     * @param {String} message.event
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.properties (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    track(message: {
        event: string;
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        properties?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send a page `message`.
     *
     * @param {Object} message
     * @param {String} message.name
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.properties (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    page(message: {
        name: string;
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        properties?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send a screen `message`.
     *
     * @param {Object} message
     * @param {Function} callback (optional)
     * @return {Analytics}
     */
    screen(message: {
        [key: string]: any;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Send an alias `message`.
     *
     * @param {Object} message
     * @param {String} message.previousId
     * @param {String=} message.userId (optional)
     * @param {String=} message.anonymousId (optional)
     * @param {Object=} message.context (optional)
     * @param {Object=} message.properties (optional)
     * @param {Object=} message.integrations (optional)
     * @param {Date=} message.timestamp (optional)
     * @param {Function=} callback (optional)
     * @return {Analytics}
     */
    alias(message: {
        previousId: string;
        userId?: string;
        anonymousId?: string;
        context?: ApiObject;
        properties?: ApiObject;
        integrations?: IntegrationOptions;
        timestamp?: Date;
    }, callback?: ApiCallback): IAnalytics;
    /**
     * Add a `message` of type `type` to the queue and
     * check whether it should be flushed.
     *
     * @param {String} type
     * @param {Object} message
     * @param {Function} [callback] (optional)
     * @api private
     */
    enqueue(type: string, message: Record<string, any>, callback?: ApiCallback): any;
    /**
     * Flush the current queue
     *
     * @param {Function} [callback] (optional)
     * @return {any}
     */
    flush(callback?: ApiCallback): any;
    _isErrorRetryable(error: AxiosError): boolean;
}
//# sourceMappingURL=Analytics.d.ts.map

export { Analytics, type ApiCallback, type ApiObject, type ConstructorOptions, type FlushOverrideMessage, type IntegrationOptions };
