/**
 * 247ChatMate — Frontend Language Controller (v1.1.50)
 * Loads widget-ui + sales-demo-chips JSON before the intro plays.
 * Keeps one global language source for bubbles, labels, buttons and chips.
 */
(function () {
  'use strict';

  var cfg = window.MATEWA_LANGUAGE || {};
  var baseUrl = String(cfg.baseUrl || '').replace(/\/$/, '') + '/';
  var fallbackLang = normaliseLang(cfg.fallbackLang || 'en-gb');
  var storageKey = '247chatmate_lang';
  var manualStorageKey = '247chatmate_lang_manual';
  var ready = false;
  var languageMap = null;
  var currentLang = normaliseLang(cfg.currentLang || fallbackLang);
  var currentUi = {};
  var currentChips = {};
  var canonicalChips = {};
  var chipLookup = {};
  var pendingLoaderText = '';
  var loaderMinimumMs = 120;
  var jsonCache = {};
  var retryDelayMs = 180;
  var lastLoadWasUserTriggered = false;
  var showSelector = isSelectorEnabled(cfg.showSelector);
  var configuredDefaultLang = normaliseLang(cfg.defaultLang || 'auto');
  var configuredSiteLang = normaliseLang(cfg.siteLang || cfg.homeLang || '');
  var configuredHomeLang = normaliseLang(cfg.homeLang || cfg.siteLang || '');
  var allowBrowserLanguage = cfg.allowBrowserLanguage === true || String(cfg.allowBrowserLanguage || '') === '1';
  var verifiedFlagFiles = {};
  var visibleLangs = parseVisibleLangs(cfg.visibleLangs || '');
  var suppressResetLanguageRestore = false;
  var originalSiteLanguage = '';

  window.MATEWA_LANGUAGE_READY = false;
  window.MATEWA_I18N = window.MATEWA_I18N || {};
  window.matewa_get_i18n_label = function (key) {
    return (window.MATEWA_I18N && window.MATEWA_I18N[key]) ? window.MATEWA_I18N[key] : '';
  };

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }

  function init() {
    var widget = document.getElementById('matewa-widget');
    if (!widget || !baseUrl) {
      markReady();
      return;
    }

    originalSiteLanguage = resolveOriginalSiteLanguage(widget);
    enforceSelectorVisibility();

    widget.classList.add('matewa-lang-loading');
    showLoader(widget);

    widget.addEventListener('matewa:reset', function (evt) {
      var reason = evt && evt.detail ? evt.detail.reason : '';
      if (reason === 'languageChanged' || reason === 'languageHardResetComplete' || suppressResetLanguageRestore) return;

      // Hard reset must clear manual visitor language first, then rebuild the
      // widget in the same language a brand-new visit would use. Stop the
      // immediate reset broadcast so flow/intro do not replay in the old language.
      if (evt && typeof evt.stopImmediatePropagation === 'function') {
        evt.stopImmediatePropagation();
      }

      clearStoredLanguageState();
      currentLang = '';
      currentUi = {};
      currentChips = {};
      canonicalChips = {};
      chipLookup = {};
      ready = false;
      window.MATEWA_LANGUAGE_READY = false;
      window.MATEWA_SELECTED_LANGUAGE = null;
      window.MATEWA_I18N = {};

      var target = languageMap ? chooseSiteDefaultLanguage(widget) : fallbackLang;
      loadLanguage(target, false, true).then(function () {
        widget.__matewaFlowStarted = false;
        if (typeof window.__matewaRestoreIntro === 'function') {
          window.__matewaRestoreIntro();
        }
        widget.dispatchEvent(new CustomEvent('matewa:languageReady', {
          detail: { language: currentLang, replay: true, reset: true }
        }));
        widget.dispatchEvent(new CustomEvent('matewa:reset', {
          detail: { reason: 'languageHardResetComplete', language: currentLang }
        }));
      });
    }, true);

    loadJson(baseUrl + 'languages.json')
      .then(function (map) {
        languageMap = validateLanguageMap(map);
        var selected = chooseInitialLanguage(widget);
        return loadLanguage(selected, false);
      })
      .catch(function () {
        return loadLanguage(fallbackLang, false);
      });
  }


  function isSelectorEnabled(value) {
    if (window.MATEWA_DISABLE_LANGUAGE_SELECTOR === true) return false;
    if (value === false || value === 0) return false;
    var text = String(value == null ? '0' : value).trim().toLowerCase();
    return !(text === '' || text === '0' || text === 'false' || text === 'no' || text === 'off');
  }

  function removeLanguageSelector() {
    var widget = document.getElementById('matewa-widget');
    var root = widget || document;
    Array.prototype.forEach.call(root.querySelectorAll('.matewa-lang-switcher'), function (node) {
      node.parentNode && node.parentNode.removeChild(node);
    });
    if (widget) widget.classList.add('matewa-language-selector-disabled');
  }

  function enforceSelectorVisibility() {
    showSelector = isSelectorEnabled(cfg.showSelector);
    if (showSelector) return;
    removeLanguageSelector();
    var header = document.querySelector('#matewa-widget .matewa-header');
    if (!header || !window.MutationObserver) return;
    var observer = new MutationObserver(function () { removeLanguageSelector(); });
    observer.observe(header, { childList: true, subtree: false });
  }

  function validateLanguageMap(map) {
    return (map && typeof map === 'object' && !Array.isArray(map)) ? map : {};
  }

  function normaliseLang(value) {
    return String(value || '')
      .trim()
      .toLowerCase()
      .replace('_', '-');
  }

  function baseLang(value) {
    return normaliseLang(value).split('-')[0] || '';
  }

  function parseVisibleLangs(value) {
    var out = {};
    String(value || '').split(',').forEach(function (part) {
      var code = normaliseLang(part);
      if (code) out[code] = true;
    });
    return out;
  }

  function hasVisibleLangFilter() {
    return visibleLangs && Object.keys(visibleLangs).length > 0;
  }

  function isVisibleAllowed(code) {
    code = normaliseLang(code);
    if (!code) return false;
    if (!hasVisibleLangFilter()) return true;
    return !!visibleLangs[code];
  }

  function firstVisibleLanguage() {
    if (!hasVisibleLangFilter() || !languageMap) return '';
    var keys = Object.keys(languageMap);
    for (var i = 0; i < keys.length; i++) {
      var code = normaliseLang(keys[i]);
      if (visibleLangs[code]) return code;
    }
    return '';
  }

  function hasLanguage(code) {
    code = normaliseLang(code);
    return !!(languageMap && languageMap[code]);
  }

  function resolveAvailableLanguage(code) {
    code = normaliseLang(code);
    var visibleFallback = firstVisibleLanguage();
    var aliases = {
      'en': 'en-gb',
      'en-in': 'en-gb',
      'en-au': 'en-gb',
      'en-ca': 'en-us',
      'pt-br': 'pt-br',
      'zh': 'zh-cn',
      'zh-hans': 'zh-cn',
      'zh-hant': 'zh-tw'
    };

    if (hasLanguage(code) && isVisibleAllowed(code)) return code;
    if (aliases[code] && hasLanguage(aliases[code]) && isVisibleAllowed(aliases[code])) return aliases[code];
    if (baseLang(code) === 'pt' && /br/.test(code) && hasLanguage('pt-br') && isVisibleAllowed('pt-br')) return 'pt-br';
    if (baseLang(code) === 'zh' && /tw|hk|hant/.test(code) && hasLanguage('zh-tw') && isVisibleAllowed('zh-tw')) return 'zh-tw';
    if (hasLanguage(baseLang(code)) && isVisibleAllowed(baseLang(code))) return baseLang(code);
    if (visibleFallback) return visibleFallback;
    if (hasLanguage(fallbackLang)) return fallbackLang;
    return 'en-gb';
  }

  function resolveOriginalSiteLanguage(widget) {
    var htmlLang = normaliseLang(document.documentElement && document.documentElement.getAttribute('lang'));
    var bodyLang = normaliseLang(document.body && (
      document.body.getAttribute('data-home-language') ||
      document.body.getAttribute('data-site-language') ||
      document.body.getAttribute('lang')
    ));
    var browserLang = allowBrowserLanguage ? normaliseLang((navigator.languages && navigator.languages[0]) || navigator.language) : '';
    var siteLang = configuredHomeLang || configuredSiteLang;

    // Hard reset must behave like a fresh visit, not like the last visitor choice.
    // Priority: dashboard fixed default is handled outside this function; Auto uses
    // WordPress website/home locale first, then page/html language, then browser
    // only when explicitly enabled, then final fallback.
    return siteLang || bodyLang || htmlLang || browserLang || fallbackLang;
  }

  function clearStoredLanguageState() {
    try {
      localStorage.removeItem(storageKey);
      localStorage.removeItem(manualStorageKey);
      sessionStorage.removeItem(storageKey);
      sessionStorage.removeItem(manualStorageKey);
      localStorage.removeItem('247chatmate_selected_language');
      sessionStorage.removeItem('247chatmate_selected_language');
      localStorage.removeItem('matewa_active_language');
      sessionStorage.removeItem('matewa_active_language');
      localStorage.removeItem('matewa_widget_language');
      sessionStorage.removeItem('matewa_widget_language');
    } catch (e) {}
  }

  function chooseInitialLanguage(widget) {
    var saved = '';
    var manual = false;
    try {
      saved = normaliseLang(localStorage.getItem(storageKey));
      manual = String(localStorage.getItem(manualStorageKey) || '') === '1';
    } catch (e) {}
    var siteLang = originalSiteLanguage || resolveOriginalSiteLanguage(widget);
    // Initial visit: honour a previous manual choice only if that language is still visible.
    // Auto follows resolveOriginalSiteLanguage(), which deliberately ignores
    // previous active widget language and uses site/page language instead.
    if (manual && saved && isVisibleAllowed(resolveAvailableLanguage(saved))) return resolveAvailableLanguage(saved);
    if (configuredDefaultLang && configuredDefaultLang !== 'auto') return resolveAvailableLanguage(configuredDefaultLang);
    return resolveAvailableLanguage(siteLang || fallbackLang);
  }

  function chooseSiteDefaultLanguage(widget) {
    var siteLang = originalSiteLanguage || resolveOriginalSiteLanguage(widget);
    if (configuredDefaultLang && configuredDefaultLang !== 'auto') return resolveAvailableLanguage(configuredDefaultLang);
    return resolveAvailableLanguage(siteLang || fallbackLang);
  }

  function loadJson(url, attempts) {
    attempts = attempts || 2;
    if (jsonCache[url]) return jsonCache[url];

    jsonCache[url] = tryFetchJson(url).catch(function (err) {
      delete jsonCache[url];
      if (attempts > 1) {
        return wait(retryDelayMs).then(function () { return loadJson(url, attempts - 1); });
      }
      throw err;
    });

    return jsonCache[url];
  }

  function tryFetchJson(url) {
    var controller = window.AbortController ? new AbortController() : null;
    var timer = controller ? setTimeout(function () { controller.abort(); }, 3000) : null;
    return fetch(url, {
      method: 'GET',
      credentials: 'same-origin',
      cache: 'default',
      signal: controller ? controller.signal : undefined
    }).then(function (res) {
      if (!res || !res.ok) throw new Error('bad_response');
      return res.json();
    }).finally(function () {
      if (timer) clearTimeout(timer);
    });
  }

  function wait(ms) {
    return new Promise(function (resolve) { setTimeout(resolve, ms); });
  }

  function loadLanguage(code, userTriggered, resetTriggered) {
    lastLoadWasUserTriggered = !!userTriggered;
    ready = false;
    window.MATEWA_LANGUAGE_READY = false;
    var widget = document.getElementById('matewa-widget');
    code = resolveAvailableLanguage(code);

    var meta = (languageMap && languageMap[code]) ? languageMap[code] : {
      code: code,
      nativeName: code,
      ui: 'widget-ui/' + code + '.json',
      chips: 'sales-demo-chips/' + code + '.json',
      rtl: false
    };

    if (widget) {
      widget.classList.add('matewa-lang-loading');
      showLoader(widget, meta);
    }

    var startTime = Date.now();

    return Promise.all([
      loadJson(baseUrl + (meta.ui || ('widget-ui/' + code + '.json'))),
      loadJson(baseUrl + (meta.chips || ('sales-demo-chips/' + code + '.json'))),
      loadJson(baseUrl + 'sales-demo-chips/en-gb.json')
    ]).then(function (parts) {
      currentLang = code;
      currentUi = normaliseUi(parts[0] || {});
      currentChips = (parts[1] && parts[1].chips) ? parts[1].chips : {};
      canonicalChips = (parts[2] && parts[2].chips) ? parts[2].chips : {};
      chipLookup = buildChipLookup(currentChips, canonicalChips);
      window.MATEWA_I18N = currentUi;
      window.MATEWA_SELECTED_LANGUAGE = meta;

      if (userTriggered) {
        try {
          localStorage.setItem(storageKey, code);
          localStorage.setItem(manualStorageKey, '1');
        } catch (e) {}
      }

      applyLanguage(meta, userTriggered);
      renderSelector(meta);

      var wait = Math.max(0, loaderMinimumMs - (Date.now() - startTime));
      setTimeout(markReady, wait);
    }).catch(function (err) {
      if (window.console && console.warn) console.warn('247ChatMate language load failed for', code, err);
      var widget = document.getElementById('matewa-widget');
      if (widget) {
        widget.classList.add('matewa-lang-loading');
        showLoader(widget, meta, true);
      }
    });
  }

  function normaliseUi(ui) {
    var out = {};
    Object.keys(ui || {}).forEach(function (key) {
      out[key] = ui[key];
    });

    var aliases = {
      'phone.label': 'phone.prompt',
      'contact.label': 'contact.prompt',
      'contact.name': 'contact.name_placeholder',
      'contact.email': 'contact.email_placeholder',
      'cta.now': 'cta.chat_now',
      'cta.later': 'cta.chat_later'
    };

    Object.keys(aliases).forEach(function (from) {
      var to = aliases[from];
      if (out[from] && !out[to]) out[to] = out[from];
      if (out[to] && !out[from]) out[from] = out[to];
    });

    if (!out['phone.mobile_only_hint']) out['phone.mobile_only_hint'] = out['phone.placeholder'] || 'Mobile number';
    if (!out['contact.optional']) out['contact.optional'] = 'Optional';
    if (!out['close.aria_label']) out['close.aria_label'] = 'Close chat';
    if (!out['launcher.aria_label']) out['launcher.aria_label'] = out['launcher.text'] || 'Open chat';

    return out;
  }

  function t(key, fallback) {
    return currentUi[key] || fallback || '';
  }

  function applyLanguage(meta, userTriggered) {
    var widget = document.getElementById('matewa-widget');
    var wrapper = document.getElementById('matewa-wrapper');
    if (!widget) return;

    widget.setAttribute('data-widget-language', currentLang);
    if (wrapper) wrapper.setAttribute('dir', meta && meta.rtl ? 'rtl' : 'ltr');

    setText('#matewa-header-title', t('header.title', 'Chat with us'));
    setAttr('.matewa-close', 'aria-label', t('close.aria_label', 'Close chat'));
    setAttr('#matewa-launcher', 'aria-label', t('launcher.aria_label', 'Open chat'));

    var intro = widget.querySelector('.matewa-intro');
    if (intro) {
      var bubbles = intro.querySelectorAll('.matewa-bubble');
      if (bubbles[0]) bubbles[0].textContent = t('intro.line_1', t('system.intro', bubbles[0].textContent));
      if (bubbles[1]) bubbles[1].textContent = t('intro.line_2', t('system.reassurance', bubbles[1].textContent));
    }

    updateTemplate('matewa-task-intent-template', function (node) {
      var bubble = node.querySelector('.matewa-bubble');
      if (bubble) bubble.textContent = t('intro.line_3', t('system.instruction', bubble.textContent));
      translateChipButtons(node);
    });

    updateTemplate('matewa-task-notes-template', function (node) {
      setNodeText(node.querySelector('.matewa-bubble'), t('notes.label', 'Add a note (optional)'));
      setNodeAttr(node.querySelector('.matewa-notes-textarea'), 'placeholder', t('notes.placeholder', 'Anything helpful we should know?'));
      setNodeAttr(node.querySelector('.matewa-notes-textarea'), 'aria-label', t('notes.label', 'Add a note (optional)'));
    });

    updateTemplate('matewa-task-phone-template', function (node) {
      setNodeText(node.querySelector('.matewa-bubble'), t('phone.prompt', t('phone.label', 'What is the best mobile number for you?')));
      setNodeAttr(node.querySelector('.matewa-phone-input'), 'placeholder', t('phone.placeholder', 'Mobile number'));
      setNodeAttr(node.querySelector('.matewa-phone-input'), 'aria-label', t('phone.placeholder', 'Mobile number'));
      setNodeText(node.querySelector('.matewa-char-counter'), t('phone.mobile_only_hint', t('phone.placeholder', 'Mobile number')));
    });

    updateTemplate('matewa-task-contact-template', function (node) {
      setNodeText(node.querySelector('.matewa-bubble'), t('contact.prompt', t('contact.label', 'A few final details help us reply properly.')));
      setNodeAttr(node.querySelector('.matewa-contact-name'), 'placeholder', t('contact.name_placeholder', t('contact.name', 'Full name')));
      setNodeAttr(node.querySelector('.matewa-contact-name'), 'aria-label', t('contact.name_placeholder', t('contact.name', 'Full name')));
      setNodeAttr(node.querySelector('.matewa-contact-email'), 'placeholder', t('contact.email_placeholder', t('contact.email', 'Email address')));
      setNodeAttr(node.querySelector('.matewa-contact-email'), 'aria-label', t('contact.email_placeholder', t('contact.email', 'Email address')));
      var hints = node.querySelectorAll('.matewa-soft-hint');
      Array.prototype.forEach.call(hints, function (hint) { hint.textContent = t('contact.optional', 'Optional'); });
    });

    translateChipButtons(widget);
    translateLiveTasks(widget);

    if (userTriggered) {
      widget.dispatchEvent(new CustomEvent('matewa:languageChanged', { detail: { language: currentLang } }));
    }
  }

  function translateLiveTasks(root) {
    var notes = root.querySelector('.matewa-notes-textarea');
    if (notes) {
      notes.placeholder = t('notes.placeholder', notes.placeholder);
      notes.setAttribute('aria-label', t('notes.label', notes.getAttribute('aria-label') || ''));
    }
    var phone = root.querySelector('.matewa-phone-input');
    if (phone) {
      phone.placeholder = t('phone.placeholder', phone.placeholder);
      phone.setAttribute('aria-label', t('phone.placeholder', phone.getAttribute('aria-label') || ''));
    }
    var name = root.querySelector('.matewa-contact-name');
    if (name) {
      name.placeholder = t('contact.name_placeholder', t('contact.name', name.placeholder));
      name.setAttribute('aria-label', name.placeholder);
    }
    var email = root.querySelector('.matewa-contact-email');
    if (email) {
      email.placeholder = t('contact.email_placeholder', t('contact.email', email.placeholder));
      email.setAttribute('aria-label', email.placeholder);
    }
  }

  function updateTemplate(id, fn) {
    var tpl = document.getElementById(id);
    if (!tpl || !tpl.content || !tpl.content.firstElementChild) return;
    fn(tpl.content.firstElementChild);
  }

  function translateChipButtons(root) {
    var buttons = root.querySelectorAll ? root.querySelectorAll('.matewa-chip[data-intent]') : [];
    Array.prototype.forEach.call(buttons, function (btn) {
      var intent = String(btn.getAttribute('data-intent') || '');
      var span = btn.querySelector('.matewa-chip-label') || btn;
      var original = String(btn.getAttribute('data-chip-label') || (span ? span.textContent : '') || '').trim();
      var label = resolveChipLabel(intent, btn, span);
      btn.classList.remove('matewa-chip-translation-missing');
      if (label) {
        span.textContent = label;
      } else if (original && baseLang(currentLang) === 'en') {
        // English labels are only allowed while an English locale is active.
        span.textContent = original;
      } else {
        // Never silently fall back to English for a selected non-English language.
        span.textContent = '';
        btn.classList.add('matewa-chip-translation-missing');
        if (window.console && console.warn) console.warn('247ChatMate missing chip translation', currentLang, intent || original);
      }
    });
  }

  function buildChipLookup(translated, canonical) {
    var lookup = {};
    translated = translated || {};
    canonical = canonical || {};

    Object.keys(translated).forEach(function (key) {
      var value = translated[key];
      if (!value) return;
      addChipLookup(lookup, key, value);
      addChipLookup(lookup, slugifyIntent(key), value);
      addChipLookup(lookup, value, value);

      if (canonical[key]) {
        addChipLookup(lookup, canonical[key], value);
        addChipLookup(lookup, slugifyIntent(canonical[key]), value);
      }
    });

    Object.keys(canonical).forEach(function (key) {
      if (translated[key]) return;
      if (baseLang(currentLang) === 'en') addChipLookup(lookup, canonical[key], canonical[key]);
    });

    // Canonical aliases used by older vertical configs and admin shortcuts.
    var aliasMap = {
      'quote': 'get_a_quote',
      'pricing': 'pricing',
      'availability': 'availability',
      'other': 'something_else',
      'something_else': 'something_else',
      'mortgage_broker': 'mortgage_quote',
      'mortgage_quote': 'mortgage_quote',
      'buy_to_let': 'buy_to_let',
      'first_time_buyer': 'first_time_buyer',
      'affordability_check': 'affordability_check',
      'remortgage': 'remortgage'
    };
    Object.keys(aliasMap).forEach(function (from) {
      var to = aliasMap[from];
      var label = translated[to] || translated[from] || '';
      if (!label && baseLang(currentLang) === 'en') {
        label = canonical[to] || canonical[from] || '';
      }
      if (label) addChipLookup(lookup, from, label);
    });

    return lookup;
  }

  function addChipLookup(lookup, key, value) {
    key = normaliseChipKey(key);
    if (key && value && !lookup[key]) lookup[key] = value;
  }

  function normaliseChipKey(value) {
    return slugifyIntent(String(value || '').replace(/^intent\./, ''));
  }

  function resolveChipLabel(intent, btn, span) {
    var candidates = [];
    function push(value) {
      value = String(value || '').trim();
      if (value) candidates.push(value);
    }

    push(intent);
    if (btn) {
      push(btn.getAttribute('data-chip-key'));
      push(btn.getAttribute('data-key'));
      push(btn.getAttribute('aria-label'));
      push(btn.getAttribute('title'));
    }
    if (span) push(span.textContent);

    candidates.forEach(function (value) {
      var clean = String(value || '').replace(/^intent\./, '');
      push(clean.replace(/-/g, '_'));
      push(clean.replace(/_/g, ' '));
    });

    for (var i = 0; i < candidates.length; i++) {
      var raw = String(candidates[i] || '').trim().replace(/^intent\./, '');
      var key = normaliseChipKey(raw);
      if (currentChips[raw]) return currentChips[raw];
      if (chipLookup[raw]) return chipLookup[raw];
      if (chipLookup[key]) return chipLookup[key];
      if (currentChips[key]) return currentChips[key];
    }

    return '';
  }

  function slugifyIntent(value) {
    return String(value || '')
      .trim()
      .toLowerCase()
      .replace(/&/g, ' and ')
      .replace(/[^a-z0-9]+/g, '_')
      .replace(/^_+|_+$/g, '');
  }

  function renderSelector(selected) {
    var header = document.querySelector('#matewa-widget .matewa-header');
    if (!header) return;

    var existing = header.querySelector('.matewa-lang-switcher');
    showSelector = isSelectorEnabled(cfg.showSelector);
    if (!showSelector) { removeLanguageSelector(); return; }
    if (!languageMap) return;
    if (existing) existing.remove();

    var wrap = document.createElement('div');
    wrap.className = 'matewa-lang-switcher';

    var button = document.createElement('button');
    button.type = 'button';
    button.className = 'matewa-lang-button';
    button.setAttribute('aria-haspopup', 'listbox');
    button.setAttribute('aria-expanded', 'false');
    button.innerHTML = flagHtml(selected) + '<span class="matewa-lang-name">' + escapeHtml(selected.nativeName || selected.englishName || selected.code || currentLang) + '</span><span class="matewa-lang-caret" aria-hidden="true">▾</span>';

    var menu = document.createElement('div');
    menu.className = 'matewa-lang-menu';
    menu.setAttribute('role', 'listbox');
    menu.hidden = true;

    Object.keys(languageMap).forEach(function (code) {
      if (hasVisibleLangFilter() && !visibleLangs[normaliseLang(code)]) return;
      var item = languageMap[code];
      var opt = document.createElement('button');
      opt.type = 'button';
      opt.className = 'matewa-lang-option';
      opt.setAttribute('role', 'option');
      opt.setAttribute('data-lang', item.code || code);
      opt.setAttribute('aria-selected', (item.code || code) === currentLang ? 'true' : 'false');
      opt.innerHTML = flagHtml(item) + '<span class="matewa-lang-option-name">' + escapeHtml(item.nativeName || item.englishName || code) + '</span>'; 
      opt.addEventListener('click', function () {
        closeMenu();
        loadLanguage(item.code || code, true);
      });
      menu.appendChild(opt);
    });

    button.addEventListener('click', function (e) {
      e.stopPropagation();
      var isOpen = !menu.hidden;
      if (isOpen) closeMenu(); else openMenu();
    });

    document.addEventListener('click', closeMenu, { once: true });

    function openMenu() {
      menu.hidden = false;
      button.setAttribute('aria-expanded', 'true');
      setTimeout(function () {
        document.addEventListener('click', closeMenu, { once: true });
      }, 0);
    }

    function closeMenu() {
      menu.hidden = true;
      button.setAttribute('aria-expanded', 'false');
    }

    wrap.appendChild(button);
    wrap.appendChild(menu);
    header.insertBefore(wrap, header.querySelector('.matewa-close'));
    attachFlagValidation(wrap);
  }

  function attachFlagValidation(scope) {
    Array.prototype.forEach.call((scope || document).querySelectorAll('img.matewa-lang-flag[data-matewa-flag-path]'), function (img) {
      img.addEventListener('error', function () {
        var path = img.getAttribute('data-matewa-flag-path') || '';
        if (window.console && console.warn) console.warn('247ChatMate missing flag SVG:', path);
        var emoji = img.getAttribute('data-matewa-flag-emoji') || '';
        if (emoji) {
          var fallback = document.createElement('span');
          fallback.className = 'matewa-lang-emoji';
          fallback.setAttribute('aria-hidden', 'true');
          fallback.textContent = emoji;
          img.parentNode && img.parentNode.replaceChild(fallback, img);
        }
      }, { once: true });
    });
  }

  function flagHtml(item) {
    item = item || {};
    var file = item.flag || item.flagFile || '';
    var code = normaliseLang(item.code || '');
    if (file && /^[A-Za-z0-9_.-]+\.svg$/.test(file)) {
      var path = baseUrl + 'flags/' + file;
      verifiedFlagFiles[path] = true;
      return '<img class="matewa-lang-flag" src="' + escapeAttr(path) + '" alt="" aria-hidden="true" loading="eager" decoding="async" data-matewa-flag-path="' + escapeAttr(path) + '" data-matewa-flag-emoji="' + escapeAttr(item.flagEmoji || emojiForLanguage(code)) + '">';
    }
    if (window.console && console.warn) {
      console.warn('247ChatMate language has no flag SVG file in languages.json:', code || item);
    }
    var emoji = item.flagEmoji ? item.flagEmoji : emojiForLanguage(code);
    return '<span class="matewa-lang-emoji" aria-hidden="true">' + escapeHtml(emoji) + '</span>';
  }

  function emojiForLanguage(code) {
    var map = {
      'en-gb':'🇬🇧','en':'🇬🇧','en-us':'🇺🇸','tr':'🇹🇷','cs':'🇨🇿','pt-br':'🇧🇷','pt':'🇵🇹','hi':'🇮🇳','ar':'🇦🇪','es':'🇪🇸','fr':'🇫🇷','de':'🇩🇪','af':'🇿🇦','bg':'🇧🇬','bn':'🇧🇩','da':'🇩🇰','el':'🇬🇷','fa':'🇮🇷','fi':'🇫🇮','he':'🇮🇱','hr':'🇭🇷','hu':'🇭🇺','id':'🇮🇩','it':'🇮🇹','ja':'🇯🇵','ko':'🇰🇷','mr':'🇮🇳','ms':'🇲🇾','nl':'🇳🇱','no':'🇳🇴','pa':'🇮🇳','pl':'🇵🇱','ro':'🇷🇴','ru':'🇷🇺','sk':'🇸🇰','sl':'🇸🇮','sr':'🇷🇸','sv':'🇸🇪','sw':'🇰🇪','ta':'🇮🇳','te':'🇮🇳','th':'🇹🇭','uk':'🇺🇦','ur':'🇵🇰','vi':'🇻🇳','zh':'🇨🇳','zh-cn':'🇨🇳','zh-hk':'🇭🇰','zh-tw':'🇹🇼'
    };
    return map[normaliseLang(code)] || '🏳️';
  }

  function loadingTextFor(meta) {
    var code = normaliseLang(meta && meta.code);
    var name = meta && (meta.nativeName || meta.englishName || meta.code) ? (meta.nativeName || meta.englishName || meta.code) : '';
    var map = {
      'tr': name + ' hazırlanıyor…',
      'es': 'Preparando ' + name + '…',
      'pt-br': 'Preparando ' + name + '…',
      'pt': 'A preparar ' + name + '…',
      'fr': 'Préparation du ' + name + '…',
      'de': name + ' wird vorbereitet…',
      'it': 'Preparazione ' + name + '…',
      'cs': 'Připravuje se ' + name + '…',
      'hi': name + ' तैयार हो रही है…',
      'ar': 'جارٍ إعداد ' + name + '…',
      'zh-cn': '正在准备' + name + '…',
      'zh-tw': '正在準備' + name + '…',
      'ja': name + 'を準備中…',
      'ko': name + ' 준비 중…'
    };
    return map[code] || (name ? (name + '…') : '…');
  }

  function showLoader(widget, meta, failed) {
    if (!widget) return;
    var loader = widget.querySelector('.matewa-lang-loader');
    var name = meta && (meta.nativeName || meta.englishName || meta.code) ? (meta.nativeName || meta.englishName || meta.code) : '';
    pendingLoaderText = failed ? 'Language is taking longer than expected…' : loadingTextFor(meta);

    if (!loader) {
      loader = document.createElement('div');
      loader.className = 'matewa-lang-loader';
      loader.setAttribute('aria-live', 'polite');
      loader.innerHTML = '<div class="matewa-lang-loader-card"><span class="matewa-lang-spinner"></span><span class="matewa-lang-loader-text"></span></div>';
      widget.appendChild(loader);
    }

    var text = loader.querySelector('.matewa-lang-loader-text');
    if (text) text.textContent = pendingLoaderText;
  }

  function hideLoader() {
    var widget = document.getElementById('matewa-widget');
    if (!widget) return;
    widget.classList.remove('matewa-lang-loading');
    var loader = widget.querySelector('.matewa-lang-loader');
    if (loader) loader.remove();
  }

  function markReady() {
    var wasReady = ready;
    var shouldReplayFlow = !!lastLoadWasUserTriggered;
    lastLoadWasUserTriggered = false;

    ready = true;
    window.MATEWA_LANGUAGE_READY = true;
    hideLoader();

    var widget = document.getElementById('matewa-widget');
    if (widget) {
      // Fire every time, not just the first page load. This keeps the flow,
      // bubbles and chips locked to the selected language.
      widget.dispatchEvent(new CustomEvent('matewa:languageReady', {
        detail: { language: currentLang, replay: shouldReplayFlow, initial: !wasReady }
      }));

      // On manual language selection, replay the widget from the beginning so
      // intro bubbles + chips are both rebuilt from the selected JSON files.
      if (shouldReplayFlow) {
        suppressResetLanguageRestore = true;
        widget.__matewaFlowStarted = false;
        if (typeof window.__matewaRestoreIntro === 'function') {
          window.__matewaRestoreIntro();
        }
        widget.dispatchEvent(new CustomEvent('matewa:reset', {
          detail: { reason: 'languageChanged', language: currentLang }
        }));
        setTimeout(function () { suppressResetLanguageRestore = false; }, 0);
      }
    }
  }

  function setText(selector, value) {
    var el = document.querySelector(selector);
    if (el && value) el.textContent = value;
  }

  function setAttr(selector, attr, value) {
    var el = document.querySelector(selector);
    if (el && value) el.setAttribute(attr, value);
  }

  function setNodeText(el, value) {
    if (el && value) el.textContent = value;
  }

  function setNodeAttr(el, attr, value) {
    if (el && value) el.setAttribute(attr, value);
  }

  function escapeHtml(value) {
    return String(value || '').replace(/[&<>"']/g, function (c) {
      return ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' })[c];
    });
  }

  function escapeAttr(value) {
    return escapeHtml(value);
  }
})();
