import type { WebRTCConnectionState, WebRTCDisconnectReason, DataChannelConfig, DataChannelState, ConnectionQualitySummary, RecordingOptions, RecordingHandle, TrackSource as CoreTrackSource } from '@agentuity/core';
/**
 * Track source interface extended for browser environment.
 */
export interface TrackSource extends Omit<CoreTrackSource, 'getStream'> {
    getStream(): Promise<MediaStream>;
}
/**
 * User media (camera/microphone) track source.
 */
export declare class UserMediaSource implements TrackSource {
    private constraints;
    readonly type: "user-media";
    private stream;
    constructor(constraints?: MediaStreamConstraints);
    getStream(): Promise<MediaStream>;
    stop(): void;
}
/**
 * Display media (screen share) track source.
 */
export declare class DisplayMediaSource implements TrackSource {
    private constraints;
    readonly type: "display-media";
    private stream;
    constructor(constraints?: DisplayMediaStreamOptions);
    getStream(): Promise<MediaStream>;
    stop(): void;
}
/**
 * Custom stream track source - wraps a user-provided MediaStream.
 */
export declare class CustomStreamSource implements TrackSource {
    private stream;
    readonly type: "custom";
    constructor(stream: MediaStream);
    getStream(): Promise<MediaStream>;
    stop(): void;
}
/**
 * Callbacks for WebRTC client state changes and events.
 * All callbacks are optional - only subscribe to events you care about.
 */
export interface WebRTCClientCallbacks {
    /**
     * Called on every state transition.
     */
    onStateChange?: (from: WebRTCConnectionState, to: WebRTCConnectionState, reason?: string) => void;
    /**
     * Called when connected to at least one peer.
     */
    onConnect?: () => void;
    /**
     * Called when disconnected from all peers.
     */
    onDisconnect?: (reason: WebRTCDisconnectReason) => void;
    /**
     * Called when local media stream is acquired.
     */
    onLocalStream?: (stream: MediaStream) => void;
    /**
     * Called when a remote media stream is received.
     */
    onRemoteStream?: (peerId: string, stream: MediaStream) => void;
    /**
     * Called when a new track is added to a stream.
     */
    onTrackAdded?: (peerId: string, track: MediaStreamTrack, stream: MediaStream) => void;
    /**
     * Called when a track is removed from a stream.
     */
    onTrackRemoved?: (peerId: string, track: MediaStreamTrack) => void;
    /**
     * Called when a peer joins the room.
     */
    onPeerJoined?: (peerId: string) => void;
    /**
     * Called when a peer leaves the room.
     */
    onPeerLeft?: (peerId: string) => void;
    /**
     * Called when negotiation starts with a peer.
     */
    onNegotiationStart?: (peerId: string) => void;
    /**
     * Called when negotiation completes with a peer.
     */
    onNegotiationComplete?: (peerId: string) => void;
    /**
     * Called for each ICE candidate generated.
     */
    onIceCandidate?: (peerId: string, candidate: RTCIceCandidateInit) => void;
    /**
     * Called when ICE connection state changes for a peer.
     */
    onIceStateChange?: (peerId: string, state: string) => void;
    /**
     * Called when an error occurs.
     */
    onError?: (error: Error, state: WebRTCConnectionState) => void;
    /**
     * Called when a data channel is opened.
     */
    onDataChannelOpen?: (peerId: string, label: string) => void;
    /**
     * Called when a data channel is closed.
     */
    onDataChannelClose?: (peerId: string, label: string) => void;
    /**
     * Called when a message is received on a data channel.
     *
     * **Note:** String messages are automatically parsed as JSON if valid.
     * - If the message is valid JSON, `data` will be the parsed object/array/value
     * - If the message is not valid JSON, `data` will be the raw string
     * - Binary messages (ArrayBuffer) are passed through unchanged
     *
     * To distinguish between parsed JSON and raw strings, check the type:
     * ```ts
     * onDataChannelMessage: (peerId, label, data) => {
     *   if (typeof data === 'string') {
     *     // Raw string (failed JSON parse)
     *   } else if (data instanceof ArrayBuffer) {
     *     // Binary data
     *   } else {
     *     // Parsed JSON object/array/primitive
     *   }
     * }
     * ```
     */
    onDataChannelMessage?: (peerId: string, label: string, data: string | ArrayBuffer | unknown) => void;
    /**
     * Called when a data channel error occurs.
     */
    onDataChannelError?: (peerId: string, label: string, error: Error) => void;
    /**
     * Called when screen sharing starts.
     */
    onScreenShareStart?: () => void;
    /**
     * Called when screen sharing stops.
     */
    onScreenShareStop?: () => void;
    /**
     * Called when a reconnect attempt is scheduled.
     */
    onReconnecting?: (attempt: number) => void;
    /**
     * Called after a successful reconnection.
     */
    onReconnected?: () => void;
    /**
     * Called when reconnect attempts are exhausted.
     */
    onReconnectFailed?: () => void;
}
/**
 * Options for WebRTCManager
 */
