// Copyright 2026 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import { log, warnLog } from './logging.js';
const FILE = 'LocalSpeechRecognition';
/**
 * Encapsulates browser-local Web Speech API (SODA/cloud ASR) recognition.
 */
export class LocalSpeechRecognition {
    recognition = null;
    delegate;
    constructor(delegate) {
        this.delegate = delegate;
        this.init();
    }
    init() {
        // Since this WebUI strictly runs inside Chromium, we check known
        // constructors (#10).
        const SpeechRecognitionClass = window.SpeechRecognition ||
            window.webkitSpeechRecognition;
        if (!SpeechRecognitionClass) {
            log(FILE, 'Web Speech API constructor not found.');
            return;
        }
        this.recognition = new SpeechRecognitionClass();
        this.recognition.continuous = true;
        this.recognition.interimResults = true;
        this.recognition.lang = 'en-US';
        log(FILE, 'Speech recognition initialized successfully.');
        this.recognition.onstart = () => {
            log(FILE, 'Speech recognition service started (listening).');
        };
        this.recognition.onaudiostart = () => {
            log(FILE, 'Audio capture started (mic is recording).');
        };
        this.recognition.onsoundstart = () => {
            log(FILE, 'Sound detected (audio levels rising).');
        };
        this.recognition.onspeechstart = () => {
            log(FILE, 'Speech detected.');
        };
        this.recognition.onresult = (event) => {
            let interimTranscript = '';
            let finalTranscript = '';
            for (let i = event.resultIndex; i < event.results.length; ++i) {
                const result = event.results[i];
                if (result && result.isFinal) {
                    finalTranscript += result[0]?.transcript || '';
                }
                else if (result) {
                    interimTranscript += result[0]?.transcript || '';
                }
            }
            const activeTranscript = finalTranscript + interimTranscript;
            log(FILE, `Speech recognition result: "${activeTranscript}" (isFinal: ${event.results[event.resultIndex]?.isFinal})`);
            if (activeTranscript.trim()) {
                if (this.delegate.isAssistantSpeaking()) {
                    // Ignore local SODA results while the assistant is speaking to
                    // prevent acoustic feedback or echo transcripts (#12).
                    return;
                }
                this.delegate.onLocalTranscript(activeTranscript);
            }
        };
        this.recognition.onerror = (event) => {
            log(FILE, 'Speech recognition error:', event.error);
            if (event.error === 'not-allowed' ||
                event.error === 'service-not-allowed') {
                warnLog(FILE, 'Speech recognition permission denied or service unavailable. Disabling local STT and falling back to cloud ASR.');
                this.recognition = null;
            }
        };
        this.recognition.onend = () => {
            log(FILE, 'Speech recognition ended.');
            if (this.recognition && this.delegate.isSessionListening()) {
                try {
                    this.recognition.start();
                }
                catch (e) {
                    // Already started
                }
            }
        };
    }
    start() {
        if (this.recognition) {
            try {
                this.recognition.start();
            }
            catch (e) {
                // Already started
            }
        }
    }
    stop() {
        if (this.recognition) {
            try {
                this.recognition.stop();
            }
            catch (e) {
                // Already stopped
            }
        }
    }
}
