/**
 * CallHandle — the concrete `OperatorCall` returned to the application.
 *
 * It is a thin, stateful facade: lifecycle transitions and the actual
 * accept/reject/dial/teardown side-effects live in `AudinOperator`, which
 * injects them here as callbacks. This keeps the handle dumb (no socket / no
 * audio knowledge) while giving the app a stable object whose getters reflect
 * the live state the operator mutates.
 */
import type { OperatorCall, CallDirection, CallState, CallEndReason } from "./types.js";
/** Side-effect callbacks injected by {@link AudinOperator}. */
export interface CallHandleDeps {
    onAccept: (call: CallHandle) => void;
    onReject: (call: CallHandle) => void;
    onMute: (call: CallHandle, on: boolean) => void;
    onDtmf: (call: CallHandle, digit: string) => void;
    onHangup: (call: CallHandle) => void;
}
export interface CallHandleInit {
    callSid: string;
    direction: CallDirection;
    from?: string;
    to?: string;
    /** Initial state — `ringing` for inbound offers, `connecting` for outbound. */
    state: CallState;
}
export declare class CallHandle implements OperatorCall {
    readonly callSid: string;
    readonly direction: CallDirection;
    readonly from?: string;
    readonly to?: string;
    private _state;
    private _endReason?;
    private _muted;
    private readonly deps;
    constructor(init: CallHandleInit, deps: CallHandleDeps);
    get state(): CallState;
    get endReason(): CallEndReason | undefined;
    get muted(): boolean;
    accept(): void;
    reject(): void;
    mute(on: boolean): void;
    sendDtmf(digit: string): void;
    hangup(): void;
    /** Move to `connecting` (audio bridge opening). */
    setConnecting(): void;
    /** Move to `active` (audio flowing). */
    setActive(): void;
    /** Terminal transition. Idempotent — keeps the first end reason. */
    markEnded(reason: CallEndReason): void;
}
