const jobs = new Map();

chrome.runtime.onMessage.addListener((msg, sender, reply) => {
  if (msg?.type === 'FETCH_IMAGE_DATA') {
    fetch(msg.url,{credentials:'include'}).then(async r=>{
      if(!r.ok)throw new Error('HTTP '+r.status);const blob=await r.blob(),bytes=new Uint8Array(await blob.arrayBuffer());
      let binary='';for(let i=0;i<bytes.length;i+=0x8000)binary+=String.fromCharCode(...bytes.subarray(i,i+0x8000));
      reply({ok:true,data:`data:${blob.type||'image/png'};base64,${btoa(binary)}`});
    }).catch(e=>reply({ok:false,error:e.message}));return true;
  }
  if (msg?.type === 'START_JOB') {
    const jobId = crypto.randomUUID();
    const job = {...msg.job, jobId, sourceTabId: sender.tab.id, createdAt: Date.now()};
    chrome.tabs.create({url: job.url, active: true}, tab => {
      job.aiTabId = tab.id;
      jobs.set(tab.id, job);
      chrome.storage.session.set({['job_' + tab.id]: job});
      reply({ok: true, jobId});
    });
    return true;
  }
  if (msg?.type === 'START_SHOPEE_JOB') {
    const jobId = crypto.randomUUID();
    const job = {...msg.job, jobId, mode: 'shopee-sku', sourceTabId: sender.tab.id, createdAt: Date.now()};
    chrome.storage.session.set({shopee_active_job: job});
    chrome.tabs.create({url: job.url, active: true}, tab => {
      jobs.set(tab.id, job);
      reply({ok: true, jobId});
    });
    return true;
  }
  if (msg?.type === 'GET_SHOPEE_JOB') {
    chrome.storage.session.get('shopee_active_job').then(v => reply({job: v.shopee_active_job || null}));
    return true;
  }
  if (msg?.type === 'SHOPEE_SKU_CAPTURED') {
    chrome.storage.session.get('shopee_active_job').then(v => {
      const job=v.shopee_active_job;
      if(!job)return reply({ok:false,error:'没有待处理的 Shopee SKU 任务'});
      chrome.tabs.sendMessage(job.sourceTabId,{type:'SHOPEE_SKU_RESULT',jobId:job.jobId,result:msg.result}).then(()=>{
        chrome.tabs.update(job.sourceTabId,{active:true});
        chrome.tabs.get(job.sourceTabId).then(tab=>tab.windowId!==undefined&&chrome.windows.update(tab.windowId,{focused:true})).catch(()=>{});
        chrome.storage.session.remove('shopee_active_job');
        reply({ok:true});
      }).catch(e=>reply({ok:false,error:e.message}));
    });
    return true;
  }
  if (msg?.type === 'GET_JOB') {
    const tabId = sender.tab?.id;
    const memory = jobs.get(tabId);
    if (memory) return reply({job: memory});
    chrome.storage.session.get('job_' + tabId).then(v => reply({job: v['job_' + tabId] || null}));
    return true;
  }
  if (msg?.type === 'UPDATE_JOB_STATE') {
    const tabId=sender.tab?.id,job=jobs.get(tabId);
    const update=found=>{if(!found)return reply({ok:false});Object.assign(found,msg.state||{});jobs.set(tabId,found);chrome.storage.session.set({['job_'+tabId]:found});reply({ok:true})};
    if(job)update(job);else chrome.storage.session.get('job_'+tabId).then(v=>update(v['job_'+tabId]));
    return true;
  }
  if (msg?.type === 'JOB_PROGRESS') {
    const job = jobs.get(sender.tab?.id);
    if (job) chrome.tabs.sendMessage(job.sourceTabId, {...msg, jobId: job.jobId}).catch(()=>{});
  }
  if (msg?.type === 'JOB_IMAGE') {
    const tabId=sender.tab?.id,job=jobs.get(tabId);
    const deliver=found=>found&&chrome.tabs.sendMessage(found.sourceTabId,{...msg,jobId:found.jobId,platform:found.platform}).catch(()=>{});
    if(job)deliver(job);else chrome.storage.session.get('job_'+tabId).then(v=>deliver(v['job_'+tabId]));
  }
  if (msg?.type === 'JOB_RESULT' || msg?.type === 'JOB_ERROR') {
    const tabId = sender.tab?.id;
    const job = jobs.get(tabId);
    const finish = found => {
      if (!found) return;
      const payload={...msg, jobId: found.jobId, platform: found.platform};
      const deliver=chrome.tabs.sendMessage(found.sourceTabId,payload).catch(()=>{});
      if (msg.type === 'JOB_RESULT') {
        deliver.finally(()=>chrome.tabs.get(found.sourceTabId).then(tab=>{
          chrome.tabs.update(found.sourceTabId,{active:true});
          if(tab.windowId!==undefined)chrome.windows.update(tab.windowId,{focused:true});
        }).catch(()=>{}));
        jobs.delete(tabId); chrome.storage.session.remove('job_' + tabId);
      }
    };
    if (job) finish(job);
    else chrome.storage.session.get('job_' + tabId).then(v => finish(v['job_' + tabId]));
  }
});
