/**
 * TTSService
 *
 * Text-to-speech service with pluggable provider architecture.
 * Manages playback state, coordinates multiple TTS entry points,
 * and integrates with HighlightCoordinator for word highlighting.
 *
 * Features:
 * - Pluggable TTS providers (browser, AWS Polly, etc.)
 * - QTI 3.0 accessibility catalogs (pre-authored spoken content)
 * - Unified playback state management
 * - Prevents conflicts from simultaneous speech
 * - Word highlighting integration
 * - Playback controls: play, pause, resume, stop
 *
 * Part of PIE Assessment Toolkit.
 */
import type { ITTSProvider, TTSConfig, TTSProviderCapabilities } from "@pie-players/pie-tts";
import type { AccessibilityCatalogResolver, CatalogLookupContext } from "./AccessibilityCatalogResolver.js";
import type { HighlightCoordinatorApi } from "./interfaces.js";
import type { TTSHighlightTargetResolverProvider } from "./tts/highlight-target-resolver.js";
export type { ITTSProvider, ITTSProviderImplementation, TTSConfig, TTSFeature, TTSProviderCapabilities, } from "@pie-players/pie-tts";
/**
 * Playback state
 */
export declare enum PlaybackState {
    IDLE = "idle",
    LOADING = "loading",
    PLAYING = "playing",
    PAUSED = "paused",
    ERROR = "error"
}
type HighlightMode = "word" | "sentence";
interface SpeakOptions {
    catalogId?: string;
    catalogContext?: CatalogLookupContext;
    ignoreCatalogs?: boolean;
    language?: string;
    contentElement?: Element;
    wordBoundaryOffset?: number;
    highlightModeOverride?: HighlightMode;
}
/**
 * TTSService
 *
 * Instantiable service for text-to-speech functionality.
 * Each instance manages its own playback state.
 */
