/**
 * TTSHelper - Text-to-Speech utility for consistent TTS behavior across the app
 * Fixes the common issue where voices aren't loaded on first call
 */

class TTSHelper {
    /**
     * Get available speech synthesis voices, waiting for them to load if necessary
     * @returns {Promise<SpeechSynthesisVoice[]>} Array of available voices
     */
    static getVoices() {
        return new Promise((resolve) => {
            let voices = window.speechSynthesis.getVoices();

            // If voices are already loaded, return them immediately
            if (voices.length > 0) {
                resolve(voices);
                return;
            }

            // Otherwise, wait for voiceschanged event
            const voicesChangedHandler = () => {
                voices = window.speechSynthesis.getVoices();
                if (voices.length > 0) {
                    window.speechSynthesis.removeEventListener('voiceschanged', voicesChangedHandler);
                    resolve(voices);
                }
            };

            window.speechSynthesis.addEventListener('voiceschanged', voicesChangedHandler);

            // Fallback timeout in case voices never load
            setTimeout(() => {
                window.speechSynthesis.removeEventListener('voiceschanged', voicesChangedHandler);
                resolve(window.speechSynthesis.getVoices());
            }, 1000);
        });
    }

    /**
     * Select the best voice for a given language
     * @param {string} language - Language code (e.g., "zh-CN", "en-US")
     * @param {SpeechSynthesisVoice[]} voices - Available voices
     * @returns {SpeechSynthesisVoice|null} - Best matching voice or null
     */
    static selectVoice(language, voices) {
        if (!voices || voices.length === 0) return null;

        const langPrefix = language.split('-')[0]; // e.g., "zh" from "zh-CN"

        // Try to find:
        // 1. Default voice for the exact language
        // 2. Any voice for the exact language
        // 3. Default voice for the language prefix
        // 4. Any voice for the language prefix
        const matchingVoice = voices.find(voice =>
            voice.lang === language && voice.default
        ) || voices.find(voice =>
            voice.lang === language
        ) || voices.find(voice =>
            voice.lang.startsWith(langPrefix) && voice.default
        ) || voices.find(voice =>
            voice.lang.startsWith(langPrefix)
        );

        return matchingVoice || null;
    }

    /**
     * Speak text using TTS with proper voice selection and error handling
     * @param {string} text - Text to speak
     * @param {Object} options - TTS options
     * @param {string} options.lang - Language code (e.g., "zh-CN", "en-US")
     * @param {number} options.rate - Speech rate (default 0.8)
     * @param {number} options.pitch - Speech pitch (default 1.0)
     * @param {number} options.volume - Speech volume (default 1.0)
     * @param {Function} options.onStart - Callback when speech starts
     * @param {Function} options.onEnd - Callback when speech ends
     * @param {Function} options.onError - Callback on error
     * @returns {Promise<void>}
     */
    static async speak(text, options = {}) {
        if (!('speechSynthesis' in window)) {
            console.warn('🔊 Speech Synthesis not supported in this browser');
            if (options.onError) options.onError(new Error('Speech Synthesis not supported'));
            return;
        }

        try {
            // Cancel any ongoing speech
            window.speechSynthesis.cancel();

            const utterance = new SpeechSynthesisUtterance(text);
            utterance.lang = options.lang || 'en-US';
            utterance.rate = options.rate || 0.8;
            utterance.pitch = options.pitch || 1.0;
            utterance.volume = options.volume || 1.0;

            // Wait for voices to be loaded before selecting one
            const voices = await TTSHelper.getVoices();
            const selectedVoice = TTSHelper.selectVoice(utterance.lang, voices);

            if (selectedVoice) {
                utterance.voice = selectedVoice;
                console.log(`🔊 Using voice: ${selectedVoice.name} (${selectedVoice.lang})`);
            } else {
                console.warn(`🔊 No voice found for language: ${utterance.lang}, using default`);
            }

            // Add event handlers
            utterance.onstart = () => {
                console.log('🔊 TTS started for:', text);
                if (options.onStart) options.onStart();
            };

            utterance.onend = () => {
                console.log('🔊 TTS finished for:', text);
                if (options.onEnd) options.onEnd();
            };

            utterance.onerror = (event) => {
                console.warn('🔊 TTS error:', event.error);
                if (options.onError) options.onError(event);
            };

            // Speak the text
            window.speechSynthesis.speak(utterance);

        } catch (error) {
            console.warn('🔊 TTS failed:', error);
            if (options.onError) options.onError(error);
        }
    }
}

export default TTSHelper;
