(() => {
  if (window.__kir0AutoUploadLoaded) return;
  window.__kir0AutoUploadLoaded = true;

  const LOCAL = 'http://127.0.0.1:8788';
  const state = {
    enabled:false,busy:false,bypass:new WeakSet(),panel:null,status:null,quota:null,
    overlay:null,ring:null,percent:null,title:null,detail:null,eta:null,saveBtn:null,lastFile:null,
    startedAt:0,lastProgress:0
  };
  const sleep = ms => new Promise(r => setTimeout(r, ms));

  function bg(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 || 'kir0Qual request failed'));
      resolve(response);
    }));
  }
  async function account(){ return (await chrome.storage.local.get(['discordSession'])).discordSession || null; }

  function buildPanel(){
    if(!state.enabled){ state.panel?.remove(); state.panel=state.status=state.quota=null; return; }
    if(state.panel?.isConnected) return;
    const p=document.createElement('div'); p.id='kir0-auto-panel';
    p.innerHTML=`<div class="kqa-activeLine"><i></i><b>KIR0QUAL ACTIVE</b></div><div id="kqa-quota" class="kqa-quota">Checking quota…</div><div id="kqa-status" class="kqa-status">Upload normally</div>`;
    document.documentElement.appendChild(p); state.panel=p; state.status=p.querySelector('#kqa-status'); state.quota=p.querySelector('#kqa-quota');
  }
  function setStatus(text,kind=''){ if(!state.enabled)return; buildPanel(); if(state.status){state.status.textContent=text;state.panel.dataset.kind=kind;} }
  function setQuota(text){ if(!state.enabled)return; buildPanel(); if(state.quota)state.quota.textContent=text; }

  async function refreshAccount(){
    const a=await account(); if(!a?.sessionToken){setQuota('Discord not connected');return null;}
    try{const r=await bg('KIR0_SESSION',{sessionToken:a.sessionToken}),s=r.session||{},remaining=Number(s.remaining??s.quotaRemaining??0),limit=Number(s.limit??s.quotaLimit??10);setQuota(`Quota ${remaining}/${limit}`);return {...a,...s};}
    catch(_){setQuota('Discord session expired');return null;}
  }
  async function helperReady(){try{const r=await fetch(LOCAL+'/health',{cache:'no-store'}),j=await r.json();return !!j.localProcessing;}catch(_){return false;}}

  function buildOverlay(){
    if(state.overlay?.isConnected)return;
    const o=document.createElement('div'); o.id='kir0-processing-overlay';
    o.innerHTML=`
      <div class="kqo-card">
        <div class="kqo-brand"><span class="kqo-dot"></span><span>kir0Qual</span></div>
        <div class="kqo-ring" id="kqo-ring"><div class="kqo-ringInner"><strong id="kqo-percent">0%</strong></div></div>
        <div class="kqo-title" id="kqo-title">Preparing video</div>
        <div class="kqo-detail" id="kqo-detail">Starting kir0Qual HQ…</div>
        <div class="kqo-eta" id="kqo-eta">Please keep this tab open</div>
        <div class="kqo-track"><i id="kqo-trackFill"></i></div>
        <button id="kqo-save" class="kqo-save" type="button" hidden>Save optimized copy</button>
        <div class="kqo-warning">Do not close or refresh this tab while kir0Qual is processing.</div>
      </div>`;
    document.documentElement.appendChild(o);
    state.overlay=o; state.ring=o.querySelector('#kqo-ring'); state.percent=o.querySelector('#kqo-percent'); state.title=o.querySelector('#kqo-title'); state.detail=o.querySelector('#kqo-detail'); state.eta=o.querySelector('#kqo-eta'); state.saveBtn=o.querySelector('#kqo-save'); state.trackFill=o.querySelector('#kqo-trackFill');
    state.saveBtn.addEventListener('click',()=>{ if(state.lastFile) saveCopy(state.lastFile); });
  }
  function formatEta(sec){ if(!Number.isFinite(sec)||sec<0)return 'Estimating time remaining…'; sec=Math.ceil(sec); const m=Math.floor(sec/60),s=sec%60; return m?`${m}:${String(s).padStart(2,'0')} remaining`:`0:${String(s).padStart(2,'0')} remaining`; }
  function showProgress(progress,title,detail){
    buildOverlay(); state.overlay.dataset.state='working'; state.saveBtn.hidden=true;
    const p=Math.max(0,Math.min(100,Math.round(progress))); state.lastProgress=p;
    state.percent.textContent=`${p}%`; state.ring.style.setProperty('--progress',`${p*3.6}deg`); state.trackFill.style.width=`${p}%`; state.title.textContent=title; state.detail.textContent=detail;
    if(state.startedAt && p>=3 && p<100){const elapsed=(Date.now()-state.startedAt)/1000;state.eta.textContent=formatEta((elapsed/p)*(100-p));} else state.eta.textContent='Please keep this tab open';
  }
  function showComplete(file){
    buildOverlay(); state.lastFile=file; state.overlay.dataset.state='done'; state.percent.textContent='✓'; state.ring.style.setProperty('--progress','360deg'); state.trackFill.style.width='100%'; state.title.textContent='Optimization complete'; state.detail.textContent='kir0Qual HQ is ready for TikTok'; state.eta.textContent='TikTok is continuing your upload'; state.saveBtn.hidden=false;
    setTimeout(()=>{ if(state.overlay?.dataset.state==='done'){state.overlay.classList.add('kqo-hide');setTimeout(()=>{state.overlay?.remove();state.overlay=null;},420);} },4500);
  }
  function showError(message){buildOverlay();state.overlay.dataset.state='error';state.percent.textContent='!';state.title.textContent='kir0Qual stopped';state.detail.textContent=message;state.eta.textContent='Your original video was not posted by kir0Qual';state.saveBtn.hidden=true;}
  function closeOverlay(){state.overlay?.remove();state.overlay=null;}
  function saveCopy(file){const url=URL.createObjectURL(file),a=document.createElement('a');a.href=url;a.download=file.name;a.style.display='none';document.documentElement.appendChild(a);a.click();a.remove();setTimeout(()=>URL.revokeObjectURL(url),30000);}

  async function prepWithHelper(file){
    state.startedAt=Date.now(); showProgress(1,'Preparing video','Starting kir0Qual HQ encoder…'); setStatus('Preparing HQ encode…','working');
    const start=await fetch(LOCAL+'/api/video/prep-1s-gop/start',{method:'POST',headers:{'Content-Type':'video/mp4'},body:file});
    if(!start.ok)throw new Error((await start.json().catch(()=>null))?.error||'Could not start local encoder');
    const {jobId}=await start.json();
    for(;;){
      await sleep(500); const r=await fetch(`${LOCAL}/api/video/prep-1s-gop/status/${encodeURIComponent(jobId)}`,{cache:'no-store'}),j=await r.json();
      if(!r.ok)throw new Error(j?.error||'Encoder status failed'); if(j.status==='error')throw new Error(j.error||'Encoder failed'); if(j.status==='complete')break;
      const p=Math.max(1,Math.min(96,Math.round(j.progress||0))); showProgress(p,'Encoding video','Quality-first H.264 • 60 FPS • Mobile optimized'); setStatus(`HQ encoding… ${p}%`,'working');
    }
    showProgress(97,'Finalizing video','Applying kir0Method and preparing TikTok upload…'); setStatus('Applying kir0Method…','working');
    const result=await fetch(`${LOCAL}/api/video/prep-1s-gop/result/${encodeURIComponent(jobId)}`,{cache:'no-store'});
    if(!result.ok)throw new Error((await result.json().catch(()=>null))?.error||'Could not retrieve encoded video');
    const prepared=new Uint8Array(await result.arrayBuffer());
    if(!window.KQEngine?.process)throw new Error('kir0Method engine did not load');
    const processed=window.KQEngine.process(prepared),bytes=processed?.bytes||processed;
    if(!(bytes instanceof Uint8Array))throw new Error('kir0Method returned invalid output');
    showProgress(100,'Finalizing video','Handing optimized video back to TikTok…');
    return new File([bytes],file.name.replace(/\.mp4$/i,'')+'_kir0Qual.mp4',{type:'video/mp4',lastModified:Date.now()});
  }

  async function handleInput(input){
    if(!state.enabled||state.busy||state.bypass.has(input))return; const file=input.files?.[0];
    if(!file||(!/video\/mp4/i.test(file.type||'')&&!/\.mp4$/i.test(file.name||'')))return;
    state.busy=true;state.lastFile=null;let reservation=null;
    try{
      const a=await refreshAccount(); if(!a?.sessionToken)throw new Error('Open kir0Qual and connect Discord first');
      if(!(await helperReady()))throw new Error('kir0Qual Engine is not running');
      buildOverlay();showProgress(0,'Checking kir0Qual','Verifying account and quota…');setStatus('Checking quota…','working');
      reservation=await bg('KIR0_QUOTA_RESERVE',{sessionToken:a.sessionToken});
      const optimized=await prepWithHelper(file);
      const dt=new DataTransfer();dt.items.add(optimized);state.bypass.add(input);input.files=dt.files;
      await bg('KIR0_QUOTA_COMMIT',{sessionToken:a.sessionToken,reservationId:reservation.reservationId});reservation=null;
      setStatus('kir0Qual HQ ready — TikTok is uploading','ok');await refreshAccount();
      input.dispatchEvent(new Event('input',{bubbles:true,composed:true}));input.dispatchEvent(new Event('change',{bubbles:true,composed:true}));setTimeout(()=>state.bypass.delete(input),2000);
      showComplete(optimized);
    }catch(err){
      if(reservation){try{const a=await account();if(a?.sessionToken)await bg('KIR0_QUOTA_RELEASE',{sessionToken:a.sessionToken,reservationId:reservation.reservationId});}catch(_){}}
      const msg=err?.message||'kir0Qual failed';setStatus(msg,'error');showError(msg);
    }finally{state.busy=false;}
  }

  function onChange(e){const input=e.target;if(!(input instanceof HTMLInputElement)||input.type!=='file'||state.bypass.has(input))return;const file=input.files?.[0];if(!file)return;const looksVideo=file.type.startsWith('video/')||/\.(mp4|mov|m4v)$/i.test(file.name);if(!looksVideo)return;if(state.enabled){e.stopImmediatePropagation();e.preventDefault();handleInput(input);}}

  chrome.storage.local.get({kir0AutoUploadEnabled:false},r=>{state.enabled=!!r.kir0AutoUploadEnabled;buildPanel();if(state.enabled)refreshAccount();});
  chrome.storage.onChanged.addListener((changes,area)=>{if(area==='local'&&changes.discordSession)refreshAccount();if(area==='local'&&changes.kir0AutoUploadEnabled){state.enabled=!!changes.kir0AutoUploadEnabled.newValue;buildPanel();if(state.enabled){setStatus('Upload normally','');refreshAccount();}else closeOverlay();}});
  document.addEventListener('change',onChange,true);setInterval(refreshAccount,30000);
})();
