/**
 * Options UI Module
 * Provides the options UI for the game
 */
import { BaseModule } from './base-module.js';
import { createUIElement, populateDropdown, registerHandler, createPreferenceBinding } from './ui-helper.js';

class OptionsUIModule extends BaseModule {
    /**
     * Create a new options UI module
     */
    constructor() {
        super('options-ui', 'Options UI');
        
        // Set up dependencies
        this.dependencies = [
            'persistence-manager',
            'localization',
            'tts-factory',
            'audio-manager',
            'game-config'
        ];
        
        // Modal element
        this.modal = null;
        
        // UI elements
        this.elements = {};
        
        // Settings that require reload
        this.reloadRequired = false;
        
        // Bind methods
        this.bindMethods([
            'show',
            'hide',
            'createModal',
            'populateTtsSystems',
            'populateVoices',
            'populateLanguages',
            'loadPreferences',
            'createVolumeControl',
            'updateVolumeToggleButtons',
            'updateVolumeToggleButton',
            'showReloadNotice',
            'toggle',
            'setupEventListeners',
            'setupApiUrlFields',
            'setupInitialState',
            'dispatchApiChangeEvent',
            'getPreference',
            'updatePreference',
            'updateUIText',
            'renderProviderStatuses'
        ]);
    }

    t(key, params = {}) {
        const localization = this.getModule('localization');
        return localization?.translate?.(key, params) || key;
    }

    updateUIText() {
        if (!this.modal) return;
        const wasOpen = this.modal.style.display === 'flex';
        this.modal.remove();
        this.modal = null;
        this.elements = {};
        this.createModal();
        this.setupPreferenceBindings();
        this.populateTtsSystems();
        this.populateLanguages();
        this.populateVoices();
        this.renderProviderStatuses();
        if (wasOpen) this.show();
    }
    
    /**
     * Dispatches an API change event
     * @param {string} eventType - Event type (e.g. 'api:key:change')
     * @param {string} provider - Provider name (e.g. 'elevenlabs')
     * @param {string} valueType - Value type (e.g. 'key', 'url')
     * @param {string} value - Value to dispatch
     */
    dispatchApiChangeEvent(eventType, provider, valueType, value) {
        const eventName = `tts:${eventType}`;
        console.log(`Options UI: Dispatching event ${eventName} for provider ${provider}`);
        document.dispatchEvent(new CustomEvent(eventName, {
            detail: { provider, [valueType]: value }
        }));
    }
    
    /**
     * Gets a preference from the persistence manager
     * @param {string} category - Preference category
     * @param {string} key - Preference key
     * @param {*} defaultValue - Default value if preference doesn't exist
     * @returns {*} - Preference value
     */
    getPreference(category, key, defaultValue) {
        const persistenceManager = this.getModule('persistence-manager');
        return persistenceManager.getPreference(category, key, defaultValue);
    }
    
    /**
     * Updates a preference in the persistence manager
     * @param {string} category - Preference category
     * @param {string} key - Preference key
     * @param {*} value - Value to set
     */
    updatePreference(category, key, value) {
        const persistenceManager = this.getModule('persistence-manager');
        persistenceManager.updatePreference(category, key, value);
    }
    
    /**
     * Initialize the Options UI module
     * @returns {Promise<boolean>} - Promise resolves with initialization success
     */
    async initialize() {
        console.log('Options UI: Initializing');
        
        // Create DOM elements
        this.createModal();
        
        // Set up event listeners
        this.setupEventListeners();
        
        // Set up API URL fields
        this.setupApiUrlFields();
        
        // Set up initial state
        await this.setupInitialState();
        
        // Set up automatic bindings using the persistence manager
        this.setupPreferenceBindings();
        
        this.reportProgress(100, 'Options UI initialized');
        return true;
    }
    