export interface WebRTCManagerOptions {
    /** WebSocket signaling URL */
    signalUrl: string;
    /** Room ID to join */
    roomId: string;
    /** Whether this peer is "polite" in perfect negotiation (default: auto-determined) */
    polite?: boolean;
    /** ICE servers configuration */
    iceServers?: RTCIceServer[];
    /**
     * Media source configuration.
     * - `false`: Data-only mode (no media)
     * - `MediaStreamConstraints`: Use getUserMedia with these constraints
     * - `TrackSource`: Use a custom track source
     * Default: { video: true, audio: true }
     */
    media?: MediaStreamConstraints | TrackSource | false;
    /**
     * Data channels to create when connection is established.
     * Only the offerer (late joiner) creates channels; the answerer receives them.
     */
    dataChannels?: DataChannelConfig[];
    /**
     * Callbacks for state changes and events.
     */
    callbacks?: WebRTCClientCallbacks;
    /**
     * Whether to auto-reconnect on WebSocket/ICE failures (default: true)
     */
    autoReconnect?: boolean;
    /**
     * Maximum reconnection attempts before giving up (default: 5)
     */
    maxReconnectAttempts?: number;
    /**
     * Connection timeout in ms for connecting/negotiating (default: 30000)
     */
    connectionTimeout?: number;
    /**
     * ICE gathering timeout in ms (default: 10000)
     */
    iceGatheringTimeout?: number;
}
/**
 * WebRTC manager state
 */
export interface WebRTCManagerState {
    state: WebRTCConnectionState;
    peerId: string | null;
    remotePeerIds: string[];
    isAudioMuted: boolean;
    isVideoMuted: boolean;
    isScreenSharing: boolean;
}
/**
 * Framework-agnostic WebRTC connection manager with multi-peer mesh networking,
 * perfect negotiation, media/data channel handling, and screen sharing.
 *
 * Uses an explicit state machine for connection lifecycle:
 * - idle: No resources allocated, ready to connect
 * - connecting: Acquiring media + opening WebSocket
 * - signaling: In room, waiting for peer(s)
 * - negotiating: SDP/ICE exchange in progress with at least one peer
 * - connected: At least one peer is connected
 *
 * @example
 * ```ts
 * const manager = new WebRTCManager({
 *   signalUrl: 'wss://example.com/call/signal',
 *   roomId: 'my-room',
 *   callbacks: {
 *     onStateChange: (from, to, reason) => console.log(`${from} → ${to}`, reason),
 *     onConnect: () => console.log('Connected!'),
 *     onRemoteStream: (peerId, stream) => { remoteVideos[peerId].srcObject = stream; },
 *   },
 * });
 *
 * await manager.connect();
 * ```
 */
