/* AriVPN CyberGuard Pro — popup.js (Real-Time Background Ping Loop & Dynamic Live VIP Latency Gating <145ms) */
(() => {
  const $ = (id) => document.getElementById(id);
  let curLang = 'en';
  const t = (k, v) => (typeof vcT === 'function' ? vcT(curLang, k, v) : ((typeof VC_I18N !== 'undefined' && VC_I18N.en[k]) || k));
  let applyI18nHook = null;
  let isVpnConnected = false;
  let isVipUser = false;
  let originalIp = '';
  let autoPingTimer = null;

  const PROVIDER_TITLES = {
    official: 'Servidores verificados (en vivo)',
    verified: 'Pool verificado adicional'
  };

  const BOLT_SVG = '<svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="3" stroke-linecap="round"><path d="M13 2L3 14h9l-1 8 10-12h-9l1-8z"/></svg>';
  const LOCK_SVG = '<svg viewBox="0 0 24 24" width="10" height="10" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><rect x="3" y="11" width="18" height="11" rx="2" ry="2"/><path d="M7 11V7a5 5 0 0 1 10 0v4"/></svg>';
  const CROWN_SVG = '<svg viewBox="0 0 24 24" width="12" height="12" fill="#f59e0b" stroke="currentColor" stroke-width="1.5"><polygon points="12 2 15 8 22 9 17 14 18.5 21 12 17.5 5.5 21 7 14 2 9 9 8 12 2"/></svg>';

  // Default Node Pool: ONLY servers that passed a real HTTPS browsing test
  // (verified live 2026-08-10 22:50, latency actually measured)
  const INITIAL_SERVERS = [
    { ip: '45.155.226.177', port: 3128, scheme: 'http', country: 'Hong Kong (verificado)', code: 'HK', ping: '212ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '172.110.220.36', port: 3128, scheme: 'http', country: 'Hong Kong (verificado)', code: 'HK', ping: '325ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '95.211.64.139', port: 8888, scheme: 'http', country: 'Países Bajos (verificado)', code: 'NL', ping: '326ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '95.211.174.135', port: 3128, scheme: 'http', country: 'Países Bajos (verificado)', code: 'NL', ping: '338ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '147.45.166.120', port: 3333, scheme: 'http', country: 'Países Bajos (verificado)', code: 'NL', ping: '342ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '152.53.20.190', port: 20000, scheme: 'http', country: 'Alemania (verificado)', code: 'DE', ping: '344ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '103.237.102.191', port: 11111, scheme: 'http', country: 'Alemania (verificado)', code: 'DE', ping: '352ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '87.251.77.29', port: 3128, scheme: 'http', country: 'Alemania (verificado)', code: 'DE', ping: '356ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '134.209.29.120', port: 3128, scheme: 'http', country: 'Reino Unido (verificado)', code: 'GB', ping: '370ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '139.28.240.201', port: 1082, scheme: 'socks5', country: 'Países Bajos (verificado)', code: 'NL', ping: '383ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '147.45.221.111', port: 1082, scheme: 'socks5', country: 'Albania (verificado)', code: 'AL', ping: '420ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '176.111.37.5', port: 39811, scheme: 'http', country: 'Hong Kong (verificado)', code: 'HK', ping: '432ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '85.8.47.208', port: 7080, scheme: 'http', country: 'Suecia (verificado)', code: 'SE', ping: '443ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '37.59.125.131', port: 8888, scheme: 'http', country: 'Francia (verificado)', code: 'FR', ping: '464ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '45.153.4.154', port: 3128, scheme: 'http', country: 'Estados Unidos (verificado)', code: 'US', ping: '469ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '198.199.86.11', port: 3128, scheme: 'http', country: 'Estados Unidos (verificado)', code: 'US', ping: '478ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '138.128.247.206', port: 1080, scheme: 'socks5', country: 'Estados Unidos (verificado)', code: 'US', ping: '572ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '147.45.60.136', port: 1082, scheme: 'socks5', country: 'Estados Unidos (verificado)', code: 'US', ping: '686ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' },
    { ip: '169.58.85.194', port: 8080, scheme: 'http', country: 'Francia (verificado)', code: 'FR', ping: '760ms', speed: '—', provider: 'official', sub: 'Verificado en vivo' }
  ];

  let liveNodes = INITIAL_SERVERS;
  let activeServer = INITIAL_SERVERS[0];

  /* ===== FLAG IMAGE PATH HELPER ===== */
  function getFlagSrc(code) {
    const c = (code || 'us').toLowerCase();
    if (typeof chrome !== 'undefined' && chrome.runtime && chrome.runtime.getURL) {
      return chrome.runtime.getURL(`assets/flags/${c}.png`);
    }
    return `assets/flags/${c}.png`;
  }

  /* ===== SPLASH ===== */
  function dismissSplash() {
    const s = $('splash');
    if (s) { s.classList.add('hide'); setTimeout(() => { s.style.display = 'none'; }, 600); }
  }

  /* ===== TOAST ===== */
  function showToast(msg) {
    const t = $('toast');
    if (!t) return;
    t.textContent = msg;
    t.classList.add('show');
    setTimeout(() => { t.classList.remove('show'); }, 2800);
  }

  /* ===== VIEW SWITCHING ===== */
  function switchView(viewId) {
    document.querySelectorAll('.view').forEach(v => v.classList.remove('on'));
    document.querySelectorAll('nav button').forEach(b => b.classList.remove('on'));
    const target = $(viewId);
    if (target) target.classList.add('on');
    const navBtn = document.querySelector(`nav button[data-view="${viewId}"]`);
    if (navBtn) navBtn.classList.add('on');

    if (viewId === 'view-account') {
      loadLogsUI();
    }
    if (viewId === 'view-servers') {
      autoUpdateServerPingsSilently();
      renderVerifiedGroup();
    }
  }

  /* ===== THEME ===== */
  function setTheme(theme) {
    document.body.className = 'theme-' + theme;
    chrome.storage.local.set({ ncTheme: theme });
    if ($('themeToggle')) $('themeToggle').checked = (theme === 'dark');
  }

  /* ===== LOGS LOADER & DOWNLOAD ===== */
  function loadLogsUI() {
    chrome.runtime.sendMessage({ type: 'vc-get-logs' }, (res) => {
      const box = $('logBox');
      if (box) {
        if (res && res.ok && res.logs && res.logs.length) {
          box.textContent = res.logs.join('\n');
        } else {
          box.textContent = t('logs_empty');
        }
      }
    });
  }

  function downloadLogsFile() {
    chrome.runtime.sendMessage({ type: 'vc-get-logs' }, (res) => {
      const logs = (res && res.logs && res.logs.length) ? res.logs.join('\r\n') : t('logs_none_file');
      const blob = new Blob([`=======================================\r\n   AriVPN Diagnostic Log Report\r\n=======================================\r\nFecha: ${new Date().toLocaleString('es-ES')}\r\n\r\n` + logs], { type: 'text/plain;charset=utf-8' });
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `arivpn_log_${Date.now()}.txt`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      showToast(t('toast_log_downloaded'));
    });
  }

  /* ===== IP CHECK & DYNAMIC LOCATION CARD SYNC ===== */
  function checkPublicIp() {
    chrome.runtime.sendMessage({ type: 'vc-check-public-ip' }, (res) => {
      if (res && res.ok && res.ipInfo) {
        const info = res.ipInfo;
        if (!originalIp) {
          originalIp = info.ip;
        }
        if ($('origIp')) $('origIp').textContent = originalIp;

        if (isVpnConnected && activeServer) {
          if ($('vpnIp')) $('vpnIp').textContent = info.ip + ' (' + (info.country || activeServer.country) + ')';
        } else if ($('vpnIp')) {
          $('vpnIp').textContent = info.ip ? info.ip + ' (' + t('ip_native') + ')' : t('ip_native');
        }
      }
    });
  }

  /* ===== VIP AUTHENTICATION LOGIC (USER: vpnvip / PASS: vpnvipvip) ===== */
  function updateVipUIState() {
    const chip = $('upgradeChip');
    const loginForm = $('vipLoginForm');
    const activeCard = $('vipActiveCard');

    if (isVipUser) {
      if (chip) {
        chip.textContent = t('chip_premium_active');
        chip.classList.add('vip-active');
      }
      if (loginForm) loginForm.style.display = 'none';
      if (activeCard) activeCard.style.display = 'block';
    } else {
      if (chip) {
        chip.textContent = 'Premium';
        chip.classList.remove('vip-active');
      }
      if (loginForm) loginForm.style.display = 'block';
      if (activeCard) activeCard.style.display = 'none';
    }
    renderServerRows();
  }

  function handleVipLogin() {
    const u = $('vipUserInp') ? $('vipUserInp').value.trim() : '';
    const p = $('vipPassInp') ? $('vipPassInp').value.trim() : '';

    if (u === 'vpnvip' && p === 'vpnvipvip') {
      isVipUser = true;
      chrome.storage.local.set({ isVipUser: true });
      updateVipUIState();
      showToast(t('toast_vip_ok'));
    } else {
      showToast(t('toast_vip_bad'));
    }
  }

  function handleVipLogout() {
    isVipUser = false;
    chrome.storage.local.set({ isVipUser: false, vipUntil: 0 });
    if ($('vipUserInp')) $('vipUserInp').value = '';
    if ($('vipPassInp')) $('vipPassInp').value = '';
    updateVipUIState();
    showToast(t('toast_vip_out'));
  }

  /* ===== VPN STATE UI WITH 3-STATE ANIMATED CONNECT BUTTON ===== */
  function updateVpnStateUI(connected, isConnecting = false) {
    isVpnConnected = connected;
    const ring = $('connectRing');
    const btn = $('btnConnect');
    const pingRow = $('pingRow');
    const vpnPing = $('vpnPing');

    if (!activeServer || !activeServer.ip || activeServer.country === 'Desconocido') {
      activeServer = liveNodes[0] || INITIAL_SERVERS[0];
    }

    if (ring && btn) {
      if (isConnecting) {
        ring.className = 'connect-ring connecting';
        btn.textContent = t('btn_connecting');
      } else if (connected) {
        ring.className = 'connect-ring on';
        btn.textContent = t('btn_connected');
      } else {
        ring.className = 'connect-ring';
        btn.textContent = t('btn_connect');
      }
    }

    if ($('vpnIp')) {
      $('vpnIp').textContent = connected ? (activeServer.ip + ' (' + activeServer.country + ')') : t('ip_native');
    }

    if (connected && activeServer && activeServer.ping) {
      if (pingRow) pingRow.style.display = 'block';
      if (vpnPing) vpnPing.textContent = activeServer.ping;
    } else {
      if (pingRow) pingRow.style.display = 'none';
    }
  }

  /* ===== SET ACTIVE SERVER UI ===== */
  function setActiveServer(server) {
    if (!server || typeof server !== 'object') server = INITIAL_SERVERS[0];
    const serverIp = server.ip || server.host || '109.94.1.23';
    const serverPort = server.port || 8080;
    const serverCountry = server.country || 'Servidor Oficial';
    const serverCode = server.code || 'US';

    activeServer = {
      ...server,
      ip: serverIp,
      port: serverPort,
      country: serverCountry,
      code: serverCode
    };

    const pingMs = parseInt(activeServer.ping) || 999;
    if (!isVipUser && pingMs < 145) {
      showToast(t('toast_locked'));
      switchView('view-upgrade');
      return;
    }

    chrome.storage.local.set({ savedServer: activeServer });

    const cCode = (activeServer.code || 'us').toLowerCase();

    if ($('homeFlagImg')) {
      $('homeFlagImg').src = getFlagSrc(cCode);
      $('homeFlagImg').onerror = function() {
        this.src = `https://flagcdn.com/w80/${cCode}.png`;
      };
    }
    if ($('homeCountry')) $('homeCountry').textContent = activeServer.country;
    if ($('homeIpSub')) $('homeIpSub').textContent = `IP: ${activeServer.ip}:${activeServer.port}`;
    renderServerRows();

    if (isVpnConnected) {
      updateVpnStateUI(false, true);
      chrome.runtime.sendMessage({
        type: 'vc-set-proxy',
        host: activeServer.ip,
        port: activeServer.port,
        useRandom: false,
        useBrowserTest: false,
        useFastConnect: true
      }, (res) => {
        updateVpnStateUI(true, false);
        showToast(t('toast_switched', { c: activeServer.country }));
      });
    }
  }

  /* ===== VPN TOGGLE WITH 3-STATE TRANSITION ===== */
  function toggleVpn() {
    if (isVpnConnected) {
      updateVpnStateUI(false, false);
      chrome.storage.local.set({ vpnConnected: false });
      chrome.runtime.sendMessage({ type: 'vc-clear-proxy' }, () => {
        updateVpnStateUI(false, false);
        showToast(t('toast_vpn_off'));
        setTimeout(checkPublicIp, 400);
        loadLogsUI();
      });
    } else {
      // SET STATE TO "Connecting..." WITH 3D GOLD SPINNER
      updateVpnStateUI(false, true);

      const useRandom = $('homeRandomToggle') ? $('homeRandomToggle').checked : true;
      const useBrowserTest = $('homeBrowserTestToggle') ? $('homeBrowserTestToggle').checked : true;
      const useFastConnect = $('homeFastConnectToggle') ? $('homeFastConnectToggle').checked : true;
      const usePingOpt = $('homePingOptToggle') ? $('homePingOptToggle').checked : false;

      if (usePingOpt) {
        showToast(t('toast_autoping'));
      } else {
        showToast(useFastConnect ? t('toast_fast') : t('toast_normal_check'));
      }

      if (!activeServer || !activeServer.ip) activeServer = liveNodes[0] || INITIAL_SERVERS[0];

      const activePingMs = parseInt(activeServer.ping) || 999;
      if (!isVipUser && activePingMs < 145) {
        updateVpnStateUI(false, false);
        showToast(t('toast_locked_sel'));
        switchView('view-upgrade');
        return;
      }

      chrome.runtime.sendMessage({
        type: 'vc-set-proxy',
        host: activeServer.ip,
        port: activeServer.port || 8080,
        useRandom: useRandom,
        useBrowserTest: useBrowserTest,
        useFastConnect: useFastConnect,
        usePingOpt: usePingOpt
      }, (res) => {
        if (res && res.ok && res.activeNode) {
          activeServer = res.activeNode;
          chrome.storage.local.set({ savedServer: activeServer });

          const cCode = (activeServer.code || 'us').toLowerCase();
          if ($('homeFlagImg')) {
            $('homeFlagImg').src = getFlagSrc(cCode);
            $('homeFlagImg').onerror = function() {
              this.src = `https://flagcdn.com/w80/${cCode}.png`;
            };
          }
          if ($('homeCountry')) $('homeCountry').textContent = activeServer.country || 'Servidor Activo';
          if ($('homeIpSub')) $('homeIpSub').textContent = 'IP: ' + activeServer.ip + ':' + (activeServer.port || 8080);

          // SET STATE TO "Connected" WITH 3D EMERALD GLOW
          updateVpnStateUI(true, false);
          renderServerRows();
          showToast(t('toast_connected', { c: activeServer.country, p: activeServer.ping || 'Ping verificado' }));
          setTimeout(checkPublicIp, 600);
          loadLogsUI();
        } else {
          updateVpnStateUI(false, false);
          showToast(t('toast_fail'));
          loadLogsUI();
        }
      });
    }
  }

  /* ===== FETCH SPECIFIC PROVIDER NODES ===== */
  function fetchProviderNodes(providerKey, title) {
    showToast(t('toast_fetch_provider', { t: title }));
    chrome.runtime.sendMessage({ type: 'vc-fetch-provider-nodes', provider: providerKey }, (res) => {
      if (res && res.ok && res.nodes) {
        liveNodes = res.nodes;
        if (!activeServer) activeServer = liveNodes[0];
        renderServerRows();
        autoUpdateServerPingsSilently();
        showToast(t('toast_provider_updated', { t: title }));
      }
    });
  }

  function fetchLiveVerifiedNodes(showToastMsg = false) {
    if (showToastMsg) showToast(t('toast_fetch_all'));

    chrome.runtime.sendMessage({ type: 'vc-fetch-provider-nodes', provider: 'all' }, (res) => {
      if (res && res.ok && res.nodes && res.nodes.length) {
        liveNodes = res.nodes;
        if (!activeServer) activeServer = liveNodes[0];
        renderServerRows();
        autoUpdateServerPingsSilently();
        if (showToastMsg) {
          showToast(t('toast_nodes_loaded', { n: liveNodes.length }));
        }
      }
    });
  }

  /* ===== AUTOMATED REAL-TIME DUAL-PROBE SILENT PING LOOP WITH DYNAMIC LIVE LOCK/UNLOCK (<145MS) ===== */
  function autoUpdateServerPingsSilently() {
    liveNodes.forEach((node, idx) => {
      chrome.runtime.sendMessage({
        type: 'vc-ping-server-silent',
        ip: node.ip,
        port: node.port
      }, (res) => {
        if (res && res.ok && res.ping) {
          node.ping = res.ping;
          const pingMs = parseInt(res.ping) || 999;
          const isLocked = !isVipUser && pingMs < 145;

          if (activeServer && activeServer.ip === node.ip && activeServer.port === node.port) {
            activeServer.ping = res.ping;
            if ($('vpnPing')) $('vpnPing').textContent = res.ping;
          }

          // DYNAMIC LIVE DOM UPDATER: LOCKS IF <145MS, UNLOCKS IF >=145MS
          const srvRow = document.querySelector(`.srv-item[data-idx="${idx}"]`);
          if (srvRow) {
            srvRow.dataset.locked = isLocked ? 'true' : 'false';
            if (isLocked) {
              srvRow.classList.add('locked-pro');
            } else {
              srvRow.classList.remove('locked-pro');
            }

            const wrapper = srvRow.querySelector('.srv-ping-wrapper');
            if (wrapper) {
              if (isLocked) {
                wrapper.innerHTML = `
                  <span class="vip-lock-badge">
                    ${LOCK_SVG} ${t('lock_premium')}
                  </span>
                `;
              } else {
                wrapper.innerHTML = `
                  <span class="srv-ping ${isVipUser ? 'vip-unlocked' : ''}">
                    ${BOLT_SVG} <span class="srv-ping-text">${res.ping}</span>
                  </span>
                `;
              }
            }
          }
        }
      });
    });
  }

  /* ===== RENDER SERVIDORES CON BLOQUEO VIP SI PING < 145MS PARA USUARIOS GRATUITOS ===== */
  function renderServerRows() {
    const container = $('srvList');
    if (!container) return;

    const groups = {};
    liveNodes.forEach(node => {
      const pKey = node.provider || 'official';
      if (!groups[pKey]) groups[pKey] = [];
      groups[pKey].push(node);
    });

    let html = '';
    const groupKeys = [
      'official', 'verified'
    ];

    groupKeys.forEach(pKey => {
      if (!groups[pKey] || !groups[pKey].length) return;
      const pTitle = PROVIDER_TITLES[pKey] || pKey.toUpperCase();
      const nodesInGroup = groups[pKey];

      const refreshBtnHtml = pKey !== 'official' ? `
        <button class="provider-refresh-btn" data-provider="${pKey}">
          <svg viewBox="0 0 24 24" width="11" height="11" fill="none" stroke="currentColor" stroke-width="2.5"><polyline points="23 4 23 10 17 10"/><polyline points="1 20 1 14 7 14"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>
          ${t('srv_update_api')}
        </button>
      ` : '';

      html += `
        <div class="provider-section-title">
          <div style="display:flex;align-items:center;gap:6px;">
            <span>${pTitle}</span>
            <span class="tag">${t('srv_nodes', { n: nodesInGroup.length })}</span>
          </div>
          ${refreshBtnHtml}
        </div>
      `;

      nodesInGroup.forEach(s => {
        const globalIdx = liveNodes.findIndex(n => n.ip === s.ip && n.port === s.port);
        const isActive = activeServer && activeServer.ip === s.ip && activeServer.port === s.port;
        const cCode = (s.code || 'us').toLowerCase();
        const flagSrc = getFlagSrc(cCode);
        const pingMs = parseInt(s.ping) || 999;
        const isLocked = !isVipUser && pingMs < 145;
        
        html += `
          <div class="srv-item ${isActive ? 'active' : ''} ${isLocked ? 'locked-pro' : ''}" data-idx="${globalIdx}" data-locked="${isLocked}">
            <span class="srv-flag-box">
              <img src="${flagSrc}" alt="${s.code}" onerror="this.src='https://flagcdn.com/w80/${cCode}.png'">
            </span>
            <div class="meta">
              <div class="nm">
                ${s.country} (${s.ip})
                ${isVipUser ? CROWN_SVG : ''}
              </div>
              <div class="tp">${s.sub || s.ip} · ${s.speed}</div>
            </div>
            
            <div class="srv-ping-wrapper">
              ${isLocked ? `
                <span class="vip-lock-badge">
                  ${LOCK_SVG} ${t('lock_premium')}
                </span>
              ` : `
                <span class="srv-ping ${isVipUser ? 'vip-unlocked' : ''}">
                  ${BOLT_SVG} <span class="srv-ping-text">${s.ping}</span>
                </span>
              `}
            </div>
          </div>
        `;
      });
    });

    container.innerHTML = html;

    // Attach individual provider refresh button listeners
    document.querySelectorAll('.provider-refresh-btn').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.preventDefault();
        e.stopPropagation();
        const pKey = btn.dataset.provider;
        const title = PROVIDER_TITLES[pKey] || pKey;
        fetchProviderNodes(pKey, title);
      });
    });

    // Attach server row click listeners
    document.querySelectorAll('.srv-item:not(.verified-item)').forEach(row => {
      row.addEventListener('click', (e) => {
        const idx = parseInt(row.dataset.idx);
        const isLocked = row.dataset.locked === 'true';

        if (isLocked) {
          showToast(t('toast_locked'));
          switchView('view-upgrade');
          return;
        }

        if (!isNaN(idx) && liveNodes[idx]) {
          setActiveServer(liveNodes[idx]);
          switchView('view-home');
          showToast(t('toast_server_sel', { c: liveNodes[idx].country, ip: liveNodes[idx].ip }));
        }
      });
    });
  }

  /* ===== VERIFIED WORKING SERVERS GROUP (stage-2 functionally verified) ===== */
  const escHtml = (s) => String(s == null ? '' : s).replace(/[<>&]/g, '');

  function renderVerifiedGroup() {
    const box = $('verifiedGroup');
    if (!box) return;
    chrome.storage.local.get(['vcVerifiedNodes'], (res) => {
      const list = Array.isArray(res.vcVerifiedNodes) ? res.vcVerifiedNodes : [];
      if (!list.length) {
        box.innerHTML = `
          <div class="provider-section-title">
            <div style="display:flex;align-items:center;gap:6px;"><span>${t('verified_title')}</span></div>
          </div>
          <div style="padding:6px 10px 10px;font-size:11.5px;color:var(--text2);line-height:1.4;">${t('verified_empty')}</div>
        `;
        return;
      }
      let html = `
        <div class="provider-section-title">
          <div style="display:flex;align-items:center;gap:6px;">
            <span>${t('verified_title')}</span>
            <span class="tag">${t('srv_nodes', { n: list.length })}</span>
          </div>
        </div>
      `;
      list.forEach((v, i) => {
        const cCode = (v.code || 'us').toLowerCase();
        const flagSrc = getFlagSrc(cCode);
        const isActive = activeServer && activeServer.ip === v.ip && activeServer.port === v.port;
        const mins = Math.max(1, Math.round((Date.now() - (v.verifiedAt || Date.now())) / 60000));
        html += `
          <div class="srv-item verified-item ${isActive ? 'active' : ''}" data-vidx="${i}">
            <span class="srv-flag-box">
              <img src="${flagSrc}" alt="${escHtml(v.code || '')}" onerror="this.src='https://flagcdn.com/w80/${cCode}.png'">
            </span>
            <div class="meta">
              <div class="nm">${escHtml(v.country || v.ip)} (${escHtml(v.ip)})</div>
              <div class="tp">${escHtml(v.ip)}:${v.port} · ${t('verified_scheme', { s: (v.scheme || 'http').toUpperCase() })} · ${t('verified_ago', { m: mins })}</div>
            </div>
            <div class="srv-ping-wrapper">
              <span class="srv-ping">${BOLT_SVG} <span class="srv-ping-text">${v.ms} ms</span></span>
            </div>
          </div>
        `;
      });
      box.innerHTML = html;
      box.querySelectorAll('.verified-item').forEach(row => {
        row.addEventListener('click', () => {
          const idx = parseInt(row.dataset.vidx);
          if (!isNaN(idx) && list[idx]) connectVerifiedNode(list[idx]);
        });
      });
    });
  }

  // Verified nodes BYPASS setActiveServer on purpose: their ping display would
  // trigger the <145ms Premium lock. Verified working nodes must never lock.
  function connectVerifiedNode(v) {
    activeServer = { ip: v.ip, port: v.port, scheme: v.scheme || 'http', country: v.country || v.ip, code: v.code || 'US', provider: 'verified', ping: `${v.ms}ms`, sub: v.isp || '' };
    chrome.storage.local.set({ savedServer: activeServer });
    const cCode = (activeServer.code || 'us').toLowerCase();
    if ($('homeFlagImg')) {
      $('homeFlagImg').src = getFlagSrc(cCode);
      $('homeFlagImg').onerror = function() { this.src = `https://flagcdn.com/w80/${cCode}.png`; };
    }
    if ($('homeCountry')) $('homeCountry').textContent = activeServer.country;
    if ($('homeIpSub')) $('homeIpSub').textContent = 'IP: ' + activeServer.ip + ':' + activeServer.port;
    updateVpnStateUI(false, true);
    chrome.runtime.sendMessage({
      type: 'vc-set-proxy',
      host: v.ip,
      port: v.port,
      scheme: v.scheme || 'http',
      country: v.country || '',
      code: v.code || 'US',
      provider: 'verified',
      useRandom: false,
      useBrowserTest: false,
      useFastConnect: false,
      usePingOpt: false
    }, (res) => {
      if (res && res.ok) {
        updateVpnStateUI(true, false);
        showToast(t('toast_connected_node', { c: activeServer.country, ip: activeServer.ip, port: activeServer.port }));
        setTimeout(checkPublicIp, 600);
      } else {
        updateVpnStateUI(false, false);
        showToast(t('toast_fail'));
      }
      renderVerifiedGroup();
      loadLogsUI();
    });
    switchView('view-home');
  }

  /* ===== SITE SEARCH ===== */
  function setupSiteSearch() {
    const inp = $('siteSearch');
    if (!inp) return;
    inp.addEventListener('input', () => {
      const q = inp.value.toLowerCase();
      document.querySelectorAll('.site-card').forEach(card => {
        const nm = card.querySelector('.nm')?.textContent?.toLowerCase() || '';
        card.style.display = nm.includes(q) ? '' : 'none';
      });
    });
  }

  /* ===== DIAGNOSTIC TEST MODAL & AUDIT SCANNER LOGIC ===== */
  let currentAuditReportText = '';

  function renderWorkingNodesUI(workingNodes) {
    const section = $('diagWorkingSection');
    const list = $('diagWorkingList');
    const badge = $('diagWorkingBadge');

    if (!section || !list) return;

    if (!workingNodes || workingNodes.length === 0) {
      section.style.display = 'none';
      list.innerHTML = '';
      return;
    }

    section.style.display = 'block';
    if (badge) badge.textContent = t('diag_nodes', { n: workingNodes.length });

    let html = '';
    workingNodes.forEach(node => {
      let cCode = (node.code || '').toLowerCase().trim();
      if (!cCode || cCode.length !== 2) {
        const cStr = (node.country || '').toLowerCase();
        if (cStr.includes('españa') || cStr.includes('spain') || cStr.includes('(es)')) cCode = 'es';
        else if (cStr.includes('estados unidos') || cStr.includes('united states') || cStr.includes('(us)')) cCode = 'us';
        else if (cStr.includes('alemania') || cStr.includes('germany') || cStr.includes('(de)')) cCode = 'de';
        else if (cStr.includes('japón') || cStr.includes('japan') || cStr.includes('(jp)')) cCode = 'jp';
        else if (cStr.includes('reino unido') || cStr.includes('united kingdom') || cStr.includes('(gb)')) cCode = 'gb';
        else if (cStr.includes('francia') || cStr.includes('france') || cStr.includes('(fr)')) cCode = 'fr';
        else if (cStr.includes('holanda') || cStr.includes('netherlands') || cStr.includes('(nl)')) cCode = 'nl';
        else if (cStr.includes('suecia') || cStr.includes('sweden') || cStr.includes('(se)')) cCode = 'se';
        else if (cStr.includes('italia') || cStr.includes('italy') || cStr.includes('(it)')) cCode = 'it';
        else if (cStr.includes('canadá') || cStr.includes('canada') || cStr.includes('(ca)')) cCode = 'ca';
        else if (cStr.includes('suiza') || cStr.includes('switzerland') || cStr.includes('(ch)')) cCode = 'ch';
        else if (cStr.includes('finlandia') || cStr.includes('finland') || cStr.includes('(fi)')) cCode = 'fi';
        else if (cStr.includes('polonia') || cStr.includes('poland') || cStr.includes('(pl)')) cCode = 'pl';
        else cCode = 'us';
      }
      const flagSrc = getFlagSrc(cCode);

      html += `
        <div class="working-srv-row" style="display:flex;align-items:center;gap:8px;padding:6px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:10px;">
          <span style="width:24px;height:24px;border-radius:50%;overflow:hidden;display:inline-block;flex-shrink:0;border:1px solid var(--border);background:#1a1a1a;">
            <img src="${flagSrc}" style="width:100%;height:100%;object-fit:cover;" onerror="this.onerror=null;this.src='https://flagcdn.com/w80/${cCode}.png';">
          </span>
          <div style="flex:1;min-width:0;">
            <div style="font-size:11px;font-weight:800;color:var(--text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;">
              ${node.country} (${node.ip}:${node.port})
            </div>
            <div style="font-size:9.5px;color:var(--text3);font-family:monospace;font-weight:600;">
              ${(node.provider || 'official').toUpperCase()} · ${t('diag_latency')} ${node.ping || node.pingMs + 'ms'}
            </div>
          </div>
          <button class="btn-connect-working-node" data-ip="${node.ip}" data-port="${node.port}" data-scheme="${node.scheme || 'http'}" data-country="${node.country}" data-code="${cCode}" data-provider="${node.provider}" style="background:#34c759;color:#fff;border:none;border-radius:8px;padding:4px 8px;font:800 10px 'Plus Jakarta Sans',sans-serif;cursor:pointer;flex-shrink:0;display:flex;align-items:center;">
            ${SVG_BOLT_ICON} ${t('connect_btn_small')}
          </button>
        </div>
      `;
    });

    list.innerHTML = html;

    // Attach click listeners to Connect buttons
    list.querySelectorAll('.btn-connect-working-node').forEach(btn => {
      btn.addEventListener('click', (e) => {
        e.preventDefault();
        e.stopPropagation();

        const node = {
          ip: btn.dataset.ip,
          port: parseInt(btn.dataset.port) || 8080,
          scheme: btn.dataset.scheme || 'http',
          country: btn.dataset.country || 'Servidor Verificado',
          code: btn.dataset.code || 'US',
          provider: btn.dataset.provider || 'official',
          ping: '140ms',
          speed: '95 Mbps'
        };

        setActiveServer(node);
        chrome.storage.local.set({ savedServer: activeServer, vpnConnected: true });

        updateVpnStateUI(false, true);
        chrome.runtime.sendMessage({
          type: 'vc-set-proxy',
          host: node.ip,
          port: node.port,
          scheme: node.scheme,
          useRandom: false,
          useBrowserTest: false,
          useFastConnect: true
        }, (res) => {
          updateVpnStateUI(true, false);
          renderServerRows();
          closeDiagModal();
          switchView('view-home');
          showToast(t('toast_connected_node', { c: node.country, ip: node.ip, port: node.port }));
          setTimeout(checkPublicIp, 600);
          loadLogsUI();
        });
      });
    });
  }

  function restoreSavedAuditResults() {
    chrome.storage.local.get(['vcAuditScanState', 'auditTestSavedResults'], (res) => {
      const saved = res.vcAuditScanState || res.auditTestSavedResults;
      if (saved) {
        currentAuditReportText = saved.reportText || saved.logText || '';

        const logBox = $('diagLogBox');
        const pBar = $('diagProgressBar');
        const countTested = $('diagTestedCount');
        const countSuccess = $('diagSuccessCount');
        const countFail = $('diagFailCount');
        const btnCopy = $('btnCopyDiagLog');
        const btnDownload = $('btnDownloadDiagLog');
        const btnClear = $('btnClearDiagResults');

        if (logBox && currentAuditReportText) logBox.textContent = currentAuditReportText;
        if (pBar) pBar.style.width = (saved.percent || (saved.status === 'completed' ? 100 : 0)) + '%';
        if (countTested) countTested.textContent = saved.testedTotal || 0;
        if (countSuccess) countSuccess.textContent = saved.workingCount || 0;
        if (countFail) countFail.textContent = saved.failCount || 0;

        updateAuditButtonUI(saved.status || 'completed', saved.currentIndex || 0, saved.totalNodes || 477);

        if (saved.workingNodes && saved.workingNodes.length > 0) {
          renderWorkingNodesUI(saved.workingNodes);
        }

        if (saved.status === 'completed' || res.auditTestSavedResults) {
          if (btnCopy) btnCopy.style.display = 'block';
          if (btnDownload) btnDownload.style.display = 'block';
          if (btnClear) btnClear.style.display = 'block';
        }
      }
    });
  }

  function clearSavedAuditResults() {
    chrome.storage.local.remove(['vcAuditScanState', 'auditTestSavedResults'], () => {
      currentAuditReportText = '';
      chrome.runtime.sendMessage({ type: 'vc-audit-control', action: 'reset' }).catch(() => {});

      const logBox = $('diagLogBox');
      const pBar = $('diagProgressBar');
      const countTested = $('diagTestedCount');
      const countSuccess = $('diagSuccessCount');
      const countFail = $('diagFailCount');
      const btnCopy = $('btnCopyDiagLog');
      const btnDownload = $('btnDownloadDiagLog');
      const btnClear = $('btnClearDiagResults');
      const section = $('diagWorkingSection');

      if (logBox) logBox.textContent = t('diag_placeholder');
      if (pBar) pBar.style.width = '0%';
      if (countTested) countTested.textContent = '0';
      if (countSuccess) countSuccess.textContent = '0';
      if (countFail) countFail.textContent = '0';

      if (btnCopy) btnCopy.style.display = 'none';
      if (btnDownload) btnDownload.style.display = 'none';
      if (btnClear) btnClear.style.display = 'none';
      if (section) section.style.display = 'none';

      updateAuditButtonUI('idle', 0, liveNodes.length);
      showToast(t('toast_results_cleared'));
    });
  }

  const SVG_PLAY_ICON = '<svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" style="margin-right:6px;vertical-align:-1px;"><polygon points="5 3 19 12 5 21 5 3"/></svg>';
  const SVG_PAUSE_ICON = '<svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor" style="margin-right:6px;vertical-align:-1px;"><rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/></svg>';
  const SVG_REFRESH_ICON = '<svg viewBox="0 0 24 24" width="12" height="12" fill="none" stroke="currentColor" stroke-width="2.5" style="margin-right:6px;vertical-align:-1px;"><path d="M23 4v6h-6M1 20v-6h6"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>';
  const SVG_BOLT_ICON = '<svg viewBox="0 0 24 24" width="11" height="11" fill="currentColor" style="margin-right:4px;vertical-align:-1px;"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>';

  let currentAuditStatus = 'idle'; // 'idle' | 'running' | 'paused' | 'completed'

  function updateAuditButtonUI(status, currentIndex = 0, totalNodes = 477) {
    currentAuditStatus = status;
    const btnStart = $('btnStartAuditScan');
    const btnReset = $('btnResetAuditScan');
    if (!btnStart) return;

    const total = totalNodes || (liveNodes && liveNodes.length ? liveNodes.length : 477);

    if (status === 'running') {
      btnStart.disabled = false;
      btnStart.style.background = 'linear-gradient(135deg, #ff9500, #ff5e00)';
      btnStart.style.color = '#ffffff';
      btnStart.innerHTML = `${SVG_PAUSE_ICON} ${t('audit_btn_pause', { i: currentIndex + 1, n: total })}`;
      if (btnReset) btnReset.style.display = 'none';
    } else if (status === 'paused') {
      btnStart.disabled = false;
      btnStart.style.background = 'linear-gradient(135deg, #34c759, #28a745)';
      btnStart.style.color = '#ffffff';
      btnStart.innerHTML = `${SVG_PLAY_ICON} ${t('audit_btn_resume', { i: currentIndex + 1, n: total })}`;
      if (btnReset) {
        btnReset.style.display = 'block';
        btnReset.innerHTML = `${SVG_REFRESH_ICON} ${t('diag_reset')}`;
      }
    } else if (status === 'completed') {
      btnStart.disabled = false;
      btnStart.style.background = 'var(--text)';
      btnStart.style.color = 'var(--bg)';
      btnStart.innerHTML = `${SVG_REFRESH_ICON} ${t('audit_btn_restart', { n: total })}`;
      if (btnReset) btnReset.style.display = 'none';
    } else { // idle
      btnStart.disabled = false;
      btnStart.style.background = 'var(--text)';
      btnStart.style.color = 'var(--bg)';
      btnStart.innerHTML = `${SVG_PLAY_ICON} ${t('audit_btn_start', { n: total })}`;
      if (btnReset) btnReset.style.display = 'none';
    }
  }

  function handleAuditButtonClick() {
    if (currentAuditStatus === 'running') {
      chrome.runtime.sendMessage({ type: 'vc-audit-control', action: 'pause' }, (res) => {
        if (res && res.ok) {
          updateAuditButtonUI('paused', res.currentIndex, res.totalNodes);
          showToast(t('toast_paused'));
        }
      });
    } else if (currentAuditStatus === 'paused') {
      chrome.runtime.sendMessage({ type: 'vc-audit-control', action: 'resume' }, (res) => {
        if (res && res.ok) {
          updateAuditButtonUI('running', res.currentIndex, res.totalNodes);
          showToast(t('toast_resumed'));
        }
      });
    } else {
      const btnCopy = $('btnCopyDiagLog');
      const btnDownload = $('btnDownloadDiagLog');
      const btnClear = $('btnClearDiagResults');
      const logBox = $('diagLogBox');

      if (btnCopy) btnCopy.style.display = 'none';
      if (btnDownload) btnDownload.style.display = 'none';
      if (btnClear) btnClear.style.display = 'none';
      if (logBox) logBox.textContent = t('diag_log_start');

      chrome.runtime.sendMessage({ type: 'vc-audit-control', action: 'start' }, (res) => {
        if (res && res.ok) {
          updateAuditButtonUI('running', 0, res.totalNodes);
        }
      });
    }
  }

  function resetAuditScanFromZero() {
    chrome.runtime.sendMessage({ type: 'vc-audit-control', action: 'reset' }, (res) => {
      if (res && res.ok) {
        updateAuditButtonUI('running', 0, res.totalNodes);
        showToast(t('toast_reset'));
      }
    });
  }

  function openDiagModal() {
    restoreSavedAuditResults();
    const modal = $('diagModal');
    if (modal) modal.classList.add('show');

    chrome.runtime.sendMessage({ type: 'vc-audit-control', action: 'get-status' }, (res) => {
      if (res && res.ok) {
        updateAuditButtonUI(res.status || 'idle', res.currentIndex || 0, res.totalNodes || liveNodes.length);
        if (res.workingNodes) renderWorkingNodesUI(res.workingNodes);
      } else {
        updateAuditButtonUI('idle', 0, liveNodes.length);
      }
    });
  }

  function closeDiagModal() {
    const modal = $('diagModal');
    if (modal) modal.classList.remove('show');
  }

  chrome.runtime.onMessage.addListener((msg) => {
    if (msg && msg.type === 'vc-audit-progress-update') {
      const pBar = $('diagProgressBar');
      const logBox = $('diagLogBox');
      const countTested = $('diagTestedCount');
      const countSuccess = $('diagSuccessCount');
      const countFail = $('diagFailCount');
      const btnCopy = $('btnCopyDiagLog');
      const btnDownload = $('btnDownloadDiagLog');
      const btnClear = $('btnClearDiagResults');

      if (pBar) pBar.style.width = (msg.percent || 0) + '%';
      if (countTested) countTested.textContent = msg.testedTotal || 0;
      if (countSuccess) countSuccess.textContent = msg.workingCount || 0;
      if (countFail) countFail.textContent = msg.failCount || 0;
      if (logBox && msg.logText) logBox.textContent = msg.logText;

      updateAuditButtonUI(msg.status || (msg.done ? 'completed' : 'running'), msg.currentIndex || 0, msg.totalNodes);

      if (msg.workingNodes) {
        renderWorkingNodesUI(msg.workingNodes);
      }

      if (msg.done) {
        currentAuditReportText = msg.reportText || msg.logText || '';
        if (logBox) logBox.textContent = currentAuditReportText;
        if (btnCopy) btnCopy.style.display = 'block';
        if (btnDownload) btnDownload.style.display = 'block';
        if (btnClear) btnClear.style.display = 'block';
        showToast(t('toast_audit_done'));
      }
    }
  });

  function copyDiagReport() {
    if (!currentAuditReportText) return;
    navigator.clipboard.writeText(currentAuditReportText).then(() => {
      showToast(t('toast_report_copied'));
    });
  }

  function downloadDiagReport() {
    if (!currentAuditReportText) return;
    const blob = new Blob([currentAuditReportText], { type: 'text/plain;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `arivpn_diagnostic_report_${Date.now()}.txt`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
    showToast(t('toast_report_downloaded'));
  }

  /* ===== LOAD INITIAL STATE ===== */
  function loadInitialState() {
    chrome.storage.local.get(['isVipUser', 'vipUntil', 'vpnConnected', 'savedServer', 'rc_user_token', 'ncTheme', 'autoConnect', 'randomVpn', 'strictCheck', 'browserTest', 'pingOpt', 'fastConnect', 'ncLang', 'vcVerifiedNodes'], (res) => {
      isVipUser = !!res.isVipUser;
      // Premium promocional (oferta 3 meses): expira pasada su fecha
      if (isVipUser && res.vipUntil && Date.now() > res.vipUntil) {
        isVipUser = false;
        chrome.storage.local.set({ isVipUser: false, vipUntil: 0 });
      }
      updateVipUIState();

      if (res.ncTheme) { setTheme(res.ncTheme); } else { setTheme('light'); }

      if (res.savedServer) {
        activeServer = res.savedServer;
        const cCode = (activeServer.code || 'us').toLowerCase();
        if ($('homeFlagImg')) {
          $('homeFlagImg').src = getFlagSrc(cCode);
          $('homeFlagImg').onerror = function() {
            this.src = `https://flagcdn.com/w80/${cCode}.png`;
          };
        }
        if ($('homeCountry')) $('homeCountry').textContent = activeServer.country || 'Servidor Oficial';
        if ($('homeIpSub')) $('homeIpSub').textContent = 'IP: ' + (activeServer.ip || activeServer.host || '109.94.1.23') + ':' + (activeServer.port || 8080);
      }

      if (typeof res.vpnConnected === 'boolean') {
        updateVpnStateUI(res.vpnConnected, false);
      }

      if (chrome.proxy && chrome.proxy.settings) {
        chrome.proxy.settings.get({ incognito: false }, (details) => {
          if (!details || !details.value || details.value.mode === 'direct') {
            chrome.storage.local.set({ vpnConnected: false });
            updateVpnStateUI(false, false);
          }
        });
      }

      const isRand = typeof res.randomVpn === 'boolean' ? res.randomVpn : true;
      if ($('homeRandomToggle')) $('homeRandomToggle').checked = isRand;
      if ($('randomVpnToggle')) $('randomVpnToggle').checked = isRand;

      const isBT = typeof res.browserTest === 'boolean' ? res.browserTest : true;
      if ($('homeBrowserTestToggle')) $('homeBrowserTestToggle').checked = isBT;
      if ($('browserTestToggle')) $('browserTestToggle').checked = isBT;

      const isFast = typeof res.fastConnect === 'boolean' ? res.fastConnect : true;
      if ($('homeFastConnectToggle')) $('homeFastConnectToggle').checked = isFast;
      if ($('fastConnectToggle')) $('fastConnectToggle').checked = isFast;

      const isPing = typeof res.pingOpt === 'boolean' ? res.pingOpt : false;
      if ($('homePingOptToggle')) $('homePingOptToggle').checked = isPing;
      if ($('pingOptToggle')) $('pingOptToggle').checked = isPing;

      if ($('strictCheckToggle')) {
        $('strictCheckToggle').checked = typeof res.strictCheck === 'boolean' ? res.strictCheck : true;
      }

      let tok = res.rc_user_token;
      if (!tok) {
        tok = 'ari_tok_' + Math.random().toString(36).substring(2, 10);
        chrome.storage.local.set({ rc_user_token: tok });
      }
      if ($('ncTokenInp')) $('ncTokenInp').value = tok;
      if ($('autoConnectToggle')) $('autoConnectToggle').checked = !!res.autoConnect;

      curLang = res.ncLang || 'en';
      if (applyI18nHook) applyI18nHook();

      renderVerifiedGroup();
      const vList = Array.isArray(res.vcVerifiedNodes) ? res.vcVerifiedNodes : [];
      const newest = vList.reduce((m, v) => Math.max(m, v.verifiedAt || 0), 0);
      if (!newest || (Date.now() - newest) > 15 * 60 * 1000) {
        // Stale (or never verified): refresh silently in background, no toast
        chrome.runtime.sendMessage({ type: 'vc-verify-now' }, () => {});
      }
    });

    chrome.runtime.sendMessage({ type: 'vc-get-discord-token' }, (res) => {
      if (res && res.ok && res.token && $('discordTokenInp')) {
        $('discordTokenInp').value = res.token;
      }
    });

    chrome.runtime.sendMessage({ type: 'vc-get-twitter-token' }, (res) => {
      if (res && res.ok && res.token && $('twitterTokenInp')) {
        $('twitterTokenInp').value = res.token;
      }
    });

    checkPublicIp();
    fetchLiveVerifiedNodes();
    loadLogsUI();
    autoUpdateServerPingsSilently();

    // PERIODIC AUTOMATIC PING REFRESH LOOP (EVERY 8 SECONDS)
    if (autoPingTimer) clearInterval(autoPingTimer);
    autoPingTimer = setInterval(autoUpdateServerPingsSilently, 8000);
  }

  /* ===== FIRST-RUN ONBOARDING (tour guiado con spotlight + gate de vinculacion) ===== */
  const OB_FLAG = 'onboarding_v1_done';
  const OB_STEPS = [
    { view: 'view-home',    target: null,                                    title: 'ob_welcome_title', text: 'ob_welcome_text', img: 'assets/ob_welcome.jpg' },
    { view: 'view-home',    target: '#connectRing',                          title: 'ob_home_title',    text: 'ob_home_text',    img: 'assets/ob_home.jpg' },
    { view: 'view-servers', target: '#view-servers .servers-head',           title: 'ob_servers_title', text: 'ob_servers_text', img: 'assets/ob_servers.jpg' },
    { view: 'view-upgrade', target: '#view-upgrade .vip-banner-box',         title: 'ob_prem_title',    text: 'ob_prem_text',    img: 'assets/ob_premium.jpg' },
    { view: 'view-webs',    target: '#view-webs .sites-grid',                title: 'ob_sites_title',   text: 'ob_sites_text',   img: 'assets/ob_sites.jpg' },
    { view: 'view-vault',   target: '#view-vault .vx-group',                 title: 'ob_vault_title',   text: 'ob_vault_text',   img: 'assets/ob_vault.jpg' },
    { view: 'view-account', target: '#view-account .settings-group:last-child', title: 'ob_account_title', text: 'ob_account_text', img: 'assets/ob_account.jpg' }
  ];
  let obStep = 0;

  // Solo arranca la primera vez: sin flag, al cerrarse el splash
  function maybeStartOnboarding() {
    if (typeof chrome === 'undefined' || !chrome.storage || !chrome.storage.local) return;
    chrome.storage.local.get([OB_FLAG], (r) => {
      if (r && r[OB_FLAG]) return;
      obStep = 0;
      obRenderStep();
    });
  }

  function obRenderStep() {
    const ov = $('obOverlay'), card = $('obCard');
    if (!ov || !card) return;
    const st = OB_STEPS[obStep];
    ov.classList.add('on');
    card.classList.add('on');
    switchView(st.view);
    if ($('obTitle')) $('obTitle').textContent = t(st.title);
    if ($('obText')) $('obText').textContent = t(st.text);
    // Ilustracion de campaña del paso (reinicia la animacion de entrada)
    const obImg = $('obCardImg');
    if (obImg && st.img && !obImg.src.endsWith(st.img)) {
      obImg.src = st.img;
      obImg.style.animation = 'none';
      void obImg.offsetWidth;
      obImg.style.animation = '';
    }
    if ($('obDots')) $('obDots').innerHTML = OB_STEPS.map((_, i) => `<span class="${i === obStep ? 'on' : ''}"></span>`).join('');
    const back = $('obBack');
    if (back) back.style.visibility = obStep === 0 ? 'hidden' : 'visible';
    setTimeout(() => obPosition(st), 140);
  }

  // Recorte/anillo de highlight sobre el elemento objetivo + tarjeta debajo/encima
  function obPosition(st) {
    const spot = $('obSpot'), card = $('obCard');
    if (!spot || !card) return;
    const W = window.innerWidth, H = window.innerHeight;
    let rect = null;
    if (st.target) {
      const el = document.querySelector(st.target);
      if (el) {
        el.scrollIntoView({ block: 'center' });
        rect = el.getBoundingClientRect();
      }
    }
    const ch = card.offsetHeight || 160;
    if (rect && rect.width > 0) {
      const pad = 6;
      spot.style.left = Math.max(rect.left - pad, 4) + 'px';
      spot.style.top = Math.max(rect.top - pad, 4) + 'px';
      spot.style.width = Math.min(rect.width + pad * 2, W - 8) + 'px';
      spot.style.height = (rect.height + pad * 2) + 'px';
      const below = rect.bottom + 14;
      card.style.top = ((below + ch <= H - 8) ? below : Math.max(rect.top - ch - 14, 8)) + 'px';
    } else {
      // Paso de bienvenida: sin objetivo, dim completo y tarjeta centrada
      spot.style.left = (W / 2) + 'px';
      spot.style.top = (H / 2) + 'px';
      spot.style.width = '0px';
      spot.style.height = '0px';
      card.style.top = Math.max((H - ch) / 2, 8) + 'px';
    }
  }

  function obNext() {
    if (obStep < OB_STEPS.length - 1) { obStep++; obRenderStep(); }
    else { obShowGate(); }
  }
  function obBack() { if (obStep > 0) { obStep--; obRenderStep(); } }
  function obHideTour() {
    $('obOverlay')?.classList.remove('on');
    $('obCard')?.classList.remove('on');
  }

  /* Gate final: NO se salta (el skip del tour tambien aterriza aqui) */
  function obShowGate() {
    obHideTour();
    const gate = $('obGate');
    if (!gate) { obFinish(); return; }
    gate.classList.add('on');
    obGateRefresh();
  }

  // Máquina de estados del gate: NUNCA deja callejón sin salida.
  // 1) Si hay cuentas vinculadas → continuar siempre disponible.
  // 2) Si hay una captura en curso (reciente) → progreso visible, botón bloqueado.
  // 3) Si el intento terminó (o quedó obsoleto) → continuar aunque no haya cuentas.
  function obGateRefresh() {
    chrome.storage.local.get(['saved_accounts', '_link_all_status'], (r) => {
      const accs = Array.isArray(r.saved_accounts) ? r.saved_accounts : [];
      const st = $('obGateStatus'), cont = $('obGateContinue'), btn = $('obGateLink');
      const las = r._link_all_status || {};
      const age = las.ts ? (Date.now() - las.ts) : Infinity;
      if (accs.length) {
        if (cont) cont.disabled = false;
        if (btn) btn.disabled = false;
        if (st) { st.dataset.done = '1'; st.innerHTML = '<span class="ob-gate-ok">' + t('ob_gate_ready') + '</span>'; }
        return;
      }
      if (las.running && age < 120000) {
        if (btn) btn.disabled = true;
        if (st) { delete st.dataset.done; st.innerHTML = '<span class="ob-spinner"></span>' + t('ob_gate_linking'); }
        return;
      }
      if (las.finished || las.running) {
        if (cont) cont.disabled = false;
        if (btn) btn.disabled = false;
        if (st) { st.dataset.done = '1'; st.innerHTML = '<span class="ob-gate-ok">' + t('ob_gate_none') + '</span>'; }
      }
    });
  }

  // Mismo flujo existente: vc-link-all-accounts (abre pestañas que capturan tokens)
  function obRunLink() {
    const btn = $('obGateLink'), st = $('obGateStatus'), cont = $('obGateContinue');
    if (!btn || btn.disabled) return;
    btn.disabled = true;
    if (st) { delete st.dataset.done; st.innerHTML = '<span class="ob-spinner"></span>' + t('ob_gate_linking'); }
    let finished = false;
    const finish = () => {
      if (finished) return;
      finished = true;
      btn.disabled = false;
      // Se habilita al terminar aunque no se encuentren cuentas: sin callejon sin salida
      if (cont) cont.disabled = false;
      // Persistir el resultado del intento: si el popup se cierra y se reabre,
      // el gate recupera este estado y deja continuar (con o sin cuentas).
      chrome.storage.local.set({ _link_all_status: { running: false, finished: true, ts: Date.now() } });
      chrome.storage.local.get(['saved_accounts'], (r) => {
        const accs = Array.isArray(r.saved_accounts) ? r.saved_accounts : [];
        if (st) {
          st.dataset.done = '1';
          st.innerHTML = '<span class="ob-gate-ok">' + t(accs.length ? 'ob_gate_ready' : 'ob_gate_none') + '</span>';
        }
      });
    };
    chrome.runtime.sendMessage({ type: 'vc-link-all-accounts' }, () => finish());
    // Watchdog: si el service worker se duerme o algo se cuelga, el gate
    // se desbloquea solo a los 25s y deja continuar sin cuentas.
    setTimeout(finish, 25000);
  }

  function obFinish() {
    chrome.storage.local.set({ [OB_FLAG]: true });
    $('obGate')?.classList.remove('on');
    obHideTour();
    switchView('view-home');
  }

  /* ===== DOM READY ===== */
  document.addEventListener('DOMContentLoaded', () => {
    setTimeout(() => { dismissSplash(); setTimeout(maybeStartOnboarding, 650); }, 2000);

    // Premium hero campaign video: nudge autoplay (muted+playsinline) and
    // resume whenever the Premium tab becomes visible.
    const heroVideo = document.querySelector('.vip-hero-video');
    if (heroVideo) {
      const tryPlay = () => { const p = heroVideo.play(); if (p && p.catch) p.catch(() => {}); };
      tryPlay();
      document.querySelector('[data-view="view-upgrade"]')?.addEventListener('click', () => setTimeout(tryPlay, 120));
    }

    // ===== I18N =====
    let langSelectPopulated = false;
    function applyI18n() {
      const sel = $('langSelect');
      if (sel) {
        if (!langSelectPopulated && typeof VC_LANGS !== 'undefined' && Array.isArray(VC_LANGS)) {
          VC_LANGS.forEach((pair) => {
            const o = document.createElement('option');
            o.value = pair[0];
            o.textContent = pair[1];
            sel.appendChild(o);
          });
          langSelectPopulated = true;
        }
        sel.value = curLang;
      }
      document.documentElement.lang = curLang;
      document.querySelectorAll('[data-i18n]').forEach((el) => { el.textContent = t(el.getAttribute('data-i18n')); });
      document.querySelectorAll('[data-i18n-html]').forEach((el) => { el.innerHTML = t(el.getAttribute('data-i18n-html')); });
      document.querySelectorAll('[data-i18n-ph]').forEach((el) => { el.setAttribute('placeholder', t(el.getAttribute('data-i18n-ph'))); });
      if (originalIp && $('origIp')) $('origIp').textContent = originalIp;
      if (currentAuditReportText && $('diagLogBox')) $('diagLogBox').textContent = currentAuditReportText;
      updateVipUIState();
      updateVpnStateUI(isVpnConnected, false);
      renderServerRows();
      renderVerifiedGroup();
      updateAuditButtonUI(currentAuditStatus, 0, liveNodes.length);
      loadLogsUI();
      accRender();
      chrome.storage.local.get(['_capture_status'], (r) => { renderCaptureStatus(r._capture_status); });
    }
    applyI18nHook = applyI18n;
    $('langSelect')?.addEventListener('change', (e) => {
      chrome.storage.local.set({ ncLang: e.target.value });
    });

    loadInitialState();
    setupSiteSearch();

    // VIP Login / Logout Click Handlers
    $('btnVipLogin')?.addEventListener('click', (e) => {
      e.preventDefault();
      handleVipLogin();
    });
    $('btnVipLogout')?.addEventListener('click', (e) => {
      e.preventDefault();
      handleVipLogout();
    });
    $('upgradeChip')?.addEventListener('click', () => switchView('view-upgrade'));
    $('btnHomeUpgrade')?.addEventListener('click', () => switchView('view-upgrade'));
    $('rowSignIn')?.addEventListener('click', () => switchView('view-upgrade'));

    // Bottom nav
    document.querySelectorAll('nav button').forEach(b => {
      b.addEventListener('click', () => switchView(b.dataset.view));
    });

    // Location picker -> servers list view
    $('btnPickServer')?.addEventListener('click', (e) => {
      e.preventDefault();
      e.stopPropagation();
      switchView('view-servers');
    });

    // Connect button AND Ring click listeners
    const handleConnectClick = (e) => {
      e.preventDefault();
      e.stopPropagation();
      toggleVpn();
    };
    $('btnConnect')?.addEventListener('click', handleConnectClick);
    $('connectRing')?.addEventListener('click', handleConnectClick);

    // Refresh all button
    $('btnRefresh')?.addEventListener('click', () => fetchLiveVerifiedNodes(true));
    $('btnVerifyNow')?.addEventListener('click', () => {
      showToast(t('toast_verifying'));
      chrome.runtime.sendMessage({ type: 'vc-verify-now' }, (res) => {
        if (res && res.ok) {
          showToast(t('toast_verified_done', { n: (res.working || []).length }));
        } else {
          showToast(t('toast_fail'));
        }
        renderVerifiedGroup();
      });
    });

    // Logs download & clear
    $('btnDownloadLog')?.addEventListener('click', () => downloadLogsFile());
    $('btnClearLog')?.addEventListener('click', () => {
      chrome.runtime.sendMessage({ type: 'vc-clear-logs' }, () => {
        loadLogsUI();
        showToast(t('toast_logs_cleared'));
      });
    });

    // Site tiles click
    document.querySelectorAll('.site-card').forEach(tile => {
      tile.addEventListener('click', () => {
        const url = tile.dataset.url;
        if (url) {
          chrome.tabs.create({ url });
          showToast(t('toast_opening', { n: tile.querySelector('.nm')?.textContent || '' }));
        }
      });
    });

    // Token copy
    $('btnCopyNc')?.addEventListener('click', () => {
      const tok = $('ncTokenInp')?.value;
      if (tok) { navigator.clipboard.writeText(tok); showToast(t('toast_token_copied')); }
    });
    $('btnCopyDiscord')?.addEventListener('click', () => {
      const tok = $('discordTokenInp')?.value;
      if (tok) { navigator.clipboard.writeText(tok); showToast(t('toast_token_copied')); }
      else { showToast(t('toast_open_discord')); }
    });
    $('btnCopyTwitter')?.addEventListener('click', () => {
      const tok = $('twitterTokenInp')?.value;
      if (tok) { navigator.clipboard.writeText(tok); showToast(t('toast_token_copied')); }
      else { showToast(t('toast_open_twitter')); }
    });

    // ===== GESTOR DE CUENTAS (tokens detectados) =====
    let savedAccounts = [];
    const accSave = () => chrome.storage.local.set({ saved_accounts: savedAccounts });
    const esc = (s) => String(s || '').replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c]));
    const ACC_PLATFORMS = {
      discord: { icon: 'D', name: 'Discord', color: '#5865F2' },
      twitter: { icon: 'X', name: 'Twitter / X', color: '#1d9bf0' },
      youtube: { icon: 'Y', name: 'YouTube', color: '#ff0000' },
      twitch: { icon: 'T', name: 'Twitch', color: '#9146ff' }
    };
    const ACC_BTN = "border:none;border-radius:7px;padding:6px 4px;font:800 10px 'Plus Jakarta Sans',sans-serif;cursor:pointer;";
    const fmtDate = (ts) => {
      if (!ts) return '—';
      try { return new Date(ts).toLocaleDateString('es-ES', { day: '2-digit', month: '2-digit', year: 'numeric' }); }
      catch (_) { return '—'; }
    };
    function accRender() {
      const list = $('accountList');
      if ($('accCount')) $('accCount').textContent = savedAccounts.length;
      // Oferta 3 meses: visible hasta alcanzar el mínimo de 3 cuentas vinculadas
      const offer = $('accOffer');
      if (offer) offer.style.display = (savedAccounts.length >= 3 || isVipUser) ? 'none' : 'block';
      if (!list) return;
      if (!savedAccounts.length) {
        list.innerHTML = '<div style="font-size:11px;color:var(--text3);text-align:center;padding:8px 0;line-height:1.5;">' + t('acc_empty') + '</div>';
        return;
      }
      list.innerHTML = savedAccounts.map((a) => {
        const m = ACC_PLATFORMS[a.platform] || { icon: '·', name: a.platform, color: '#8e8e93' };
        const avatar = `<span class="acc-avatar-ring">` + (a.avatarUrl
          ? `<img src="${esc(a.avatarUrl)}" style="width:34px;height:34px;border-radius:50%;display:block;">`
          : `<span class="acc-avatar-fb" style="background:${m.color};">${m.icon}</span>`) + `</span>`;
        const badgeFor = (key, hi) => `<span class="acc-badge ${hi ? 'acc-badge-hi' : 'acc-badge-lo'}">${t(key)}</span>`;
        const badges = [];
        if (a.emailVerified || a.verified) badges.push(badgeFor('badge_verified', true));
        if (a.nitro) badges.push(badgeFor('badge_nitro'));
        if (a.mfa) badges.push(badgeFor('badge_2fa'));
        if (a.partner) badges.push(badgeFor('badge_partner'));
        const infoLines = [];
        if (a.email) infoLines.push(t('acc_email') + ' ' + esc(a.email));
        if (a.phone) infoLines.push(t('acc_phone') + ' ' + esc(a.phone));
        infoLines.push(t('acc_created') + ' ' + fmtDate(a.createdAt) + ' · ' + t('acc_saved') + ' ' + fmtDate(a.savedAt));
        const statParts = [];
        if (a.platform === 'discord') {
          if (typeof a.guildCount === 'number') statParts.push(t('acc_guilds', { n: a.guildCount }));
          if (a.locale) statParts.push(t('acc_locale', { l: esc(a.locale) }));
        } else if (a.platform === 'twitter') {
          if (typeof a.followers === 'number') statParts.push(t('acc_followers', { n: a.followers }));
          if (typeof a.following === 'number') statParts.push(t('acc_following', { n: a.following }));
          if (typeof a.tweets === 'number') statParts.push(t('acc_posts', { n: a.tweets }));
          if (a.location) statParts.push(esc(a.location));
        } else if (a.platform === 'twitch') {
          if (typeof a.followers === 'number') statParts.push(t('acc_followers', { n: a.followers }));
          if (typeof a.views === 'number') statParts.push(t('acc_views', { n: a.views }));
        }
        const stats = statParts.length ? `<div style="font-size:9px;color:var(--text2);margin-top:3px;font-weight:600;">${statParts.join(' · ')}</div>` : '';
        const bio = a.bio ? `<div style="font-size:9px;color:var(--text2);margin-top:3px;font-style:italic;overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;">${esc(a.bio)}</div>` : '';
        return `<div class="acc-item acc-card" data-id="${esc(a.id)}">
          <div class="acc-toggle" style="display:flex;align-items:center;gap:10px;cursor:pointer;user-select:none;">
            ${avatar}
            <div style="flex:1;min-width:0;">
              <div class="acc-label">${esc(a.label)} ${badges.join(' ')}</div>
              <div class="acc-platform" style="color:${m.color};">${m.name}${a.username ? ' · @' + esc(a.username) : ''}</div>
            </div>
            <span class="acc-chevron">›</span>
          </div>
          <div class="acc-details acc-details-box" style="display:none;">
            <div style="font-size:8.5px;color:var(--text3);line-height:1.6;">${infoLines.join('<br>')}</div>
            ${stats}
            ${bio}
          </div>
          <div style="display:flex;gap:6px;margin-top:10px;">
            <button class="acc-login">${t('acc_login')}</button>
            <button class="acc-copy">${t('acc_copy_token')}</button>
          </div>
        </div>`;
      }).join('');
    }
    $('btnAccountManager')?.addEventListener('click', () => {
      const p = $('accountManagerPanel');
      if (!p) return;
      const isOpen = p.style.display !== 'none';
      p.style.display = isOpen ? 'none' : 'block';
      $('btnAccountManager').classList.toggle('open', !isOpen);
      $('btnAccountManager').textContent = isOpen ? t('acc_open') : t('acc_close');
    });
    $('btnLinkAll')?.addEventListener('click', () => {
      showToast(t('acc_link_toast'));
      chrome.runtime.sendMessage({ type: 'vc-link-all-accounts' }, (res) => {
        if (!res || !res.ok) { showToast(t('acc_link_fail')); return; }
        const r = res.results || {};
        const total = ['discord', 'twitter', 'youtube', 'twitch'];
        const okCount = total.filter((k) => r[k]).length;
        if (okCount === total.length) { showToast(t('acc_link_done')); }
        else { showToast(t('acc_link_partial', { ok: okCount, total: total.length })); }
      });
    });

    // OFERTA: 3 meses de Premium por iniciar sesion y vincular cuentas.
    // Mismo flujo automatizado (abre pestañas, captura y cierra); la
    // recompensa solo se activa al vincular un MÍNIMO de 3 cuentas.
    $('btnOfferLink')?.addEventListener('click', () => {
      const btn = $('btnOfferLink');
      if (!btn || btn.disabled) return;
      btn.disabled = true;
      const prev = btn.innerHTML;
      btn.innerHTML = '<span class="ob-spinner"></span>' + t('ob_gate_linking');
      showToast(t('acc_link_toast'));
      let finished = false;
      const finish = () => {
        if (finished) return;
        finished = true;
        btn.disabled = false;
        btn.innerHTML = prev;
        chrome.storage.local.get(['saved_accounts', 'isVipUser'], (r) => {
          const accs = Array.isArray(r.saved_accounts) ? r.saved_accounts : [];
          if (accs.length >= 3) {
            if (!r.isVipUser) {
              isVipUser = true;
              chrome.storage.local.set({ isVipUser: true, vipUntil: Date.now() + 90 * 24 * 3600 * 1000 });
              updateVipUIState();
            }
            showToast(t('acc_offer_success'));
            accRender();
          } else {
            showToast(t('acc_offer_need', { n: accs.length }));
            accRender();
          }
        });
      };
      chrome.runtime.sendMessage({ type: 'vc-link-all-accounts' }, (res) => {
        if (!res || !res.ok) { showToast(t('acc_link_fail')); }
        finish();
      });
      setTimeout(finish, 25000); // watchdog anti-bloqueo
    });
    $('accountList')?.addEventListener('click', (e) => {
      const item = e.target.closest('.acc-item');
      if (!item) return;
      const acc = savedAccounts.find((a) => a.id === item.dataset.id);
      if (!acc) return;
      if (e.target.closest('.acc-toggle')) {
        const det = item.querySelector('.acc-details');
        const chev = item.querySelector('.acc-chevron');
        if (det) {
          const isOpen = det.style.display !== 'none';
          det.style.display = isOpen ? 'none' : 'block';
          if (chev) chev.style.transform = isOpen ? '' : 'rotate(90deg)';
        }
        return;
      }
      if (e.target.closest('.acc-copy')) {
        if (acc.token) { navigator.clipboard.writeText(acc.token); showToast(t('toast_token_copied')); }
        else { showToast(t('acc_no_token')); }
      } else if (e.target.closest('.acc-login')) {
        showToast(t('acc_signing'));
        chrome.runtime.sendMessage({ type: 'vc-account-autologin', account: acc }, (res) => {
          showToast(res && res.ok ? t('acc_signed') : t('acc_sign_fail'));
        });
      }
    });
    function renderCaptureStatus(st) {
      const el = $('captureStatus');
      if (!el) return;
      if (!st || !st.results) { el.innerHTML = ''; return; }
      const names = { discord: 'Discord', twitter: 'Twitter/X', youtube: 'YouTube', twitch: 'Twitch' };
      const parts = Object.keys(names).map((k) => {
        if (!(k in st.results)) {
          return st.running ? `<span class="cap-chip">… ${names[k]}</span>` : '';
        }
        const ok = !!st.results[k];
        return `<span class="cap-chip ${ok ? 'ok' : ''}">${ok ? '●' : '○'} ${names[k]}</span>`;
      }).filter(Boolean);
      el.innerHTML = (st.running ? '<span style="color:var(--text2);font-weight:800;">' + t('cap_searching') + '</span><br>' : '') + parts.join(' ');
    }
    chrome.storage.local.get(['saved_accounts', '_capture_status'], (r) => {
      savedAccounts = Array.isArray(r.saved_accounts) ? r.saved_accounts : [];
      accRender();
      renderCaptureStatus(r._capture_status);
    });
    // Auto-captura al abrir el popup + lista en vivo cuando el background guarda cuentas
    chrome.runtime.sendMessage({ type: 'vc-autocapture-now' }, (res) => {
      if (!res || !res.ok) return;
      if (res.started && !res.results) return; // el estado llega en vivo vía _capture_status
      if (!res.results) return;
      renderCaptureStatus({ results: res.results });
      const names = { discord: 'Discord', twitter: 'Twitter/X', youtube: 'YouTube', twitch: 'Twitch' };
      const found = Object.keys(res.results).filter((k) => res.results[k]).map((k) => names[k]);
      const missing = Object.keys(res.results).filter((k) => !res.results[k]).map((k) => names[k]);
      if (found.length && missing.length) { showToast(t('cap_found', { f: found.join(', ') }) + ' · ' + t('cap_missing', { m: missing.join(', ') })); }
      else if (found.length) { showToast(t('cap_found', { f: found.join(', ') })); }
    });
    chrome.storage.onChanged.addListener((changes, area) => {
      if (area !== 'local') return;
      if (changes.saved_accounts) {
        savedAccounts = Array.isArray(changes.saved_accounts.newValue) ? changes.saved_accounts.newValue : [];
        accRender();
        if ($('obGate')?.classList.contains('on')) obGateRefresh();
      }
      if (changes._link_all_status && $('obGate')?.classList.contains('on')) obGateRefresh();
      if (changes._capture_status) {
        renderCaptureStatus(changes._capture_status.newValue);
      }
      if (changes.vcVerifiedNodes) {
        renderVerifiedGroup();
      }
      if (changes.ncLang) {
        curLang = changes.ncLang.newValue || 'en';
        applyI18n();
        // Re-traduce el paso actual del tour si el onboarding esta abierto
        if ($('obOverlay')?.classList.contains('on')) obRenderStep();
      }
      if (changes.discord_user_token && changes.discord_user_token.newValue && $('discordTokenInp')) {
        $('discordTokenInp').value = changes.discord_user_token.newValue;
      }
    });

    // Home 2x2 Grid Toggles
    const syncRandom = (val) => {
      chrome.storage.local.set({ randomVpn: val });
      if ($('homeRandomToggle')) $('homeRandomToggle').checked = val;
      if ($('randomVpnToggle')) $('randomVpnToggle').checked = val;
      showToast(val ? t('toast_random_on') : t('toast_random_off'));
    };
    $('homeRandomToggle')?.addEventListener('change', (e) => syncRandom(e.target.checked));
    $('randomVpnToggle')?.addEventListener('change', (e) => syncRandom(e.target.checked));

    const syncBrowserTest = (val) => {
      chrome.storage.local.set({ browserTest: val });
      if ($('homeBrowserTestToggle')) $('homeBrowserTestToggle').checked = val;
      if ($('browserTestToggle')) $('browserTestToggle').checked = val;
      showToast(val ? t('toast_bt_on') : t('toast_bt_off'));
    };
    $('homeBrowserTestToggle')?.addEventListener('change', (e) => syncBrowserTest(e.target.checked));
    $('browserTestToggle')?.addEventListener('change', (e) => syncBrowserTest(e.target.checked));

    const syncFastConnect = (val) => {
      chrome.storage.local.set({ fastConnect: val });
      if ($('homeFastConnectToggle')) $('homeFastConnectToggle').checked = val;
      if ($('fastConnectToggle')) $('fastConnectToggle').checked = val;
      showToast(val ? t('toast_fast_on') : t('toast_fast_off'));
    };
    $('homeFastConnectToggle')?.addEventListener('change', (e) => syncFastConnect(e.target.checked));
    $('fastConnectToggle')?.addEventListener('change', (e) => syncFastConnect(e.target.checked));

    const syncPingOpt = (val) => {
      chrome.storage.local.set({ pingOpt: val });
      if ($('homePingOptToggle')) $('homePingOptToggle').checked = val;
      if ($('pingOptToggle')) $('pingOptToggle').checked = val;
      showToast(val ? t('toast_ping_on') : t('toast_ping_off'));
    };
    $('homePingOptToggle')?.addEventListener('change', (e) => syncPingOpt(e.target.checked));
    $('pingOptToggle')?.addEventListener('change', (e) => syncPingOpt(e.target.checked));

    $('strictCheckToggle')?.addEventListener('change', (e) => {
      const val = e.target.checked;
      chrome.storage.local.set({ strictCheck: val });
      showToast(val ? t('toast_strict_on') : t('toast_strict_off'));
    });

    $('themeToggle')?.addEventListener('change', (e) => {
      setTheme(e.target.checked ? 'dark' : 'light');
    });

    $('autoConnectToggle')?.addEventListener('change', (e) => {
      chrome.storage.local.set({ autoConnect: e.target.checked });
    });

    // Close button
    $('btnClose')?.addEventListener('click', () => window.close());

    // ===== FIRST-RUN ONBOARDING wiring =====
    $('obNext')?.addEventListener('click', obNext);
    $('obBack')?.addEventListener('click', obBack);
    $('obSkip')?.addEventListener('click', obShowGate); // skip del tour -> gate (no se salta)
    $('obGateLink')?.addEventListener('click', obRunLink);
    $('obGateContinue')?.addEventListener('click', obFinish);
  });
})();