    /**
     * Create the options modal
     */
    createModal() {
        console.log('Options UI: Creating options modal');
        
        // Create modal container
        this.modal = document.createElement('div');
        this.modal.id = 'options-modal';
        this.modal.className = 'modal';
        this.modal.style.display = 'none';
        
        // Create modal content
        const modalContent = document.createElement('div');
        modalContent.className = 'modal-content';
        
        // Create header
        const header = document.createElement('div');
        header.className = 'modal-header';
        
        const title = document.createElement('h2');
        title.textContent = this.t('options.title');
        header.appendChild(title);
        
        const closeButton = document.createElement('span');
        closeButton.className = 'close';
        closeButton.innerHTML = '&times;';
        closeButton.onclick = () => this.hide();
        header.appendChild(closeButton);
        
        modalContent.appendChild(header);
        
        // Create body
        const body = document.createElement('div');
        body.className = 'modal-body';
        const localization = this.getModule('localization');
        
        // Create sections
        // App Settings Section (Language and Speed)
        const appSettingsSection = document.createElement('div');
        appSettingsSection.className = 'options-section';
        
        const appSettingsTitle = document.createElement('h3');
        appSettingsTitle.textContent = this.t('options.applicationSettings');
        appSettingsSection.appendChild(appSettingsTitle);
        
        // Language
        const languageContainer = document.createElement('div');
        languageContainer.className = 'option-item';
        
        const languageLabel = document.createElement('label');
        languageLabel.textContent = this.t('options.language') + ':';
        languageContainer.appendChild(languageLabel);
        
        this.elements.language = createUIElement('select', {
            'data-pref-bind': 'app.locale'
        }, null, languageContainer);
        
        appSettingsSection.appendChild(languageContainer);

        const gameLanguageContainer = document.createElement('div');
        gameLanguageContainer.className = 'option-item';

        const gameLanguageLabel = document.createElement('label');
        gameLanguageLabel.textContent = this.t('options.gameLanguage') + ':';
        gameLanguageContainer.appendChild(gameLanguageLabel);

        const gameLanguageValue = document.createElement('span');
        gameLanguageValue.className = 'game-language-value';
        const gameConfig = this.getModule('game-config');
        const gameLocale = gameConfig?.getLocale?.() || 'en_US';
        gameLanguageValue.textContent = localization?.getLanguageName?.(gameLocale) || gameLocale;
        this.elements.gameLanguage = gameLanguageValue;
        gameLanguageContainer.appendChild(gameLanguageValue);

        appSettingsSection.appendChild(gameLanguageContainer);
        
        // Speed
        const speedContainer = document.createElement('div');
        speedContainer.className = 'option-item';
        
        const speedLabel = document.createElement('label');
        speedLabel.textContent = this.t('options.speed') + ':';
        speedContainer.appendChild(speedLabel);
        
        const speedValue = document.createElement('span');
        speedValue.className = 'slider-value';
        speedValue.textContent = '100%';
        this.elements.ttsSpeedValue = speedValue;
        speedContainer.appendChild(speedValue);
        
        this.elements.ttsSpeed = createUIElement('input', {
            type: 'range',
            min: 50,
            max: 150,
            value: 100,
            'data-pref-bind': 'tts.speed',
            'data-pref-transform': 'centered-speed'
        }, null, speedContainer);
        
        // Update displayed value when slider changes
        this.elements.ttsSpeed.addEventListener('input', () => {
            this.updateSpeedDisplay();
        });
        
        appSettingsSection.appendChild(speedContainer);
        
        body.appendChild(appSettingsSection);
        
        // TTS Section
        const ttsSection = document.createElement('div');
        ttsSection.className = 'options-section';
        
        const ttsTitle = document.createElement('h3');
        ttsTitle.textContent = this.t('options.speech');
        ttsSection.appendChild(ttsTitle);
        
        // TTS Enable
        const ttsEnableContainer = document.createElement('div');
        ttsEnableContainer.className = 'option-item';
        
        const ttsEnableLabel = document.createElement('label');
        ttsEnableLabel.textContent = this.t('options.enableSpeech') + ':';
        ttsEnableContainer.appendChild(ttsEnableLabel);
        
        this.elements.ttsEnabled = createUIElement('input', { 
            type: 'checkbox',
            'data-pref-bind': 'tts.enabled'
        }, null, ttsEnableContainer);
        
        ttsSection.appendChild(ttsEnableContainer);
        
        // TTS System
        const ttsSystemContainer = document.createElement('div');
        ttsSystemContainer.className = 'option-item';
        
        const ttsSystemLabel = document.createElement('label');
        ttsSystemLabel.textContent = this.t('options.provider') + ':';
        ttsSystemContainer.appendChild(ttsSystemLabel);
        
        this.elements.ttsSystem = createUIElement('select', {
            'data-pref-bind': 'tts.preferred_handler'
        }, null, ttsSystemContainer);
        
        ttsSection.appendChild(ttsSystemContainer);

        const providerStatusContainer = document.createElement('div');
        providerStatusContainer.className = 'provider-status-list';
        this.elements.providerStatus = providerStatusContainer;
        ttsSection.appendChild(providerStatusContainer);
        
        // TTS Voice
        const ttsVoiceContainer = document.createElement('div');
        ttsVoiceContainer.className = 'option-item';
        
        const ttsVoiceLabel = document.createElement('label');
        ttsVoiceLabel.textContent = this.t('options.voice') + ':';
        ttsVoiceContainer.appendChild(ttsVoiceLabel);
        
        this.elements.ttsVoice = createUIElement('select', {
            'data-pref-bind': 'tts.voice'
        }, null, ttsVoiceContainer);
        
        ttsSection.appendChild(ttsVoiceContainer);
        
        // Add API Settings
        const apiSettings = this.createApiSettings();
        ttsSection.appendChild(apiSettings);
        
        body.appendChild(ttsSection);
        
        // Audio Section
        const audioSection = document.createElement('div');
        audioSection.className = 'options-section';
        
        const audioTitle = document.createElement('h3');
        audioTitle.textContent = this.t('options.audio');
        audioSection.appendChild(audioTitle);
        
        audioSection.appendChild(this.createVolumeControl('masterVolume', 'masterVolumeEnabled', 'options.masterVolume', 'options.muteMasterVolume', 'options.unmuteMasterVolume', 100));
        audioSection.appendChild(this.createVolumeControl('ttsVolume', 'ttsVolumeEnabled', 'options.speechVolume', 'options.muteSpeechVolume', 'options.unmuteSpeechVolume', 100));
        audioSection.appendChild(this.createVolumeControl('musicVolume', 'musicVolumeEnabled', 'options.musicVolume', 'options.muteMusicVolume', 'options.unmuteMusicVolume', 70));
        audioSection.appendChild(this.createVolumeControl('sfxVolume', 'sfxVolumeEnabled', 'options.sfxVolume', 'options.muteSfxVolume', 'options.unmuteSfxVolume', 100));
        audioSection.appendChild(this.createVolumeControl('musicDuckingAmount', 'musicDuckingEnabled', 'options.musicDucking', 'options.disableMusicDucking', 'options.enableMusicDucking', 30));
        
        body.appendChild(audioSection);
        
        modalContent.appendChild(body);
        
        // Create footer
        const footer = document.createElement('div');
        footer.className = 'modal-footer';
        
        const closeModalButton = document.createElement('button');
        closeModalButton.textContent = this.t('options.close');
        closeModalButton.onclick = () => this.hide();
        footer.appendChild(closeModalButton);
        
        modalContent.appendChild(footer);
        
        // Add modal content to modal
        this.modal.appendChild(modalContent);
        
        // Add modal to document
        document.body.appendChild(this.modal);
    }

