try {
  importScripts("../src/lib/biliindex-core.js");
} catch (e) {
  console.error("[BiliIndex] Service Worker 加载核心库失败", e);
}

async function bootstrap() {
  if (BiliIndex.ensureFixedApiConfig) await BiliIndex.ensureFixedApiConfig();
  preloadTags();
  if (BiliIndex.syncExtensionIcon) await BiliIndex.syncExtensionIcon();
  if (BiliIndex.schedulePasserbyScanResume) BiliIndex.schedulePasserbyScanResume();
}

chrome.runtime.onInstalled.addListener(() => {
  chrome.storage.local.get(["apiMode", "customCloudApiBase"], (st) => {
    void chrome.runtime?.lastError;
    const patch = {};
    if (!st.apiMode) patch.apiMode = "cloud";
    if (!st.customCloudApiBase && !st.apiMode) {
      patch.apiBase = BiliIndex.CLOUD_API_BASE;
      patch.cloudApiBase = BiliIndex.CLOUD_API_BASE;
    }
    if (Object.keys(patch).length) chrome.storage.local.set(patch);
    void bootstrap();
  });
});

chrome.runtime.onStartup.addListener(() => {
  void bootstrap();
});

chrome.alarms?.create?.("biliindex-sync-icon", { periodInMinutes: 360 });
chrome.alarms?.onAlarm?.addListener((alarm) => {
  if (alarm.name === "biliindex-sync-icon" && BiliIndex.syncExtensionIcon) {
    void BiliIndex.syncExtensionIcon();
  }
});

chrome.storage?.onChanged?.addListener((changes, area) => {
  if (area !== "local" || !changes.apiBase) return;
  if (BiliIndex.syncExtensionIcon) void BiliIndex.syncExtensionIcon({ force: true });
});

async function preloadTags() {
  try {
    await BiliIndex.refreshTagCaches(false);
  } catch (e) {
    console.warn("[BiliIndex] 标签预加载失败", e.message);
  }
}

/** 低优先级（display-batch 等）串行；打标/开菜单 走高优先级且不占低优先级队列 */
let apiLowPriorityChain = Promise.resolve();

function isHighPriorityApiPath(path) {
  const p = String(path || "");
  return (
    p.includes("/slot-options") ||
    p.includes("/quick-submit") ||
    p.includes("/check-frequency") ||
    p.includes("/auth/login") ||
    p.includes("/auth/register")
  );
}

function runApiJob(path, job) {
  if (isHighPriorityApiPath(path)) {
    return Promise.resolve().then(job);
  }
  const run = apiLowPriorityChain.then(job, job);
  apiLowPriorityChain = run.then(
    () => {},
    () => {}
  );
  return run;
}

chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
  if (msg.type === "PING") {
    sendResponse({ ok: true });
    return false;
  }
  if (msg.type === "FETCH_PUBLIC") {
    runApiJob(msg.path, () => BiliIndex._fetchPublicDirect(msg.path))
      .then((data) => sendResponse({ ok: true, data }))
      .catch((e) => sendResponse({ ok: false, error: e.message }));
    return true;
  }
  if (msg.type === "API_FETCH") {
    runApiJob(msg.path, () =>
      BiliIndex._apiFetchDirect(msg.path, msg.options || {})
    )
      .then((data) => sendResponse({ ok: true, data }))
      .catch((e) => sendResponse({ ok: false, error: e.message }));
    return true;
  }
  if (msg.type === "REFRESH_TAGS") {
    BiliIndex.refreshTagCaches(true)
      .then(({ tree, quick }) =>
        sendResponse({ ok: true, tree, quick, items: quick })
      )
      .catch((e) => sendResponse({ ok: false, error: e.message, items: [] }));
    return true;
  }
  if (msg.type === "GET_TAG_TREE") {
    BiliIndex.getTagTree(!!msg.force)
      .then((tree) => sendResponse({ ok: true, items: tree }))
      .catch((e) => sendResponse({ ok: false, error: e.message, items: [] }));
    return true;
  }
  if (msg.type === "GET_QUICK_TAGS") {
    BiliIndex.getQuickTags(!!msg.force)
      .then((items) => sendResponse({ ok: true, items: items || [] }))
      .catch((e) => sendResponse({ ok: false, error: e.message, items: [] }));
    return true;
  }
  if (msg.type === "SUPER_HATE_SYNCED") {
    chrome.tabs.query({ url: ["*://*.bilibili.com/*", "*://bilibili.com/*"] }, (tabs) => {
      void chrome.runtime.lastError;
      for (const tab of tabs || []) {
        if (!tab.id) continue;
        chrome.tabs.sendMessage(tab.id, { type: "SUPER_HATE_SYNCED" }).catch(() => {});
      }
    });
    sendResponse({ ok: true });
    return true;
  }
  if (msg.type === "QUICK_TAG") {
    BiliIndex.quickTag(msg.up_mid, msg.tag_code, {
      slot: msg.slot || "tag1",
      nickname: msg.nickname,
      fan_count: msg.fan_count,
    })
      .then((res) => sendResponse(res))
      .catch((e) => sendResponse({ ok: false, error: e.message }));
    return true;
  }
  if (msg.type === "SUBMIT_TAG") {
    BiliIndex.submitTag(msg.up_mid, msg.tag_id)
      .then((res) => sendResponse(res))
      .catch((e) => sendResponse({ ok: false, error: e.message }));
    return true;
  }
  if (msg.type === "GET_AUTH") {
    Promise.all([BiliIndex.getToken(), BiliIndex.storageGet(["user"])])
      .then(([token, { user }]) => sendResponse({ token, user }))
      .catch((e) => sendResponse({ token: null, user: null, error: e.message }));
    return true;
  }
});
