import { AxiosRequestConfig, AxiosResponse } from 'axios';
import { ConnectedEvent, UserRequest, VideoEvent } from '../../gen/coordinator';
import { AllSfuEvents } from '../../rtc';
import type { ConfigureLoggersOptions, LogLevel } from '@stream-io/logger';
import type { DevicePersistenceOptions } from '../../devices/devicePersistence';
import { InputDeviceStatus } from '../../devices';
export type UR = Record<string, unknown>;
export type User = (Omit<UserRequest, 'role'> & {
    type?: 'authenticated';
}) | (Omit<UserRequest, 'role'> & {
    type: 'guest';
}) | (Omit<UserRequest, 'id' | 'role'> & {
    id?: '!anon';
    type: 'anonymous';
});
export type UserWithId = (UserRequest & {
    type?: 'authenticated';
}) | (UserRequest & {
    type: 'guest';
}) | (UserRequest & {
    id: '!anon';
    type: 'anonymous';
});
export type { OwnUserResponse } from '../../gen/coordinator';
export type ConnectAPIResponse = Promise<void | ConnectedEvent>;
type ErrorResponseDetails = {
    code: number;
    messages: string[];
};
export type APIErrorResponse = {
    code: number;
    duration: string;
    message: string;
    more_info: string;
    StatusCode: number;
    details?: ErrorResponseDetails;
    unrecoverable?: boolean;
};
/**
 * A standard `Error` augmented with the metadata that the coordinator
 * WebSocket connection layer attaches to rejection causes.
 * `isWSFailure: true` marks transient/retriable failures; absent or `false`
 * indicates a permanent failure that should not be retried.
 */