    createVolumeControl(valueKey, enabledKey, labelKey, muteTitleKey, unmuteTitleKey, defaultPercent) {
        const container = document.createElement('div');
        container.className = 'option-item volume-option';

        const label = document.createElement('label');
        label.textContent = this.t(labelKey) + ':';
        container.appendChild(label);

        const toggle = document.createElement('button');
        toggle.type = 'button';
        toggle.className = 'volume-toggle';
        toggle.dataset.prefCategory = 'audio';
        toggle.dataset.prefKey = enabledKey;
        toggle.dataset.muteTitleKey = muteTitleKey;
        toggle.dataset.unmuteTitleKey = unmuteTitleKey;
        toggle.addEventListener('click', () => {
            const current = this.getPreference('audio', enabledKey, true) !== false;
            this.updatePreference('audio', enabledKey, !current);
            this.updateVolumeToggleButton(toggle);
        });
        container.appendChild(toggle);

        const value = document.createElement('span');
        value.className = 'slider-value';
        value.textContent = `${defaultPercent}%`;
        this.elements[`${valueKey}Value`] = value;
        container.appendChild(value);

        const slider = createUIElement('input', {
            type: 'range',
            min: 0,
            max: 100,
            value: defaultPercent,
            'data-pref-bind': `audio.${valueKey}`,
            'data-pref-transform': 'range:0,1'
        }, null, container);
        this.elements[valueKey] = slider;
        slider.addEventListener('input', () => {
            value.textContent = `${slider.value}%`;
        });

        this.updateVolumeToggleButton(toggle);
        return container;
    }

