(() => {
  const $ = id => document.getElementById(id);
  let file = null;

  const DISCORD_CLIENT_ID = '1537246151709950042';
  const KIR0_GUILD_ID = '1537245984806141992';
  const DISCORD_SCOPE = 'identify';
  const FREE_LIMIT = 10;
  let currentQuotaLimit = FREE_LIMIT;
  let currentResetAt = 0;
  let currentAccessLabel = 'FREE';
  let currentStaffAccess = false;
  let quotaTimer = null;

  const discordRedirect = () => chrome.identity.getRedirectURL('discord');

  function sendBackground(type, payload = {}) {
    return new Promise((resolve, reject) => {
      chrome.runtime.sendMessage({type, ...payload}, response => {
        if (chrome.runtime.lastError) return reject(new Error(chrome.runtime.lastError.message));
        if (!response?.ok) return reject(new Error(response?.error || 'Background request failed.'));
        resolve(response);
      });
    });
  }

  const base64url = buf => {
    let s = '';
    const u = new Uint8Array(buf);
    for (const b of u) s += String.fromCharCode(b);
    return btoa(s).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/,'');
  };
  const randomString = n => {
    const a = new Uint8Array(n);
    crypto.getRandomValues(a);
    return base64url(a);
  };
  async function sha256(text) {
    return crypto.subtle.digest('SHA-256', new TextEncoder().encode(text));
  }

  async function getAccount() {
    return (await chrome.storage.local.get(['discordSession'])).discordSession || null;
  }

  async function saveAccount(account) {
    await chrome.storage.local.set({discordSession: account});
  }

  async function getServerState() {
    const session = await getAccount();
    if (!session?.sessionToken) return null;
    try {
      const result = await sendBackground('KIR0_SESSION', {sessionToken: session.sessionToken});
      if (!result.session) return null;
      await saveAccount({...session, ...result.session});
      return result.session;
    } catch (_) {
      await chrome.storage.local.remove(['discordSession']);
      return null;
    }
  }

  function formatCountdown(resetAt) {
    const ms = Number(resetAt || 0) - Date.now();
    if (!Number.isFinite(ms) || !resetAt) return 'Connect Discord to view reset';
    if (ms <= 0) return 'Refilling now…';
    const totalMinutes = Math.floor(ms / 60000);
    const days = Math.floor(totalMinutes / 1440);
    const hours = Math.floor((totalMinutes % 1440) / 60);
    const minutes = totalMinutes % 60;
    if (days > 0) return `Resets in ${days}d ${hours}h ${minutes}m`;
    if (hours > 0) return `Resets in ${hours}h ${minutes}m`;
    return `Resets in ${Math.max(1, minutes)}m`;
  }

  function formatResetExact(resetAt) {
    if (!resetAt) return '—';
    const d = new Date(Number(resetAt));
    if (Number.isNaN(d.getTime())) return '—';
    return d.toLocaleString([], {
      weekday: 'short',
      day: 'numeric',
      month: 'short',
      hour: 'numeric',
      minute: '2-digit'
    });
  }

  function updateResetClock() {
    const countdown = formatCountdown(currentResetAt);
    const exact = formatResetExact(currentResetAt);
    if ($('quotaResetCountdown')) $('quotaResetCountdown').textContent = countdown;
    if ($('quotaResetExact')) $('quotaResetExact').textContent = currentResetAt ? `Full quota returns • ${exact}` : '—';
    if ($('adminResetCountdown')) $('adminResetCountdown').textContent = countdown.replace('Resets in ', '');
    if ($('adminResetExact')) $('adminResetExact').textContent = exact;
  }

  function renderQuota(remaining, limit = FREE_LIMIT, resetAt = 0, accessLabel = 'FREE', staffAccess = false) {
    const max = Math.max(1, Number(limit || FREE_LIMIT));
    const value = Math.max(0, Math.min(max, Number(remaining ?? 0)));
    currentQuotaLimit = max;
    currentResetAt = Number(resetAt || 0);
    currentAccessLabel = String(accessLabel || 'FREE').toUpperCase();
    currentStaffAccess = !!staffAccess;

    $('quotaUsed').textContent = value;
    if ($('quotaLimit')) $('quotaLimit').textContent = max;
    $('quotaRemaining').textContent = `${value} optimization${value === 1 ? '' : 's'} remaining`;
    $('quotaBar').style.width = `${Math.max(0, Math.min(100, (value / max) * 100))}%`;
    $('discordQuota').textContent = value > 0
      ? `${value} / ${max} weekly optimizations remaining`
      : 'Weekly limit reached';

    if ($('quotaTitle')) $('quotaTitle').textContent = staffAccess ? 'Staff quota' : 'Free quota';
    if ($('quotaAccessPill')) $('quotaAccessPill').textContent = staffAccess ? `${currentAccessLabel} ACCESS` : 'FREE V2';
    document.querySelector('.quotaCard')?.classList.toggle('staffQuota', staffAccess);

    updateResetClock();
    clearInterval(quotaTimer);
    if (currentResetAt) quotaTimer = setInterval(updateResetClock, 30000);
  }

  function setStaffUI(account) {
    const staff = !!account?.staffAccess;
    currentStaffAccess = staff;
    const nav = $('adminNav');
    nav?.classList.toggle('hidden', !staff);
    document.querySelector('.navTabs')?.classList.toggle('adminEnabled', staff);
    if (!staff && !$('adminPage')?.classList.contains('hidden')) showPage('dashboard');
  }

  async function refreshAdminPage(account = null) {
    const state = account || await getServerState();
    if (!state?.staffAccess) return;
    if ($('adminRoleLabel')) $('adminRoleLabel').textContent = state.accessLabel || 'STAFF';
    if ($('adminAccessBadge')) $('adminAccessBadge').textContent = `◆ ${state.accessLabel || 'STAFF'} ACCESS`;
    if ($('adminRemaining')) $('adminRemaining').textContent = state.remaining ?? 0;
    if ($('adminLimit')) $('adminLimit').textContent = state.limit ?? 100;

    const cloudStatus = $('adminCloudStatus');
    const engineStatus = $('adminEngineStatus');
    if (cloudStatus) { cloudStatus.textContent = 'CHECKING…'; cloudStatus.className = ''; }
    if (engineStatus) { engineStatus.textContent = 'CHECKING…'; engineStatus.className = ''; }

    try {
      const cloud = await sendBackground('KIR0_BACKEND_STATUS');
      if (cloudStatus) { cloudStatus.textContent = cloud?.backendConfigured ? 'ONLINE' : 'OFFLINE'; cloudStatus.className = cloud?.backendConfigured ? 'online' : 'offline'; }
    } catch (_) {
      if (cloudStatus) { cloudStatus.textContent = 'OFFLINE'; cloudStatus.className = 'offline'; }
    }

    if (engineStatus) { engineStatus.textContent = 'BROWSER'; engineStatus.className = 'online'; }
    updateResetClock();
  }

  function setMembershipUI(member) {
    const badge = $('membershipBadge');
    const text = $('membershipText');
    const gateText = $('optimizerGateText');
    const gateSub = $('optimizerGateSub');
    if (member) {
      badge.textContent = 'SERVER VERIFIED';
      badge.className = 'membershipBadge verified';
      text.textContent = 'Member of the kir0Qual Discord server';
      gateText.textContent = 'Optimizer unlocked.';
      gateSub.textContent = 'Your Discord membership is verified.';
    } else {
      badge.textContent = 'SERVER REQUIRED';
      badge.className = 'membershipBadge';
      text.textContent = 'Join the kir0Qual Discord server to optimize';
      gateText.textContent = 'Discord membership required.';
      gateSub.textContent = 'Connect Discord after joining the kir0Qual server.';
    }
  }

  async function updateOptimizerAccess() {
    const account = await getServerState();
    const member = !!account?.member;
    const remaining = account ? Number(account.remaining ?? 0) : FREE_LIMIT;
    renderQuota(
      remaining,
      account?.limit ?? FREE_LIMIT,
      account?.resetAt ?? 0,
      account?.accessLabel ?? 'FREE',
      !!account?.staffAccess
    );
    setStaffUI(account);
    const allowed = member && remaining > 0;
    $('optimizerLocked').classList.toggle('hidden', allowed);
    $('optimizerControls').classList.toggle('hidden', !allowed);
    if (!allowed) {
      $('run').disabled = true;
      setStatus(member ? 'WEEKLY LIMIT REACHED' : 'DISCORD MEMBERSHIP REQUIRED');
      setActivityState(member ? 'LIMIT' : 'LOCKED');
    }
    setMembershipUI(member);
  }

  function showPage(page) {
    const optimizer = $('optimizerPage');
    const dashboard = $('dashboardPage');
    const signal = $('signalPage');
    const admin = $('adminPage');
    const tabs = document.querySelectorAll('.navTab');
    if (!optimizer || !dashboard || !signal || !admin) return;

    if (page === 'admin' && !currentStaffAccess) page = 'dashboard';
    const isOptimizer = page === 'optimizer';
    const isSignal = page === 'signal';
    const isAdmin = page === 'admin';
    tabs.forEach(tab => tab.classList.toggle('active', tab.dataset.page === page));
    optimizer.classList.toggle('hidden', !isOptimizer);
    dashboard.classList.toggle('hidden', isOptimizer || isSignal || isAdmin);
    signal.classList.toggle('hidden', !isSignal);
    admin.classList.toggle('hidden', !isAdmin);

    if (isOptimizer) Promise.resolve(updateOptimizerAccess()).catch(() => {});
    if (isAdmin) Promise.resolve(refreshAdminPage()).catch(() => {});
  }

  document.querySelectorAll('.navTab').forEach(btn => {
    btn.addEventListener('click', e => {
      e.preventDefault();
      e.stopPropagation();
      showPage(btn.dataset.page);
    });
  });

  async function discordLogin() {
    const btn = $('discordBtn');
    if ((await getAccount())?.sessionToken) {
      return discordLogout();
    }
    btn.disabled = true;
    btn.textContent = 'CONNECTING…';
    try {
      const verifier = randomString(32);
      const challenge = base64url(await sha256(verifier));
      const redirect = discordRedirect();
      const params = new URLSearchParams({
        client_id: DISCORD_CLIENT_ID,
        response_type: 'code',
        redirect_uri: redirect,
        scope: DISCORD_SCOPE,
        code_challenge: challenge,
        code_challenge_method: 'S256'
      });

      const result = await chrome.identity.launchWebAuthFlow({
        url: 'https://discord.com/oauth2/authorize?' + params.toString(),
        interactive: true
      });
      const u = new URL(result);
      const code = u.searchParams.get('code');
      if (!code) throw new Error('Discord did not return an authorization code.');

      const auth = await sendBackground('KIR0_AUTH_DISCORD', {
        code,
        codeVerifier: verifier,
        redirectUri: redirect
      });

      if (!auth.session) throw new Error('Backend did not return a session.');
      await saveAccount(auth.session);
      renderDiscord(auth.session);
      setMembershipUI(!!auth.session.member);
      renderQuota(auth.session.remaining, auth.session.limit, auth.session.resetAt, auth.session.accessLabel, auth.session.staffAccess);
      setStaffUI(auth.session);
      logEvent(`<strong>Discord connected</strong> — ${auth.session.username}`, 'done');
      if (auth.session.member) logEvent('<strong>Server membership verified</strong> — optimizer unlocked', 'done');
      else logEvent('<strong>Server membership not found</strong> — optimizer remains locked', 'error');
    } catch(e) {
      if (typeof logEvent === 'function') logEvent(`<strong>Discord connection failed</strong> — ${e.message}`, 'error');
    }
    btn.disabled = false;
    btn.textContent = 'CONNECT DISCORD';
    await updateOptimizerAccess();
  }

  function renderDiscord(me) {
    $('discordName').textContent = me.username || 'Connected';
    $('discordBtn').textContent = 'DISCONNECT';
    $('discordBtn').disabled = false;
    $('discordBtn').classList.add('disconnect');

    const avatar = $('discordAvatar');
    const userId = String(me?.userId || me?.id || '');
    const avatarHash = String(me?.avatar || '');

    // Discord custom avatars use the user's ID + avatar hash.
    // Animated avatar hashes begin with "a_" and can be rendered as GIF.
    // If the account has no custom avatar, use Discord's default avatar CDN.
    let avatarUrl = '';
    if (userId && avatarHash) {
      const ext = avatarHash.startsWith('a_') ? 'gif' : 'png';
      avatarUrl = `https://cdn.discordapp.com/avatars/${userId}/${avatarHash}.${ext}?size=128`;
    } else if (userId) {
      let index = 0;
      try {
        // New Discord usernames use (user_id >> 22) % 6 for the default avatar.
        index = Number((BigInt(userId) >> 22n) % 6n);
      } catch (_) {
        index = Number(me?.discriminator || 0) % 5;
      }
      avatarUrl = `https://cdn.discordapp.com/embed/avatars/${index}.png`;
    }

    avatar.style.backgroundImage = avatarUrl ? `url("${avatarUrl}")` : '';
    avatar.style.backgroundSize = avatarUrl ? 'cover' : '';
    avatar.style.backgroundPosition = avatarUrl ? 'center' : '';
    avatar.style.backgroundRepeat = avatarUrl ? 'no-repeat' : '';
    avatar.textContent = avatarUrl ? '' : (me?.username?.[0] || 'K').toUpperCase();
  }

  function renderDisconnected() {
    $('discordName').textContent = 'Not connected';
    $('discordBtn').textContent = 'CONNECT DISCORD';
    $('discordBtn').disabled = false;
    $('discordBtn').classList.remove('disconnect');
    $('discordAvatar').style.backgroundImage = '';
    $('discordAvatar').textContent = 'K';
    $('discordAvatar').style.backgroundSize = '';
    $('discordAvatar').style.backgroundPosition = '';
    setMembershipUI(false);
    renderQuota(FREE_LIMIT, FREE_LIMIT, 0, 'FREE', false);
    setStaffUI(null);
  }

  async function discordLogout() {
    const btn = $('discordBtn');
    const account = await getAccount();
    btn.disabled = true;
    btn.textContent = 'DISCONNECTING…';
    try {
      if (account?.sessionToken) {
        try { await sendBackground('KIR0_LOGOUT', {sessionToken: account.sessionToken}); } catch (_) {}
      }
      await chrome.storage.local.remove(['discordSession']);
      if (chrome.identity?.clearAllCachedAuthTokens) {
        try { await chrome.identity.clearAllCachedAuthTokens(); } catch (_) {}
      }
      renderDisconnected();
      clearActivity();
      logEvent('<strong>Discord disconnected</strong> — account session cleared', 'done');
      showPage('dashboard');
      await updateOptimizerAccess();
    } catch (e) {
      logEvent(`<strong>Disconnect failed</strong> — ${e.message}`, 'error');
      btn.disabled = false;
      btn.textContent = 'DISCONNECT';
    }
  }

  async function restoreDiscord() {
    const account = await getServerState();
    if (account) {
      renderDiscord(account);
      setMembershipUI(!!account.member);
      renderQuota(account.remaining, account.limit, account.resetAt, account.accessLabel, account.staffAccess);
      setStaffUI(account);
    } else {
      await chrome.storage.local.remove(['discordSession']);
      renderDisconnected();
    }
    await updateOptimizerAccess();
  }

  $('discordBtn').addEventListener('click', discordLogin);
  $('adminRefresh')?.addEventListener('click', async () => {
    const btn = $('adminRefresh');
    btn.disabled = true;
    btn.textContent = 'REFRESHING…';
    try {
      const account = await getServerState();
      if (account) {
        renderQuota(account.remaining, account.limit, account.resetAt, account.accessLabel, account.staffAccess);
        setStaffUI(account);
        await refreshAdminPage(account);
      }
    } finally {
      btn.disabled = false;
      btn.textContent = 'REFRESH STATUS ↻';
    }
  });
 document.querySelector('.gateBtn')?.addEventListener('click', e => {
    e.preventDefault();
    e.stopPropagation();
    showPage('dashboard');
  });

  const setStatus = (t,c='') => { $('status').textContent=t; $('status').className='status '+c; };
  let displayedProgress = 0;
  const nextPaint = () => new Promise(resolve => requestAnimationFrame(() => requestAnimationFrame(resolve)));
  const setStage = (t,p,{allowReset=false}={}) => {
    const requested = Math.max(0, Math.min(100, Math.round(Number(p) || 0)));
    if (allowReset) displayedProgress = requested;
    else displayedProgress = Math.max(displayedProgress, requested);
    $('stage').textContent=t;
    $('pct').textContent=displayedProgress+'%';
    $('bar').style.width=displayedProgress+'%';
  };
  const check = (n,txt) => { $(n).textContent='✓ '+txt; $(n).classList.add('done'); };
  function resetChecks(){
    ['c1','c2','c3','c4'].forEach((x,i)=>{
      $(x).textContent='○ '+['Inspect','Rebuild H.264','Apply kir0Method','Validate'][i];
      $(x).classList.remove('done');
    });
  }
  function stamp(){return new Date().toLocaleTimeString([], {hour:'2-digit',minute:'2-digit',second:'2-digit'});}
  function clearActivity(){$('activityList').innerHTML='';}
  function logEvent(message,type=''){
    const list=$('activityList');
    const empty=list.querySelector('.activityEmpty');
    if(empty) empty.remove();
    const row=document.createElement('div'); row.className='logRow '+type;
    const time=document.createElement('span'); time.className='logTime'; time.textContent=stamp();
    const dot=document.createElement('span'); dot.className='logDot';
    const text=document.createElement('span'); text.innerHTML=message;
    row.append(time,dot,text); list.appendChild(row); list.scrollTop=list.scrollHeight;
  }
  function setActivityState(t){$('activityState').textContent=t;}

  // Chrome-native MP4/H.264/AAC preparation.
  // No BAT, CMD, localhost helper, FFmpeg executable, or WASM dependency.

  function load(f){
    if(!f || !f.name.toLowerCase().endsWith('.mp4')){logEvent('Rejected file — MP4 required','error');return;}
    file=f;
    $('name').textContent=f.name;
    $('size').textContent=(f.size/1048576).toFixed(1)+' MB';
    $('source').classList.remove('hidden');
    $('process').classList.remove('hidden');
    $('run').disabled=false;
    $('again').classList.add('hidden');
    setStatus('SOURCE READY • LOCAL ONLY');
    setActivityState('SCANNING');
    clearActivity();
    logEvent(`<strong>Source selected</strong> — ${f.name}`,'active');
    f.arrayBuffer().then(buf=>{
      const i=KQEngine.inspect(new Uint8Array(buf));
      $('video').textContent=(i.videoCodec||'unknown').toUpperCase()+' • '+i.videoSamples.toLocaleString();
      $('audio').textContent=(i.audioCodec||'none').toUpperCase()+' • '+i.audioSamples.toLocaleString();
      $('log').textContent=`FILE\n${f.name}\n${f.size.toLocaleString()} bytes\n\nVIDEO\ncodec: ${i.videoCodec||'unknown'}\nsamples: ${i.videoSamples.toLocaleString()}\n\nAUDIO\ncodec: ${i.audioCodec||'none'}\nsamples: ${i.audioSamples.toLocaleString()}\n\nENGINE\nIndependent engine: ${KQEngine.version || 'kir0Method v4'}`;
      logEvent(`<strong>Source inspected</strong> — ${(i.videoCodec||'unknown').toUpperCase()} / ${(i.audioCodec||'no audio')}`,'done');
      setActivityState('READY');
    }).catch(e=>{
      $('log').textContent='SCAN ERROR: '+e.message;
      $('run').disabled=true;
      setStatus('SOURCE ERROR');
      setActivityState('ERROR');
      logEvent(`<strong>Scan failed</strong> — ${e.message}`,'error');
    });
  }

  $('file').addEventListener('change',e=>load(e.target.files[0]));
  const drop=$('drop');
  ['dragenter','dragover'].forEach(ev=>drop.addEventListener(ev,e=>{e.preventDefault();drop.classList.add('drag');}));
  ['dragleave','drop'].forEach(ev=>drop.addEventListener(ev,e=>{e.preventDefault();drop.classList.remove('drag');}));
  drop.addEventListener('drop',e=>load(e.dataTransfer.files[0]));
  drop.addEventListener('keydown',e=>{if(e.key==='Enter'||e.key===' ')$('file').click();});
  $('clear').onclick=()=>location.reload();
  $('again').onclick=()=>location.reload();

  $('run').onclick=async()=>{
    if(!file)return;
    const account = await getServerState();
    if (!account?.member || Number(account.remaining || 0) <= 0) { await updateOptimizerAccess(); return; }

    let reservation = null;
    try {
      reservation = await sendBackground('KIR0_QUOTA_RESERVE', {sessionToken: account.sessionToken});
      if (!reservation.reservationId) throw new Error('Could not reserve an optimization.');
      renderQuota(reservation.remaining, reservation.limit, reservation.resetAt, reservation.accessLabel, reservation.staffAccess);
    } catch (e) {
      setStatus('QUOTA CHECK FAILED');
      logEvent(`<strong>Quota reservation failed</strong> — ${e.message}`, 'error');
      await updateOptimizerAccess();
      return;
    }

    resetChecks(); displayedProgress=0; setStage('STARTING',0,{allowReset:true}); $('run').disabled=true; setStatus('PROCESSING • BROWSER ONLY','busy'); $('process').classList.remove('hidden'); setActivityState('PROCESSING'); clearActivity(); logEvent('<strong>Optimization started</strong> — kir0Qual V2','active');
    try{
      setStage('READING SOURCE',12); logEvent('Reading original MP4 locally'); check('c1','Inspect'); await new Promise(r=>setTimeout(r,80));
      const originalInput=new Uint8Array(await file.arrayBuffer());
      setStage('BROWSER H.264 PREP',18); logEvent('<strong>Native H.264 prep</strong> — keep this popup open','active');
      const input=await KQBrowserPrep.reencode(file,{
        onProgress:f=>setStage('BROWSER H.264 PREP',18+Math.round(f*47)),
        onLog:m=>logEvent(m)
      });
      setStage('H.264 PREP COMPLETE',66); check('c2','Rebuild H.264 stream'); logEvent('<strong>Playback prep complete</strong> — real ~1s keyframes requested','done');
      await nextPaint();

      setStage('BUILDING KIR0 MP4',74); logEvent('Applying current kir0Method to browser-prepared MP4');
      await nextPaint();
      const result=KQEngine.process(input);
      check('c3','Apply kir0Method'); logEvent('kir0Method transformation complete');

      setStage('VALIDATING OUTPUT',96); logEvent('Running output validation');
      await nextPaint();
      // The current engine's process() call has already parsed/rebuilt the MP4.
      // Only mark validation complete after we have a non-empty MP4 result.
      if (!result?.bytes || result.bytes.length < 8) throw new Error('Output validation failed.');
      check('c4','Validate'); logEvent('<strong>Validation passed</strong> — browser H.264 + kir0Method','done');

      setStage('FINALIZING',98);
      await nextPaint();
      const committed = await sendBackground('KIR0_QUOTA_COMMIT', {sessionToken: account.sessionToken, reservationId: reservation.reservationId});
      reservation = null;
      renderQuota(committed.remaining, committed.limit, committed.resetAt, committed.accessLabel, committed.staffAccess);

      // 100% now means every processing/validation/quota step is finished.
      // Give Chrome a paint before starting the browser download so the UI can
      // never visually remain at 60–90% while a completed file appears.
      setStage('COMPLETE',100);
      setActivityState('COMPLETE');
      setStatus('OPTIMIZATION COMPLETE • STARTING DOWNLOAD','good');
      await nextPaint();

      const blob=new Blob([result.bytes],{type:'video/mp4'}),url=URL.createObjectURL(blob),a=document.createElement('a'); a.href=url; a.download='kir0Qual_optimized.mp4'; document.body.appendChild(a); a.click(); a.remove(); setTimeout(()=>URL.revokeObjectURL(url),10000);
      $('log').textContent+=`\n\nRESULT\nOutput: ${result.bytes.length.toLocaleString()} bytes\nMode: Chrome native H.264/AAC → classic MP4 → kir0Method\nVideo: browser re-encoded for smooth playback\nAudio: browser AAC\nContainer: validated\nValidation: PASS\nWeekly remaining: ${committed.remaining}/${committed.limit || currentQuotaLimit}`;
      setActivityState('COMPLETE'); setStatus('OPTIMIZATION COMPLETE • DOWNLOAD STARTED','good'); logEvent('<strong>Export complete</strong> — kir0Qual_optimized.mp4','done'); $('again').classList.remove('hidden');
    }catch(e){
      if (reservation?.reservationId) {
        try { await sendBackground('KIR0_QUOTA_RELEASE', {sessionToken: account.sessionToken, reservationId: reservation.reservationId}); } catch (_) {}
      }
      await updateOptimizerAccess();
      setStage('FAILED',displayedProgress); $('log').textContent+='\n\nERROR\n'+e.message; $('run').disabled=false; setStatus('NOT EXPORTED • '+e.message.toUpperCase()); setActivityState('ERROR'); logEvent(`<strong>Processing failed</strong> — ${e.message}`,'error');
    }
  };

  // TikTok Auto Upload toggle lives in the extension popup.
  async function renderAutoUploadToggle() {
    const toggle = $('autoUploadToggle');
    const card = document.querySelector('.autoUploadCard');
    const status = $('autoUploadStatus');
    const hint = $('autoUploadHint');
    if (!toggle || !card || !status || !hint) return;
    const r = await chrome.storage.local.get({kir0AutoUploadEnabled:false});
    const enabled = !!r.kir0AutoUploadEnabled;
    toggle.checked = enabled;
    card.classList.toggle('active', enabled);
    status.textContent = enabled ? 'KIR0QUAL ACTIVE' : 'OFF';
    hint.textContent = enabled
      ? 'Upload normally on TikTok Studio.'
      : 'TikTok uploads are untouched.';
  }

  $('autoUploadToggle')?.addEventListener('change', async e => {
    const enabled = !!e.target.checked;
    await chrome.storage.local.set({kir0AutoUploadEnabled:enabled});
    await renderAutoUploadToggle();
  });

  $('openTikTokStudio')?.addEventListener('click', () => {
    chrome.tabs.create({url:'https://www.tiktok.com/tiktokstudio/upload'});
  });

  chrome.storage.onChanged.addListener((changes, area) => {
    if (area === 'local' && changes.kir0AutoUploadEnabled) renderAutoUploadToggle();
  });

  renderAutoUploadToggle();



  // kir0Signal + TikTok site-data reset
  chrome.storage.local.get({kir0SignalEnabled:true}, r => { if ($('signalToggle')) $('signalToggle').checked = !!r.kir0SignalEnabled; });
  $('signalToggle')?.addEventListener('change', async e => {
    await sendBackground('KIR0_SET_SIGNAL', {enabled:e.target.checked});
  });
  $('openTikTok')?.addEventListener('click', () => chrome.tabs.create({url:'https://www.tiktok.com/'}));
  $('clearTikTok')?.addEventListener('click', async () => {
    const btn=$('clearTikTok'), out=$('cacheStatus');
    btn.disabled=true; btn.textContent='CLEARING…'; out.textContent='Resetting TikTok site data…';
    try {
      const r=await sendBackground('KIR0_CLEAR_TIKTOK_DATA');
      out.textContent=`Cleared. Reloaded ${r.reloaded||0} TikTok tab${r.reloaded===1?'':'s'}. Sign in again if needed.`;
    } catch(e) { out.textContent='Reset failed: '+e.message; }
    btn.disabled=false; btn.textContent='CLEAR TIKTOK SITE DATA';
  });

  restoreDiscord();
})();
