// Global TTS Helper to avoid event handler collisions and ensure robust voice picking
(function () {
    if (window.ttsHelper) return;

    const localeMap = { en: 'en-US', tr: 'tr-TR', de: 'de-DE', es: 'es-ES', fr: 'fr-FR', ru: 'ru-RU' };
    const nameHints = { en: ['english'], tr: ['turkish','türkçe'], de: ['german','deutsch'], es: ['spanish','español'], fr: ['french','français'], ru: ['russian','русский'] };

    let voicesReady = false;
    let cachedVoices = [];
    function refreshVoices() {
        try {
            cachedVoices = window.speechSynthesis ? (speechSynthesis.getVoices() || []) : [];
            voicesReady = cachedVoices && cachedVoices.length > 0;
        } catch (_) { voicesReady = false; cachedVoices = []; }
    }

    if ('speechSynthesis' in window) {
        refreshVoices();
        try {
            window.speechSynthesis.addEventListener('voiceschanged', function () {
                refreshVoices();
            });
        } catch (_) {
            // As a fallback, still attempt to set property without overriding if possible
            try {
                const prev = window.speechSynthesis.onvoiceschanged;
                window.speechSynthesis.onvoiceschanged = function () {
                    if (typeof prev === 'function') { try { prev(); } catch (_) {} }
                    refreshVoices();
                };
            } catch (_) {}
        }
    }

    function pickVoiceFor(code) {
        const lcCode = (code || 'en').toLowerCase();
        const desiredLocale = (localeMap[lcCode] || 'en-US').toLowerCase();
        if (!cachedVoices || cachedVoices.length === 0) return null;
        let v = cachedVoices.find(voice => (voice.lang || '').toLowerCase() === desiredLocale);
        if (v) return v;
        v = cachedVoices.find(voice => (voice.lang || '').toLowerCase().startsWith(lcCode));
        if (v) return v;
        const hints = nameHints[lcCode] || [];
        v = cachedVoices.find(voice => hints.some(h => (voice.name || '').toLowerCase().includes(h)));
        return v || null;
    }

    async function waitForVoices(timeoutMs) {
        if (voicesReady) return true;
        const start = Date.now();
        return new Promise(resolve => {
            const check = () => {
                refreshVoices();
                if (voicesReady || (Date.now() - start) > timeoutMs) return resolve(voicesReady);
                setTimeout(check, 50);
            };
            check();
        });
    }

    window.ttsHelper = {
        async speak(text, languageCode, options) {
            try {
                if (!('speechSynthesis' in window)) return;
                if (!text) return;
                try { window.speechSynthesis.cancel(); } catch (_) {}
                const code = (languageCode || 'en').toLowerCase();
                const desiredLocale = localeMap[code] || 'en-US';
                const utterance = new SpeechSynthesisUtterance(text);
                utterance.lang = desiredLocale;
                utterance.rate = (options && options.rate) || 0.9;
                utterance.pitch = (options && options.pitch) || 1.0;
                utterance.volume = (options && options.volume) || 1.0;
                if (options && typeof options.onstart === 'function') utterance.onstart = options.onstart;
                if (options && typeof options.onend === 'function') utterance.onend = options.onend;
                if (options && typeof options.onerror === 'function') utterance.onerror = options.onerror;

                await waitForVoices(1500);
                const voice = pickVoiceFor(code);
                if (voice) utterance.voice = voice;

                setTimeout(() => { try { speechSynthesis.speak(utterance); } catch (_) {} }, 30);
            } catch (_) {}
        }
    };
})();