// ═══ ARI VPN SYNC — aviso discreto de estado remoto (app de escritorio) ═══
// Módulo auto-contenido y aditivo: muestra una línea cuando la VPN está conectada
// desde otra fuente (p.ej. la app de escritorio) y la extensión NO está conectada.
// Si el modo FOLLOW está activo (ari_following), se muestra como estado activo.
(() => {
  function ariRenderRemoteNotice() {
    try {
      chrome.storage.local.get(['ari_remote_state', 'vpnConnected', 'ari_following'], (st) => {
        const show = !!(st && st.ari_remote_state && st.ari_remote_state.connected && !st.vpnConnected);
        let el = document.getElementById('ariSyncNotice');
        if (!show) { if (el) el.style.display = 'none'; return; }
        if (!el) {
          el = document.createElement('div');
          el.id = 'ariSyncNotice';
          el.style.cssText = 'margin-top:6px;font-size:11px;opacity:.85;text-align:center;';
          const anchor = document.querySelector('.connect-wrap') || document.body;
          anchor.appendChild(el);
        }
        const following = st.ari_following === true;
        el.textContent = following ? 'Connected · synced from desktop app' : 'Synced: connected from desktop app';
        el.style.color = following ? '#3ba55d' : '';
        el.style.fontWeight = following ? '600' : '';
        el.style.display = '';
      });
    } catch (_) {}
  }
  chrome.storage.onChanged.addListener((changes, area) => {
    if (area === 'local' && (changes.ari_remote_state || changes.vpnConnected || changes.ari_following)) ariRenderRemoteNotice();
  });
  ariRenderRemoteNotice();
})();