    updateVolumeToggleButtons() {
        if (!this.modal) return;
        this.modal.querySelectorAll('.volume-toggle').forEach(button => {
            this.updateVolumeToggleButton(button);
        });
    }

    updateVolumeToggleButton(button) {
        if (!button) return;
        const enabled = this.getPreference(button.dataset.prefCategory, button.dataset.prefKey, true) !== false;
        button.classList.toggle('is-muted', !enabled);
        button.innerHTML = enabled ? '&#128266;' : '&#128263;';
        const titleKey = enabled ? button.dataset.muteTitleKey : button.dataset.unmuteTitleKey;
        const title = this.t(titleKey);
        button.title = title;
        button.setAttribute('aria-label', title);
    }
    
    /**
     * Create API settings controls
     * @returns {HTMLElement} - API settings element
     */
    createApiSettings() {
        console.log('Options UI: Creating API settings');
        const apiSettings = document.createElement('div');
        apiSettings.className = 'options-section';
        
        // ElevenLabs API settings
        const elevenLabsSettings = document.createElement('div');
        elevenLabsSettings.className = 'api-settings elevenlabs-tts-settings';
        elevenLabsSettings.style.display = 'none';
        
        const elevenLabsTitle = document.createElement('h3');
        elevenLabsTitle.textContent = this.t('options.elevenLabsSettings');
        elevenLabsSettings.appendChild(elevenLabsTitle);
        
        // ElevenLabs API Key
        const elevenLabsApiKeyContainer = document.createElement('div');
        elevenLabsApiKeyContainer.className = 'option-item';
        
        const elevenLabsApiKeyLabel = document.createElement('label');
        elevenLabsApiKeyLabel.textContent = this.t('options.apiKey') + ':';
        elevenLabsApiKeyContainer.appendChild(elevenLabsApiKeyLabel);
        
        this.elements.elevenLabsApiKey = createUIElement('input', { 
            type: 'password',
            'data-pref-bind': 'tts.elevenlabs-tts_api_key'
        }, null, elevenLabsApiKeyContainer);
        
        elevenLabsSettings.appendChild(elevenLabsApiKeyContainer);
        
        // ElevenLabs API URL
        const elevenLabsApiUrlContainer = document.createElement('div');
        elevenLabsApiUrlContainer.className = 'option-item';
        
        const elevenLabsApiUrlLabel = document.createElement('label');
        elevenLabsApiUrlLabel.textContent = this.t('options.apiUrl') + ':';
        elevenLabsApiUrlContainer.appendChild(elevenLabsApiUrlLabel);
        
        this.elements.elevenLabsApiUrl = createUIElement('input', { 
            type: 'text',
            'data-pref-bind': 'tts.elevenlabs-tts_api_url'
        }, null, elevenLabsApiUrlContainer);
        
        elevenLabsSettings.appendChild(elevenLabsApiUrlContainer);
        
        // OpenAI API settings
        const openaiSettings = document.createElement('div');
        openaiSettings.className = 'api-settings openai-tts-settings';
        openaiSettings.style.display = 'none';
        
        const openaiTitle = document.createElement('h3');
        openaiTitle.textContent = this.t('options.openAiSettings');
        openaiSettings.appendChild(openaiTitle);
        
        // OpenAI API Key
        const openaiApiKeyContainer = document.createElement('div');
        openaiApiKeyContainer.className = 'option-item';
        
        const openaiApiKeyLabel = document.createElement('label');
        openaiApiKeyLabel.textContent = this.t('options.apiKey') + ':';
        openaiApiKeyContainer.appendChild(openaiApiKeyLabel);
        
        this.elements.openaiApiKey = createUIElement('input', { 
            type: 'password',
            'data-pref-bind': 'tts.openai-tts_api_key'
        }, null, openaiApiKeyContainer);
        
        openaiSettings.appendChild(openaiApiKeyContainer);
        
        // OpenAI API URL
        const openaiApiUrlContainer = document.createElement('div');
        openaiApiUrlContainer.className = 'option-item';
        
        const openaiApiUrlLabel = document.createElement('label');
        openaiApiUrlLabel.textContent = this.t('options.apiUrl') + ':';
        openaiApiUrlContainer.appendChild(openaiApiUrlLabel);
        
        this.elements.openaiApiUrl = createUIElement('input', { 
            type: 'text', 
            'data-pref-bind': 'tts.openai-tts_api_url'
        }, null, openaiApiUrlContainer);
        
        openaiSettings.appendChild(openaiApiUrlContainer);
        
        // Add all API settings to container
        apiSettings.appendChild(elevenLabsSettings);
        apiSettings.appendChild(openaiSettings);
        
        return apiSettings;
    }
    