export type WSConnectionError = Error & {
    code?: string | number;
    isWSFailure?: boolean;
    StatusCode?: string | number;
    reason?: string;
    wasClean?: boolean;
    target?: EventTarget | null;
};
export declare class ErrorFromResponse<T> extends Error {
    code: number | null;
    status: number;
    response: AxiosResponse<T>;
    name: string;
    unrecoverable: boolean | null;
    constructor({ message, code, status, response, unrecoverable, }: Pick<ErrorFromResponse<T>, 'message' | 'code' | 'status' | 'response' | 'unrecoverable'>);
    toJSON(): {
        message: string;
        stack: string | undefined;
        name: string;
    };
}
export type ConnectionChangedEvent = {
    type: 'connection.changed';
    online: boolean;
};
export type NetworkChangedEvent = {
    type: 'network.changed';
    online: boolean;
};
export type TransportChangedEvent = {
    type: 'transport.changed';
    mode: 'longpoll';
};
export type ConnectionRecoveredEvent = {
    type: 'connection.recovered';
};
export type MicCaptureReportEvent = {
    type: 'mic.capture_report';
    call_cid: string;
    /**
     * Whether the mic is capturing audio.
     */
    capturesAudio: boolean;
    /**
     * The device ID of the mic.
     */
    deviceId?: string;
    /**
     * The human-readable label of the mic.
     */
    label?: string;
};
export type DeviceDisconnectedEvent = {
    type: 'device.disconnected';
    call_cid: string;
    /**
     * The device status at the time it was disconnected.
     */
    status: InputDeviceStatus;
    /**
     * The disconnected device ID.
     */
    deviceId: string;
    /**
     * The human-readable label of the disconnected device.
     */
    label?: string;
    /**
     * The disconnected device kind.
     */
    kind: MediaDeviceKind;
};
export type StreamVideoEvent = (VideoEvent | NetworkChangedEvent | ConnectionChangedEvent | TransportChangedEvent | ConnectionRecoveredEvent | MicCaptureReportEvent | DeviceDisconnectedEvent) & {
    received_at?: string | Date;
};
export type StreamCallEvent = Extract<StreamVideoEvent, {
    call_cid: string;
}>;
export type EventTypes = 'all' | StreamVideoEvent['type'];
export type AllClientEventTypes = 'all' | StreamVideoEvent['type'];
export type AllClientEvents = {
    [K in AllClientEventTypes]: Extract<StreamVideoEvent, {
        type: K;
    }>;
};
export type ClientEventListener<E extends keyof AllClientEvents> = (event: AllClientEvents[E]) => void;
export type AllClientCallEvents = {
    [K in EventTypes]: Extract<StreamVideoEvent, {
        type: K;
    }>;
};
export type AllCallEvents = AllClientCallEvents & AllSfuEvents;
export type CallEventListener<E extends keyof AllCallEvents> = (event: AllCallEvents[E]) => void;
export type Logger = (logLevel: LogLevel, message: string, ...args: unknown[]) => void;
export type StreamClientOptions = Partial<AxiosRequestConfig> & {
    /**
     * Used to disable warnings that are triggered by using connectUser or connectAnonymousUser server-side.
     */
    allowServerSideConnect?: boolean;
    axiosRequestConfig?: AxiosRequestConfig;
    /**
     * Base url to use for API
     * such as https://chat-proxy-dublin.stream-io-api.com
     */
    baseURL?: string;
    browser?: boolean;
    /**
     * Enables the client-side event reporter (call lifecycle telemetry).
     * Set to `false` for non-interactive sessions such as egress/recording
     * where the telemetry adds no value. Defaults to `true`.
     */
    clientEventsReportingEnabled?: boolean;
    /**
     *  @deprecated Use `logOptions` instead.
     *  Custom logger instance used to handle log messages.
     *  Will be removed in a future release.
     */
    logger?: Logger;
    /**
     *  @deprecated Use `logOptions` instead.
     *  Sets the minimum log level for all logs.
     *  Will be removed in a future release.
     */
    logLevel?: LogLevel;
    /**
     * Configuration options where keys are logger scopes.
     * The `default` scope is reserved is used to set defaults for all loggers.
     *
     */
    logOptions?: ConfigureLoggersOptions;
    /**
     * The URL to use for the location hint.
     */
    locationHintUrl?: string;
    /**
     * The default timeout for requesting a location hint.
     */
    locationHintTimeout?: number;
    /**
     * The maximum number of attempts to request a location hint.
     */
    locationHintMaxAttempts?: number;
    /**
     * When true, user will be persisted on client. Otherwise if `connectUser` call fails, then you need to
     * call `connectUser` again to retry.
     * This is mainly useful for chat application working in offline mode, where you will need client.user to
     * persist even if connectUser call fails.
     */
    persistUserOnConnectionFailure?: boolean;
    /**
     * The secret key for the API key. This is only needed for server side authentication.
     */
    secret?: string;
    /**
     * The WebSocket implementation to use. This is mainly useful for testing.
     * In Node.js environment, you can use the `ws` package.
     */
    WebSocketImpl?: typeof WebSocket;
    /**
     * Create Web Worker to initiate timer events like health checks. Can possibly prevent
     * timer throttling issues in inactive browser tabs.
     */
    enableTimerWorker?: boolean;
    /**
     * The client app identifier.
     */
    clientAppIdentifier?: ClientAppIdentifier;
    /**
     * The default timeout for WebSocket connections.
     */
    defaultWsTimeout?: number;
    /**
     * The maximum number of retries to connect a user.
     */
    maxConnectUserRetries?: number;
    /**
     * A callback to be called one the maxUserConnectRetries is exhausted.
     * @param lastError the last error.
     * @param allErrors all errors.
     */
    onConnectUserError?: (lastError: Error, allErrors: Error[]) => void;
    /**
     * When set to true, the incoming calls are rejected when the user is busy in an another call.
     */
    rejectCallWhenBusy?: boolean;
    /**
     * Device persistence preference options (web only).
     */
    devicePersistence?: DevicePersistenceOptions;
};
export type ClientAppIdentifier = {
    sdkName?: 'react' | 'react-native' | 'plain-javascript' | (string & {});
    sdkVersion?: string;
    app?: string;
    app_version?: string;
    os?: string;
    device_model?: string;
};
export type TokenProvider = () => Promise<string>;
export type TokenOrProvider = null | string | TokenProvider | undefined;
export type BuiltInRejectReason = 'busy' | 'decline' | 'cancel' | 'timeout';
export type RejectReason = BuiltInRejectReason | (string & {});