export declare class WebRTCManager {
    private ws;
    private localStream;
    private trackSource;
    private previousVideoTrack;
    private peerId;
    private peers;
    private isAudioMuted;
    private isVideoMuted;
    private isScreenSharing;
    private _state;
    private isConnecting;
    private basePolite;
    private options;
    private callbacks;
    private reconnectManager;
    private isReconnecting;
    private intentionalClose;
    private connectionTimeoutId;
    private recordings;
    constructor(options: WebRTCManagerOptions);
    /**
     * Current connection state
     */
    get state(): WebRTCConnectionState;
    /**
     * Get current manager state
     */
    getState(): WebRTCManagerState;
    /**
     * Get local media stream
     */
    getLocalStream(): MediaStream | null;
    /**
     * Get remote media streams keyed by peer ID
     */
    getRemoteStreams(): Map<string, MediaStream>;
    /**
     * Get a specific peer's remote stream
     */
    getRemoteStream(peerId: string): MediaStream | null;
    /**
     * Whether this manager is in data-only mode (no media streams).
     */
    get isDataOnly(): boolean;
    /**
     * Get connected peer count
     */
    get peerCount(): number;
    private setState;
    private mapToDisconnectReason;
    private handleStateTimeouts;
    private startConnectionTimeout;
    private clearConnectionTimeout;
    private handleTimeout;
    private shouldAutoReconnect;
    private updateConnectionState;
    private send;
    /**
     * Connect to the signaling server and start the call
     */
    connect(): Promise<void>;
    private ensureLocalStream;
    private openWebSocket;
    private handleConnectionLoss;
    private scheduleReconnect;
    private reconnect;
    private handleSignalingMessage;
    private createPeerSession;
    private createOffer;
    private handleRemoteSDP;
    private hasOfferCollision;
    private isOffererFor;
    private handleRemoteICE;
    private closePeerSession;
    private cleanupPeerSessions;
    private scheduleIceGatheringTimeout;
    private setupDataChannel;
    /**
     * Create a new data channel to all connected peers.
     */
    createDataChannel(config: DataChannelConfig): Map<string, RTCDataChannel>;
    /**
     * Get a data channel by label from a specific peer.
     */
    getDataChannel(peerId: string, label: string): RTCDataChannel | undefined;
    /**
     * Get all open data channel labels.
     */
    getDataChannelLabels(): string[];
    /**
     * Get the state of a data channel for a specific peer.
     */
    getDataChannelState(peerId: string, label: string): DataChannelState | null;
    /**
     * Send a string message to all peers on a data channel.
     */
    sendString(label: string, data: string): boolean;
    /**
     * Send a string message to a specific peer.
     */
    sendStringTo(peerId: string, label: string, data: string): boolean;
    /**
     * Send binary data to all peers on a data channel.
     */
    sendBinary(label: string, data: ArrayBuffer | Uint8Array): boolean;
    /**
     * Send binary data to a specific peer.
     */
    sendBinaryTo(peerId: string, label: string, data: ArrayBuffer | Uint8Array): boolean;
    /**
     * Send JSON data to all peers on a data channel.
     */
    sendJSON(label: string, data: unknown): boolean;
    /**
     * Send JSON data to a specific peer.
     */
    sendJSONTo(peerId: string, label: string, data: unknown): boolean;
    /**
     * Close a specific data channel on all peers.
     */
    closeDataChannel(label: string): boolean;
    /**
     * Mute or unmute audio
     */
    muteAudio(muted: boolean): void;
    /**
     * Mute or unmute video
     */
    muteVideo(muted: boolean): void;
    /**
     * Start screen sharing, replacing the current video track.
     * @param options - Display media constraints
     */
    startScreenShare(options?: DisplayMediaStreamOptions): Promise<void>;
    /**
     * Stop screen sharing and restore the previous video track.
     */
    stopScreenShare(): Promise<void>;
    /**
     * Get raw stats for a peer connection.
     */
    getRawStats(peerId: string): Promise<RTCStatsReport | null>;
    /**
     * Get raw stats for all peer connections.
     */
    getAllRawStats(): Promise<Map<string, RTCStatsReport>>;
    /**
     * Get a normalized quality summary for a peer connection.
     */
    getQualitySummary(peerId: string): Promise<ConnectionQualitySummary | null>;
    /**
     * Get quality summaries for all peer connections.
     */
    getAllQualitySummaries(): Promise<Map<string, ConnectionQualitySummary>>;
    private parseStatsToSummary;
    private findMatchingReport;
    private getStatReport;
    /**
     * Start recording a stream.
     * @param streamId - 'local' for local stream, or a peer ID for remote stream
     * @param options - Recording options
     */
    startRecording(streamId: string, options?: RecordingOptions): RecordingHandle | null;
    /**
     * Check if a stream is being recorded.
     */
    isRecording(streamId: string): boolean;
    /**
     * Stop all recordings and return the blobs.
     */
    stopAllRecordings(): Promise<Map<string, Blob>>;
    private selectMimeType;
    /**
     * End the call and disconnect from all peers
     */
    hangup(): void;
    /**
     * Clean up all resources
     */
    dispose(): void;
}
//# sourceMappingURL=webrtc-manager.d.ts.map