    /**
     * Set up event listeners for options controls
     */
    setupEventListeners() {
        if (!this.modal) return;
        
        // TTS System change
        if (this.elements.ttsSystem) {
            this.elements.ttsSystem.addEventListener('change', async (event) => {
                this.updateApiSettingsVisibility(event.target.value);
                const ttsFactory = this.getModule('tts-factory');
                if (ttsFactory) {
                    await ttsFactory.refreshHandlerStatus(event.target.value);
                }
                await this.populateVoices();
                this.renderProviderStatuses();
            });
        }
        
        // Close when clicking outside the modal content
        this.modal.addEventListener('click', (event) => {
            if (event.target === this.modal) {
                this.hide();
            }
        });
    }
      
    /**
     * Update API settings visibility based on selected TTS system
     * @param {string} handlerId - Selected TTS system
     */
    updateApiSettingsVisibility(handlerId) {
        const apiContainers = this.modal.querySelectorAll('.api-settings');
        apiContainers.forEach(container => {
            const shouldShow = container.classList.contains(`${handlerId}-settings`);
            container.style.display = shouldShow ? 'block' : 'none';
        });
    }
    
    /**
     * Show the options UI
     */
    show() {
        if (this.modal) {
            this.modal.style.display = 'flex';
            document.body.classList.add('modal-open');
        }
    }
    
    /**
     * Hide the options UI
     */
    hide() {
        if (this.modal) {
            this.modal.style.display = 'none';
            document.body.classList.remove('modal-open');
        }
    }
    
    /**
     * Toggle the options UI visibility
     */
    toggle() {
        if (this.modal) {
            if (this.modal.style.display === 'flex') {
                this.hide();
            } else {
                this.show();
            }
        }
    }
    
    /**
     * Populate the TTS systems dropdown
     */
    async populateTtsSystems() {
        const ttsFactory = this.getModule('tts-factory');
        if (!ttsFactory || !this.elements.ttsSystem) return;
        
        // Get available TTS systems
        const handlers = ttsFactory.getAvailableHandlers();
        console.log('Options UI: Available TTS handlers:', handlers);
        
        // Format for display
        const systems = handlers.map(handler => ({
            id: handler.id,
            name: handler.displayName || handler.id
        }));
        
        // Populate dropdown
        populateDropdown(
            this.elements.ttsSystem,
            systems,
            'id',
            'name',
            this.getPreference('tts', 'preferred_handler', 'none')
        );
        
        // Update API settings visibility
        this.updateApiSettingsVisibility(this.elements.ttsSystem.value);
        this.renderProviderStatuses();
    }
    