export declare class TTSService {
    private currentProvider;
    private provider;
    private highlightCoordinator;
    private highlightTargetResolverProvider;
    private catalogResolver;
    private state;
    private ttsConfig;
    private currentText;
    private currentContentElement;
    private normalizedToDOM;
    private listeners;
    private lastError;
    private speakRunId;
    private currentBoundaryOffset;
    private activeWordBoundaryOffset;
    private seekSegments;
    private sentenceHighlightSegments;
    private currentSeekSegmentIndex;
    private activeSentenceStartOffset;
    private activeHighlightMode;
    private lastRenderedRegionTarget;
    private telemetryReporter;
    private readonly generatedMathSpeechResolver;
    private static readonly debugEnabled;
    constructor();
    private debugLog;
    private emitTelemetry;
    /**
     * Initialize TTS service with a provider
     *
     * @param provider TTS provider instance
     * @param config Provider configuration
     */
    initialize(provider: ITTSProvider, config?: Partial<TTSConfig>): Promise<void>;
    /**
     * Update TTS settings dynamically without full reinitialization
     *
     * This allows changing rate, pitch, and voice on the fly.
     * Note: Some providers may require reinitialization for voice changes.
     *
     * @param settings Partial settings to update (rate, pitch, voice)
     */
    updateSettings(settings: Partial<TTSConfig>): Promise<void>;
    /**
     * Set highlight coordinator for word highlighting
     */
    setHighlightCoordinator(coordinator: HighlightCoordinatorApi): void;
    /**
     * Set a late-bound provider for optional host TTS highlight target remapping.
     */
    setHighlightTargetResolverProvider(provider: TTSHighlightTargetResolverProvider | null): () => void;
    /**
     * Set accessibility catalog resolver for spoken content
     *
     * When set, the speak() method will check for pre-authored spoken
     * content in catalogs before falling back to generated TTS.
     *
     * @param resolver AccessibilityCatalogResolver instance
     */
    setCatalogResolver(resolver: AccessibilityCatalogResolver): void;
    private getHighlightResolverRuntime;
    private getNodeElement;
    private isElementWithinScope;
    private isRangeWithinScope;
    private resolveWordHighlightRange;
    private resolveSentenceHighlightTargets;
    private createTextRange;
    private paintTTSWordRange;
    private paintTTSSentenceRanges;
    /**
     * Get provider capabilities
     */
    getCapabilities(): TTSProviderCapabilities | null;
    /**
     * Build a character-by-character map from normalized text positions to DOM positions
     * This handles the complexity of whitespace normalization
     */
    private getTextProcessingOptions;
    private getMathSpeechOptions;
    private buildPositionMap;
    private getStructuralPauseProfile;
    private resolvePauseMsFromUnits;
    private resolveHighlightMode;
    private hasExplicitBreakSemantics;
    private isElementHidden;
    private getBoundaryStrength;
    private getBoundaryAnchor;
    private createSpeechPlan;
    private collectSpeechPlanBoundaries;
    private createNodeStartOffsets;
    private createSpeechPlanSegments;
    private segmentSentences;
    private createSeekSegmentsFromText;
    private splitSegmentsAtBoundaries;
    private createSentenceHighlightSegments;
    private getCurrentSeekSegmentIndex;
    private speakWithPlan;
    private highlightSentenceSegment;
    private getSegmentIndexForOffset;
    private highlightSentenceForOffset;
    /**
     * Find text node and offsets for highlighting a word
     *
     * @param charIndex Character position in normalized/spoken text
     * @param length Length of the word
     * @returns Text node and local offsets, or null if not found
     */
    private findHighlightRange;
    /**
     * Speak text with optional catalog support
     *
     * @param text Text to speak (will be normalized: trimmed and whitespace collapsed)
     * @param options Optional catalog ID, language, and content element for highlighting
     */
    speak(text: string, options?: SpeakOptions): Promise<void>;
    private switchProviderToBrowser;
    private isBrowserSpeechFallbackAvailable;
    private applyLanguageSettings;
    private resolveSpeechContent;
    private resolveCatalogComposedSpeechContent;
    private collectCatalogSpeechChunks;
    /**
     * Decide the playback format for the generated (no authored catalog) math
     * path. SSML is only emitted to providers that report `supportsSSML`: the
     * browser Web Speech API speaks tags literally (capability `false`), and the
     * server bridge reports `true` only for SSML-reliable backends (Polly,
     * Google) — the `custom`/SchoolCity transport stays plain.
     *
     * A speak-time plain fallback (`SpeechCompositionChunk.plainFallback`) is the
     * defensive net if a capable provider still rejects a given SSML payload.
     */
    private resolveGeneratedPlaybackFormat;
    private resolveGeneratedSpeechContent;
    private logResolvedSpeechContent;
    private initializeSpeakTracking;
    private prepareHighlightsForSpeak;
    private configureWordBoundaryHighlighting;
    private clearWordBoundaryHighlighting;
    private highlightCatalogRegion;
    private highlightCatalogActiveRange;
    private highlightRenderableRegionTarget;
    private highlightRenderableActiveTarget;
    private renderHighlightDecision;
    private speakCatalogChunk;
    private speakCatalogChunkOnce;
    private executeSpeakPlayback;
    private clearHighlightsAndTracking;
    /**
     * Speak a text range with accurate word highlighting
     *
     * This calculates the offset of the range within its parent element
     * to ensure word highlighting aligns correctly with the selected text.
     *
     * @param range DOM Range to speak
     */
    speakRange(range: Range, options?: {
        contentRoot?: Element | null;
    }): Promise<void>;
    /**
     * Pause playback
     */
    pause(): void;
    /**
     * Resume playback
     */
    resume(): void;
    private normalizePlaybackRate;
    private restartFromSeekIndex;
    setPlaybackRate(rate: number): Promise<void>;
    private seekBy;
    seekForward(units?: number): Promise<void>;
    seekBackward(units?: number): Promise<void>;
    /**
     * Stop playback
     */
    stop(): void;
    /**
     * Request UI-level TTS controls to hand off/deactivate.
     *
     * This is intentionally separate from playback controls so hosts can orchestrate
     * control handoff explicitly (for example: stop playback, then dismiss controls).
     */
    requestControlHandoff(): void;
    /**
     * Check if currently playing
     */
    isPlaying(): boolean;
    /**
     * Check if paused
     */
    isPaused(): boolean;
    /**
     * Get current state
     */
    getState(): PlaybackState;
    /**
     * Get current text being spoken
     */
    getCurrentText(): string | null;
    /**
     * Get the last error message
     * Returns null if no error has occurred
     */
    getLastError(): string | null;
    /**
     * Subscribe to state changes
     *
     * @param id Unique listener ID
     * @param callback Function to call on state change
     */
    onStateChange(id: string, callback: (state: PlaybackState) => void): void;
    /**
     * Unsubscribe from state changes
     */
    offStateChange(id: string, callback: (state: PlaybackState) => void): void;
    /**
     * Set state and notify listeners
     */
    private setState;
}
