/**
 * Cyber-Assistant - Module d'internationalisation (i18n)
 * Gère les traductions multi-langues de l'interface utilisateur.
 *
 * Langues supportées :
 * - fr : Français (défaut)
 * - en : English
 * - nl : Nederlands
 *
 * Utilisation :
 * - CSI_i18n.t('key') ou t('key') : Retourne la traduction
 * - CSI_i18n.setLanguage('en') : Change la langue
 * - CSI_i18n.getLanguage() : Retourne la langue courante
 */
(function() {
  'use strict';

  // Clé localStorage pour stocker la langue
  const STORAGE_KEY = 'smsi_language';

  // Langue par défaut
  const DEFAULT_LANGUAGE = 'fr';

  // Langues disponibles
  const AVAILABLE_LANGUAGES = {
    fr: { name: 'Français', flag: '🇫🇷' },
    en: { name: 'English', flag: '🇬🇧' },
    nl: { name: 'Nederlands', flag: '🇳🇱' }
  };

  // Cascade de repli par langue : clé absente en nl → en → fr (le fr est la référence).
  const FALLBACK_CHAIN = {
    nl: ['en', 'fr'],
    en: ['fr'],
    fr: []
  };

  // Dictionnaire de traductions (chargé dynamiquement)
  let translations = {};

  // Langue courante
  let currentLanguage = DEFAULT_LANGUAGE;

  // Guard against double initialization
  var _i18nInitialized = false;

  /**
   * Initialise le module i18n
   */
  function init() {
    if (_i18nInitialized) return;
    _i18nInitialized = true;

    // Charger la langue sauvegardée ou utiliser le défaut
    const savedLang = localStorage.getItem(STORAGE_KEY);
    if (savedLang && AVAILABLE_LANGUAGES[savedLang]) {
      currentLanguage = savedLang;
    } else {
      // Détecter la langue du navigateur : fr-*/en-*/nl-* → langue correspondante,
      // tout le reste → français (langue par défaut du produit).
      const browserLang = navigator.language?.substring(0, 2).toLowerCase();
      currentLanguage = AVAILABLE_LANGUAGES[browserLang] ? browserLang : DEFAULT_LANGUAGE;
      // Nettoyer une ancienne valeur invalide dans le localStorage
      if (savedLang && !AVAILABLE_LANGUAGES[savedLang]) {
        localStorage.setItem(STORAGE_KEY, currentLanguage);
      }
    }

    // Set html lang on init
    document.documentElement.lang = currentLanguage;

    void 0;
  }

  /**
   * Charge un fichier de traduction
   * @param {string} lang - Code de la langue
   * @param {object} data - Dictionnaire de traductions
   */
  function loadTranslations(lang, data) {
    if (!AVAILABLE_LANGUAGES[lang]) {
      void 0;
      return false;
    }

    translations[lang] = data;
    void 0;
    return true;
  }

  /**
   * Retourne la traduction d'une clé
   * @param {string} key - Clé de traduction (ex: 'nav.dashboard')
   * @param {object} params - Paramètres pour l'interpolation {count: 5}
   * @returns {string} Traduction ou clé si non trouvée
   */
  /**
   * Résout une clé imbriquée dans un dictionnaire
   * @param {object} dict - Dictionnaire de traductions
   * @param {string} key - Clé (ex: 'nav.dashboard')
   * @returns {string|undefined} Valeur trouvée ou undefined
   */
  function resolveKey(dict, key) {
    if (!dict) return undefined;
    let value = dict;
    const parts = key.split('.');
    for (let i = 0; i < parts.length; i++) {
      if (value && typeof value === 'object' && parts[i] in value) {
        value = value[parts[i]];
      } else {
        return undefined;
      }
    }
    return typeof value === 'string' ? value : undefined;
  }

  function translate(key, params) {
    // Chercher la traduction dans la langue courante
    const langDict = translations[currentLanguage];
    let value = resolveKey(langDict, key);

    // Cascade de repli (nl → en → fr ; en → fr) si la clé n'existe pas dans la langue courante
    if (value === undefined) {
      const chain = FALLBACK_CHAIN[currentLanguage] || ['fr'];
      for (let i = 0; i < chain.length && value === undefined; i++) {
        value = resolveKey(translations[chain[i]], key);
      }
      if (value !== undefined && typeof console !== 'undefined' && console.debug) {
        void 0;
      }
    }

    // Si toujours pas trouvé, retourner le fallback string ou la clé brute
    if (value === undefined) {
      if (typeof console !== 'undefined' && console.debug) {
        void 0;
      }
      if (typeof params === 'string') return params;
      return key;
    }

    // Interpolation des paramètres {{count}}
    if (params && typeof params === 'object') {
      value = value.replace(/\{\{(\w+)\}\}/g, function(match, paramName) {
        return params[paramName] !== undefined ? params[paramName] : match;
      });
    }

    return value;
  }

  /**
   * Change la langue courante
   * @param {string} lang - Code de la langue
   * @param {object} [opts] - { persist: false } pour un changement TEMPORAIRE
   *                          (n'écrit pas localStorage, ne consomme pas isFirstLaunch)
   * @returns {boolean} Succès du changement
   */
  function setLanguage(lang, opts) {
    if (!AVAILABLE_LANGUAGES[lang]) {
      void 0;
      return false;
    }

    currentLanguage = lang;
    // FIX-WIZARD-LANG-FLAG (audit 2026-06-10, bundle.js:2768) : le rendu de l'étape
    // « langue » du wizard bascule temporairement en anglais ; persister ici consommait
    // définitivement le flag de premier lancement (isFirstLaunch) avant tout choix
    // utilisateur. opts.persist === false saute l'écriture localStorage — le flag n'est
    // consommé qu'à la validation de l'étape (onLeave → setLanguage + markLanguageChosen).
    if (!opts || opts.persist !== false) {
      localStorage.setItem(STORAGE_KEY, lang);
    }

    // Update html lang attribute for accessibility and SEO
    document.documentElement.lang = lang;

    void 0;

    // Émettre un événement pour que l'UI se mette à jour
    if (typeof CustomEvent !== 'undefined') {
      window.dispatchEvent(new CustomEvent('languageChange', {
        detail: { language: lang }
      }));
    }

    return true;
  }

  /**
   * Retourne la langue courante
   * @returns {string} Code de la langue
   */
  function getLanguage() {
    return currentLanguage;
  }

  /**
   * Retourne les langues disponibles
   * @returns {object} { code: { name, flag } }
   *
   * FEAT-I18N-NL : ne propose que les langues dont les traductions sont réellement
   * chargées (un package sans nl.js ne doit pas offrir un « Nederlands » qui
   * afficherait de l'anglais en silence). fr/en sont toujours embarquées ; avant le
   * chargement des locales (appel très précoce), on retourne la liste complète.
   */
  function getAvailableLanguages() {
    const loaded = Object.keys(translations);
    if (loaded.length === 0) return { ...AVAILABLE_LANGUAGES };
    const out = {};
    Object.keys(AVAILABLE_LANGUAGES).forEach(function(code) {
      if (translations[code] || code === currentLanguage) out[code] = AVAILABLE_LANGUAGES[code];
    });
    return out;
  }

  /**
   * Vérifie si c'est le premier lancement (pas de langue sauvegardée)
   * @returns {boolean}
   */
  function isFirstLaunch() {
    return localStorage.getItem(STORAGE_KEY) === null;
  }

  /**
   * Marque le choix de langue comme effectué
   */
  function markLanguageChosen() {
    localStorage.setItem(STORAGE_KEY, currentLanguage);
  }

  /**
   * Traduit tous les éléments avec data-i18n dans le DOM
   */
  function translatePage() {
    const elements = document.querySelectorAll('[data-i18n]');
    elements.forEach(function(el) {
      const key = el.getAttribute('data-i18n');
      const translation = translate(key);

      // Ne pas remplacer si la traduction n'existe pas (clé retournée telle quelle)
      if (translation !== key) {
        // Gérer différents types d'éléments
        if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') {
          if (el.placeholder) {
            el.placeholder = translation;
          }
        } else if (el.tagName === 'OPTION') {
          el.textContent = translation;
        } else {
          // Préserver les icônes et autres enfants
          const icon = el.querySelector('i.fas, i.far, i.fab');
          if (icon) {
            el.innerHTML = '';
            el.appendChild(icon.cloneNode(true));
            el.appendChild(document.createTextNode(' ' + translation));
          } else {
            el.textContent = translation;
          }
        }
      }
    });

    // Traduire les attributs title et aria-label
    const titledElements = document.querySelectorAll('[data-i18n-title]');
    titledElements.forEach(function(el) {
      const key = el.getAttribute('data-i18n-title');
      const translation = translate(key);
      if (translation !== key) {
        el.title = translation;
        if (el.hasAttribute('aria-label')) {
          el.setAttribute('aria-label', translation);
        }
      }
    });

    // Traduire les aria-label
    const ariaLabelElements = document.querySelectorAll('[data-i18n-aria-label]');
    ariaLabelElements.forEach(function(el) {
      const key = el.getAttribute('data-i18n-aria-label');
      const translation = translate(key);
      if (translation !== key) {
        el.setAttribute('aria-label', translation);
      }
    });

    // Traduire les placeholders
    const placeholderElements = document.querySelectorAll('[data-i18n-placeholder]');
    placeholderElements.forEach(function(el) {
      const key = el.getAttribute('data-i18n-placeholder');
      const translation = translate(key);
      if (translation !== key) {
        el.placeholder = translation;
      }
    });
  }

  // Exposer le module
  const module = {
    init: init,
    t: translate,
    translate: translate,
    setLanguage: setLanguage,
    getLanguage: getLanguage,
    getAvailableLanguages: getAvailableLanguages,
    loadTranslations: loadTranslations,
    isFirstLaunch: isFirstLaunch,
    markLanguageChosen: markLanguageChosen,
    translatePage: translatePage,
    DEFAULT_LANGUAGE: DEFAULT_LANGUAGE
  };

  // Exposer globalement
  window.CSI_i18n = module;

  // Raccourci global pour la fonction de traduction
  window.t = translate;

  // Enregistrer dans le registre CSI si disponible
  if (window.CSI && typeof window.CSI.register === 'function') {
    window.CSI.register('i18n', {
      exports: { CSI_i18n: module, t: translate },
      init: init
    });
  } else {
    // Initialiser directement si le registre n'est pas encore chargé
    init();
  }

  // Load pending translations (loaded before i18n module was ready)
  if (window._pendingTranslations) {
    Object.entries(window._pendingTranslations).forEach(function([lang, data]) {
      loadTranslations(lang, data);
    });
    delete window._pendingTranslations;
  }

})();