    /**
     * Populate the voices dropdown
     */
    async populateVoices() {
        const ttsFactory = this.getModule('tts-factory');
        if (!ttsFactory || !this.elements.ttsVoice) return;
        
        const selectedHandler = this.elements.ttsSystem?.value || this.getPreference('tts', 'preferred_handler', 'none');
        const voices = typeof ttsFactory.getVoicesForHandler === 'function'
            ? await ttsFactory.getVoicesForHandler(selectedHandler) || []
            : await ttsFactory.getVoices() || [];
        console.log('Options UI: TTS voices:', voices);
        
        // Populate dropdown
        populateDropdown(
            this.elements.ttsVoice,
            voices,
            'id',
            'name',
            this.getPreference('tts', `${selectedHandler}_voice`, this.getPreference('tts', 'voice', ''))
        );
    }

    renderProviderStatuses() {
        const container = this.elements.providerStatus;
        const ttsFactory = this.getModule('tts-factory');
        if (!container || !ttsFactory || typeof ttsFactory.getHandlerStatuses !== 'function') {
            return;
        }

        container.innerHTML = '';
        const statuses = ttsFactory.getHandlerStatuses();
        statuses.forEach(status => {
            const row = document.createElement('div');
            row.className = 'provider-status-row';

            const name = document.createElement('span');
            name.textContent = status.name;
            row.appendChild(name);

            const value = document.createElement('span');
            value.className = 'provider-status-value';
            value.textContent = `${status.ready ? 'ready' : 'not ready'} - ${status.message}`;
            row.appendChild(value);

            container.appendChild(row);
        });
    }
    
    /**
     * Populate the languages dropdown
     */
    async populateLanguages() {
        const localization = this.getModule('localization');
        if (!localization || !this.elements.language) return;
        
        // Get available languages
        const languages = localization.getAvailableLocales() || [];
        console.log('Options UI: Available languages:', languages);
        
        // Format languages with their names
        const languageOptions = languages.map(code => ({
            code,
            name: localization.getLanguageName(code)
        }));
        
        // Populate dropdown
        populateDropdown(
            this.elements.language,
            languageOptions,
            'code',
            'name',
            this.getPreference('app', 'locale', localization.getLocale?.() || 'en_US')
        );
    }
    
    /**
     * Load user preferences from the persistence manager
     * This is now handled by the persistence manager's setupBindings method
     */
    loadPreferences() {
        // Update API settings visibility based on current TTS system
        if (this.elements.ttsSystem) {
            this.updateApiSettingsVisibility(this.elements.ttsSystem.value);
        }
    }
        
    /**
     * Show a reload notice
     * @param {string} message - Message to show
     */
    showReloadNotice(message) {
        console.log('Options UI: Reload required -', message);
        this.reloadRequired = true;
    }
    
    /**
     * Set up listeners for settings that should save immediately
     */
    setupImmediateSaveListeners() {
        // Settings are saved immediately with two-way binding via data-pref-bind attributes
    }
    
    /**
     * Set up API URL fields with default values
     */
    setupApiUrlFields() {
        // Set up ElevenLabs API URL
        if (this.elements.elevenLabsApiUrl) {
            const savedUrl = this.getPreference('tts', 'elevenlabs-tts_api_url');
            const defaultUrl = 'https://api.elevenlabs.io/v1';
            
            // If no saved URL, set the default
            if (!savedUrl) {
                console.log('Options UI: Setting default ElevenLabs API URL:', defaultUrl);
                this.updatePreference('tts', 'elevenlabs-tts_api_url', defaultUrl);
            }
        }
        
        // Set up OpenAI API URL
        if (this.elements.openaiApiUrl) {
            const savedUrl = this.getPreference('tts', 'openai-tts_api_url');
            const defaultUrl = 'https://api.openai.com/v1';
            
            // If no saved URL, set the default
            if (!savedUrl) {
                console.log('Options UI: Setting default OpenAI API URL:', defaultUrl);
                this.updatePreference('tts', 'openai-tts_api_url', defaultUrl);
            }
        }
        
        // Make sure API keys are initialized if not already set
        if (!this.getPreference('tts', 'elevenlabs-tts_api_key')) {
            this.updatePreference('tts', 'elevenlabs-tts_api_key', '');
        }
        
        if (!this.getPreference('tts', 'openai-tts_api_key')) {
            this.updatePreference('tts', 'openai-tts_api_key', '');
        }
    }
    
