/**
 * i18n - Internationalization System
 * Handles translations for the tenant panel
 * 
 * @module i18n
 */

const i18n = {
  currentLanguage: 'en',
  translations: {},
  fallbackLanguage: 'en',
  isLoaded: false,
  isInitializing: false,

  /**
   * Initialize i18n system
   * @param {string} language - Language code (en, pt, es, etc.)
   */
  async init(language = null) {
    // Prevent multiple simultaneous initializations
    if (this.isInitializing) {
      return;
    }
    
    // Check if already loaded with same language
    if (this.isLoaded && language && this.currentLanguage === language) {
      this.translatePage();
      return;
    }

    this.isInitializing = true;

    let defaultLanguage = null;

    // Always fetch the default language from server
    const token = localStorage.getItem('superadmin_token');
    if (token) {
      try {
        const response = await fetch('/api/superadmin/languages', {
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });
        if (response.ok) {
          const data = await response.json();
          if (data.success && data.data.defaultLanguage) {
            defaultLanguage = data.data.defaultLanguage;
            console.log('✅ Default language from server:', defaultLanguage);
          }
        }
      } catch (e) {
        console.error('❌ Could not fetch default language:', e);
      }
    }

    // Priority: 1. Passed language, 2. Server default, 3. Saved preference, 4. Fallback to 'en'
    const savedLang = localStorage.getItem('language');
    language = language || defaultLanguage || savedLang || 'en';

    console.log('🌍 Initializing i18n with language:', language);

    this.currentLanguage = language;
    
    // Load translations for current language
    await this.loadTranslations(language);
    
    // Also preload fallback language if different
    if (language !== this.fallbackLanguage && !this.translations[this.fallbackLanguage]) {
      await this.loadTranslations(this.fallbackLanguage);
    }
    
    this.isLoaded = true;
    this.isInitializing = false;
    this.translatePage();
    
    // Setup mutation observer for dynamic content
    this.setupMutationObserver();
    
    localStorage.setItem('language', language);
    if (defaultLanguage) {
      localStorage.setItem('system_default_language', defaultLanguage);
    }
    document.documentElement.lang = language;
  },

  /**
   * Load translations from server
   * @param {string} language - Language code
   */
  async loadTranslations(language) {
    try {
      // Add cache-busting parameter
      const response = await fetch(`/locales/${language}.json?v=${Date.now()}`);
      if (!response.ok) {
        throw new Error(`Failed to load ${language} translations`);
      }
      const data = await response.json();
      this.translations[language] = data;
      console.log(`✅ Translations loaded for ${language}:`, Object.keys(data).length, 'categories');
    } catch (error) {
      console.error('❌ Error loading translations:', error);
      if (language !== this.fallbackLanguage) {
        console.log(`Falling back to ${this.fallbackLanguage}...`);
        await this.loadTranslations(this.fallbackLanguage);
      }
    }
  },

  /**
   * Get translation for a key
   * @param {string} key - Translation key (e.g., 'stores.title')
   * @param {Object} params - Parameters for interpolation
   * @returns {string} Translated text
   */
  t(key, params = {}) {
    // Try current language first
    let value = this.getNestedValue(this.translations[this.currentLanguage], key);
    
    // Fallback to English if not found
    if (value === undefined || value === null) {
      value = this.getNestedValue(this.translations[this.fallbackLanguage], key);
    }
    
    // Return key if still not found (only warn if translations are loaded)
    if (value === undefined || value === null) {
      if (this.isLoaded) {
        console.warn(`Translation key not found: ${key}`);
      }
      return key;
    }

    if (typeof value !== 'string') {
      if (this.isLoaded) {
        console.warn(`Translation value is not a string: ${key}`);
      }
      return key;
    }

    // Replace parameters {{param}}
    return value.replace(/\{\{(\w+)\}\}/g, (match, param) => {
      return params[param] !== undefined ? params[param] : match;
    });
  },

  /**
   * Get nested value from object using dot notation
   * @param {Object} obj - Object to search
   * @param {string} key - Dot-notated key (e.g., 'stores.title')
   * @returns {*} Value or undefined
   */
  getNestedValue(obj, key) {
    if (!obj || !key || typeof key !== 'string') return undefined;
    
    const keys = key.split('.');
    let value = obj;

    for (const k of keys) {
      if (value && typeof value === 'object' && k in value) {
        value = value[k];
      } else {
        return undefined;
      }
    }

    return value;
  },

  /**
   * Translate all elements with data-i18n attribute
   */
  translatePage() {
    // Don't translate if translations aren't loaded yet
    if (!this.isLoaded || !this.translations[this.currentLanguage]) {
      return;
    }

    // Translate text content
    document.querySelectorAll('[data-i18n]').forEach(element => {
      const key = element.getAttribute('data-i18n');
      if (key) {
        const translation = this.t(key);
        if (translation !== key) {
          element.textContent = translation;
        }
      }
    });

    // Translate placeholders
    document.querySelectorAll('[data-i18n-placeholder]').forEach(element => {
      const key = element.getAttribute('data-i18n-placeholder');
      if (key) {
        const translation = this.t(key);
        if (translation !== key) {
          element.placeholder = translation;
        }
      }
    });

    // Translate titles
    document.querySelectorAll('[data-i18n-title]').forEach(element => {
      const key = element.getAttribute('data-i18n-title');
      if (key) {
        const translation = this.t(key);
        if (translation !== key) {
          element.title = translation;
        }
      }
    });

    // Translate aria-labels
    document.querySelectorAll('[data-i18n-aria]').forEach(element => {
      const key = element.getAttribute('data-i18n-aria');
      if (key) {
        const translation = this.t(key);
        if (translation !== key) {
          element.setAttribute('aria-label', translation);
        }
      }
    });
  },

  /**
   * Change language
   * @param {string} language - New language code
   */
  async changeLanguage(language) {
    if (language === this.currentLanguage) return;
    
    this.currentLanguage = language;
    
    // Load translations if not already loaded
    if (!this.translations[language]) {
      await this.loadTranslations(language);
    }
    
    this.translatePage();
    localStorage.setItem('language', language);
    document.documentElement.lang = language;

    // Dispatch language change event for RTL integration
    window.dispatchEvent(new CustomEvent('languagechange', {
      detail: { language: language }
    }));
    
    console.log(`Language changed to: ${language}`);
  },

  /**
   * Get current language
   * @returns {string} Current language code
   */
  getCurrentLanguage() {
    return this.currentLanguage;
  },

  /**
   * Set language
   * @param {string} language - Language code
   */
  setLanguage(language) {
    this.changeLanguage(language);
  },

  /**
   * Get language
   * @returns {string} Current language code
   */
  getLanguage() {
    return this.currentLanguage;
  },

  /**
   * Setup mutation observer to translate dynamically added elements
   */
  setupMutationObserver() {
    if (this.observer) return; // Already setup

    this.observer = new MutationObserver((mutations) => {
      if (!this.isLoaded) return;

      let shouldTranslate = false;
      for (const mutation of mutations) {
        if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
          shouldTranslate = true;
          break;
        }
      }

      if (shouldTranslate) {
        // Debounce translation to avoid excessive calls
        clearTimeout(this.translateTimeout);
        this.translateTimeout = setTimeout(() => {
          this.translatePage();
        }, 100);
      }
    });

    this.observer.observe(document.body, {
      childList: true,
      subtree: true
    });
  }
};

// Expose i18n globally
window.i18n = i18n;
