/**
 * Localization Module for AI Interactive Fiction
 * Handles translations and locale settings
 */
import { BaseModule } from './base-module.js';

class LocalizationModule extends BaseModule {
    /**
     * Create a new localization module
     */
    constructor() {
        super('localization', 'Localization');
        
        // Current locale
        this.translations = {};
        this.defaultLocale = 'en_US';
        this.currentLocale = this.defaultLocale;
        this.dependencies = ['persistence-manager'];
        
        // Available translations
        this.languageNames = {
            'en_US': 'English (US)',
            'de_DE': 'Deutsch (Deutschland)'
        };
        
        // Bind methods
        this.bindMethods([
            'setLocale',
            'normalizeLocale',
            'getLocale',
            'translate',
            'getAvailableLocales',
            'getLanguageName',
            'getLanguage'
        ]);
    }
    
    /**
     * Initialize the module
     * @returns {Promise<boolean>} - Resolves with success status
     */
    async initialize() {
        try {
            this.reportProgress(10, "Initializing localization");
            
            // Load default English locale
            await this.loadTranslations(this.defaultLocale);
            this.reportProgress(50, "Loaded default locale");
            
            // Get stored locale from persistence manager if available
            const persistenceManager = this.getModule('persistence-manager');
            
            if (persistenceManager) {
                const storedLocale = persistenceManager.getPreference('app', 'locale');
                if (storedLocale) {
                    const normalizedLocale = this.normalizeLocale(storedLocale);
                    console.log(`Localization: Found stored locale: ${normalizedLocale}`);
                    await this.loadTranslations(normalizedLocale);
                    this.currentLocale = normalizedLocale;
                    this.reportProgress(80, `Loaded stored locale: ${normalizedLocale}`);
                } else {
                    console.log(`Localization: No stored locale found, using default ${this.defaultLocale}`);
                    this.currentLocale = this.defaultLocale;
                    this.reportProgress(80, `Using default locale: ${this.defaultLocale}`);
                }
            } else {
                console.log(`Localization: Persistence manager not available, using default ${this.defaultLocale} locale`);
                this.reportProgress(80, `Using default locale: ${this.defaultLocale}`);
            }
            
            // Dispatch event to notify about loaded locale
            document.dispatchEvent(new CustomEvent('localization:languageChanged', {
                detail: { locale: this.currentLocale }
            }));
            document.documentElement.lang = this.currentLocale.replace('_', '-');
            
            this.reportProgress(100, "Localization ready");
            return true;
        } catch (error) {
            console.error("Error initializing localization:", error);
            this.reportProgress(100, "Localization failed");
            return false;
        }
    }
    
    /**
     * Load translations for a locale
     * @param {string} locale - Locale to load
     * @returns {Promise<void>}
     */
    async loadTranslations(locale) {
        const normalizedLocale = this.normalizeLocale(locale);
        if (this.translations[normalizedLocale]) {
            return; // Already loaded
        }
        
        try {
            // Try to load the exact locale
            const response = await fetch(`/locales/${normalizedLocale}.json`);
            
            if (response.ok) {
                const translations = await response.json();
                this.translations[normalizedLocale] = translations;
            } else {
                // If exact locale not found, try to load just the language part
                const langPart = normalizedLocale.split('_')[0];
                if (langPart !== normalizedLocale) {
                    const langResponse = await fetch(`/locales/${langPart}.json`);
                    if (langResponse.ok) {
                        const translations = await langResponse.json();
                        this.translations[normalizedLocale] = translations;
                    } else {
                        console.warn(`No translations found for ${locale} or ${langPart}`);
                    }
                }
            }
        } catch (error) {
            console.error(`Error loading translations for ${locale}:`, error);
            throw error;
        }
    }
    
    /**
     * Set the current locale
     * @param {string} locale - Locale to set
     * @returns {Promise<boolean>} - Success status
     */
    async setLocale(locale, options = {}) {
        if (!locale) return false;
        
        try {
            const normalizedLocale = this.normalizeLocale(locale);
            const userInitiated = options.userInitiated !== false;
            
            // Load translations if not already loaded
            if (!this.translations[normalizedLocale]) {
                await this.loadTranslations(normalizedLocale);
            }
            
            // Set current locale
            this.currentLocale = normalizedLocale;
            
            // Update persistence
            const persistenceManager = this.getModule('persistence-manager');
            if (persistenceManager) {
                persistenceManager.updatePreference('app', 'locale', normalizedLocale);
                if (userInitiated) {
                    persistenceManager.updatePreference('app', 'localeUserOverride', true);
                }
            }

            document.documentElement.lang = normalizedLocale.replace('_', '-');
            
            // Dispatch locale change event
            this.dispatchEvent('locale-changed', {
                locale: normalizedLocale
            });
            document.dispatchEvent(new CustomEvent('locale:changed', {
                detail: { locale: normalizedLocale }
            }));
            document.dispatchEvent(new CustomEvent('localization:languageChanged', {
                detail: { locale: normalizedLocale }
            }));
            
            return true;
        } catch (error) {
            console.error(`Error setting locale to ${locale}:`, error);
            return false;
        }
    }

    normalizeLocale(locale) {
        const normalized = String(locale || this.defaultLocale).trim().replace('-', '_').toLowerCase();
        if (normalized.startsWith('de')) return 'de_DE';
        return 'en_US';
    }
    
    /**
     * Get the current locale
     * @returns {string} - Current locale
     */
    getLocale() {
        return this.currentLocale;
    }
    
    /**
     * Get the language part of the current locale (e.g., 'en' from 'en-us')
     * @returns {string} - Language code
     */
    getLanguage() {
        return this.currentLocale.split('_')[0];
    }
    
    /**
     * Get all available locales
     * @returns {Array<string>} - Array of locale codes
     */
    getAvailableLocales() {
        // Return the keys of the language names object
        // This is a simplification - in a real app, we would dynamically load available locales
        return Object.keys(this.languageNames);
    }
    
    /**
     * Get the language name for a locale
     * @param {string} locale - Locale code
     * @returns {string} - Language name
     */
    getLanguageName(locale) {
        if (!locale) return '';
        
        // Normalize locale
        const normalizedLocale = this.normalizeLocale(locale);
        
        // Try exact match
        if (this.languageNames[normalizedLocale]) {
            return this.languageNames[normalizedLocale];
        }
        
        // Try language part only
        const langPart = normalizedLocale.split('_')[0];
        if (this.languageNames[langPart]) {
            return this.languageNames[langPart];
        }
        
        // Fallback: return the locale code itself
        return locale;
    }
    
    /**
     * Translate a key
     * @param {string} key - Translation key
     * @param {Object} params - Parameters for interpolation
     * @returns {string} - Translated text
     */
    translate(key, params = {}) {
        if (!key) return '';
        
        // Get translations for current locale
        const translations = this.translations[this.currentLocale] || {};
        
        // Get translation or fallback to key
        let translation = translations[key] || key;
        
        // Interpolate parameters
        if (params && Object.keys(params).length > 0) {
            for (const [param, value] of Object.entries(params)) {
                translation = translation.replace(new RegExp(`\{\{${param}\}\}`, 'g'), value);
            }
        }
        
        return translation;
    }
    
    /**
     * Clean up when module is disposed
     */
    dispose() {
        // Clear translations
        this.translations = {};
    }
}

// Create the singleton instance
const Localization = new LocalizationModule();

// Export the module
export { Localization };