    /**
     * Set up the initial state of the Options UI
     */
    async setupInitialState() {
        // Add event listener for toggling options UI
        document.addEventListener('ui:options:toggle', () => this.toggle());
        
        // Set up key bindings
        document.addEventListener('keydown', (e) => {
            if (e.key === 'Escape' && this.modal && this.modal.style.display === 'flex') {
                this.hide();
            }
        });
        
        // Populate TTS systems selector
        await this.populateTtsSystems();
        
        // Populate languages
        await this.populateLanguages();
        
        // Populate voices based on current TTS system
        await this.populateVoices();
        
        // Register for TTS events to update voices when they change
        document.addEventListener('tts:voices:updated', () => {
            console.log('Options UI: Received tts:voices:updated event, updating voice dropdown');
            this.populateVoices();
            this.renderProviderStatuses();
        });
        
        // Set up language change listener
        document.addEventListener('locale:changed', async () => {
            this.updateUIText();
            await this.populateLanguages();
        });
        
        // Register event listeners for TTS availability and voiceId changes
        document.addEventListener('tts:engine:change', async (event) => {
            console.log('Options UI: Received TTS engine change event:', event.detail);
            await this.populateVoices();
            this.updateApiSettingsVisibility(this.elements.ttsSystem.value);
            this.renderProviderStatuses();
        });

        document.addEventListener('tts:status:updated', () => {
            this.renderProviderStatuses();
        });

        document.addEventListener('tts:enabled:change', async (event) => {
            if (!event.detail || typeof event.detail.enabled !== 'boolean') {
                return;
            }

            if (this.elements.ttsEnabled) {
                this.elements.ttsEnabled.checked = event.detail.enabled;
            }

            const ttsFactory = this.getModule('tts-factory');
            if (!ttsFactory) {
                return;
            }

            if (event.detail.enabled) {
                const preferredHandler = this.getPreference('tts', 'preferred_handler', 'none');
                if (preferredHandler !== 'none') {
                    await ttsFactory.setActiveHandler(preferredHandler);
                }
            } else {
                await ttsFactory.disableAfterCurrentPlayback();
            }
            this.renderProviderStatuses();
        });
    }
    
    /**
     * Set up two-way bindings for preferences using data attributes
     */
    setupPreferenceBindings() {
        const persistenceManager = this.getModule('persistence-manager');
        if (!persistenceManager || !persistenceManager.setupBindings) {
            console.error('Options UI: Cannot set up preference bindings, persistence manager not available or missing setupBindings method');
            return;
        }
        
        // Setup all bindings in the modal
        this.bindings = persistenceManager.setupBindings('#options-modal');
        console.log('Options UI: Preference bindings set up', this.bindings.length);
        this.updateSpeedDisplay();
        this.updateVolumeDisplays();
        
        // Add event listeners for side effects when preferences change
        document.addEventListener('preference-updated', (event) => {
            const { category, key, value } = event.detail;
            
            // Handle audio settings side effects
            if (category === 'audio') {
                const audioManager = this.getModule('audio-manager');
                if (!audioManager) return;
                
                if (key === 'masterVolume') {
                    audioManager.setMasterVolume(value);
                } else if (key === 'musicVolume') {
                    audioManager.setMusicVolume(value);
                } else if (key === 'sfxVolume') {
                    audioManager.setSfxVolume(value);
                } else if (key === 'ttsVolume') {
                    audioManager.setTtsVolume(value);
                } else if (key === 'masterVolumeEnabled') {
                    audioManager.setVolumeEnabled('master', value);
                } else if (key === 'musicVolumeEnabled') {
                    audioManager.setVolumeEnabled('music', value);
                } else if (key === 'sfxVolumeEnabled') {
                    audioManager.setVolumeEnabled('sfx', value);
                } else if (key === 'ttsVolumeEnabled') {
                    audioManager.setVolumeEnabled('tts', value);
                } else if (key === 'musicDuckingAmount') {
                    audioManager.setMusicDuckingAmount(value);
                } else if (key === 'musicDuckingEnabled') {
                    audioManager.setMusicDuckingEnabled(value);
                }

                this.updateVolumeDisplays();
                this.updateVolumeToggleButtons();
            }
            
            // Handle TTS settings side effects
            if (category === 'tts') {
                const ttsFactory = this.getModule('tts-factory');
                if (!ttsFactory) return;
                
                if (key === 'preferred_handler') {
                    const enabled = this.getPreference('tts', 'enabled', false);
                    const activation = enabled && value !== 'none'
                        ? ttsFactory.setActiveHandler(value)
                        : Promise.resolve(ttsFactory.disableAfterCurrentPlayback());
                    activation.then(() => {
                        this.populateVoices();
                        this.renderProviderStatuses();
                    });
                    this.updateApiSettingsVisibility(value);
                } else if (key === 'voice') {
                    ttsFactory.configure({ voice: value });
                } else if (key === 'speed') {
                    ttsFactory.configure({ speed: value });
                } else if (key === 'enabled') {
                    if (!value) {
                        ttsFactory.disableAfterCurrentPlayback();
                    } else {
                        const preferredHandler = this.getPreference('tts', 'preferred_handler', 'none');
                        if (preferredHandler !== 'none') {
                            ttsFactory.setActiveHandler(preferredHandler);
                        }
                    }
                    document.dispatchEvent(new CustomEvent('tts:enabled:change', {
                        detail: { enabled: value }
                    }));
                } else if (key.endsWith('_api_key')) {
                    const provider = key.replace('_api_key', '');
                    this.dispatchApiChangeEvent('api:keyChanged', provider, 'key', value);
                    ttsFactory.refreshHandlerStatus(provider).then(() => this.renderProviderStatuses());
            } else if (key.endsWith('_api_url')) {
                const provider = key.replace('_api_url', '');
                this.dispatchApiChangeEvent('api:urlChanged', provider, 'url', value);
                ttsFactory.refreshHandlerStatus(provider).then(() => this.renderProviderStatuses());
            }
            if (key === 'speed' && this.elements.ttsSpeed) {
                this.updateSpeedDisplay();
            }
        }
            
            // Handle locale changes
            if (category === 'app' && key === 'locale') {
                const localization = this.getModule('localization');
                if (localization) {
                    localization.setLocale(value);
                }
            }
        });
    }

    updateSpeedDisplay() {
        if (!this.elements.ttsSpeed || !this.elements.ttsSpeedValue) {
            return;
        }

        this.elements.ttsSpeedValue.textContent = `${this.elements.ttsSpeed.value}%`;
    }

    updateVolumeDisplays() {
        if (this.elements.masterVolume && this.elements.masterVolumeValue) {
            this.elements.masterVolumeValue.textContent = `${this.elements.masterVolume.value}%`;
        }
        if (this.elements.ttsVolume && this.elements.ttsVolumeValue) {
            this.elements.ttsVolumeValue.textContent = `${this.elements.ttsVolume.value}%`;
        }
        if (this.elements.musicVolume && this.elements.musicVolumeValue) {
            this.elements.musicVolumeValue.textContent = `${this.elements.musicVolume.value}%`;
        }
        if (this.elements.sfxVolume && this.elements.sfxVolumeValue) {
            this.elements.sfxVolumeValue.textContent = `${this.elements.sfxVolume.value}%`;
        }
        if (this.elements.musicDuckingAmount && this.elements.musicDuckingAmountValue) {
            this.elements.musicDuckingAmountValue.textContent = `${this.elements.musicDuckingAmount.value}%`;
        }
    }
}

// Create the singleton instance
const OptionsUI = new OptionsUIModule();

// Export the module
export { OptionsUI };
