/* vps-manager Service Worker
 * 缓存策略：
 *  - 页面导航（HTML）：network-first，回源失败才用缓存。保证刷新即拿到最新版本号
 *  - 静态资源（?v= 版本号）：stale-while-revalidate（先返回缓存秒开，后台自动拉取最新）
 *    —— 版本号变了 URL 就变，缓存必 miss，天然回源新文件
 *  - /api/* 数据请求：始终走网络，保证数据实时
 * 更新机制：sw.js 由服务端 no-cache 提供，改动后导航时立即被浏览器发现；
 *           install 后 skipWaiting + clients.claim 立即接管，无需手动清缓存。
 */
const CACHE_NAME = 'vps-manager-v3';

const PRECACHE_URLS = [
  '/',
  '/static/js/vue.global.prod.js',
  '/static/js/tailwind.js',
  '/static/js/api.js',
  '/static/js/app.js',
  '/static/manifest.json',
  '/static/icons/icon-192.png',
  '/static/icons/icon-512.png',
];

self.addEventListener('install', (event) => {
  event.waitUntil(
    caches
      .open(CACHE_NAME)
      .then((cache) => cache.addAll(PRECACHE_URLS))
      .then(() => self.skipWaiting())
  );
});

self.addEventListener('activate', (event) => {
  event.waitUntil(
    caches
      .keys()
      .then((keys) =>
        Promise.all(keys.filter((k) => k !== CACHE_NAME).map((k) => caches.delete(k)))
      )
      .then(() => self.clients.claim())
  );
});

self.addEventListener('fetch', (event) => {
  const request = event.request;
  if (request.method !== 'GET') return;

  const url = new URL(request.url);
  if (url.origin !== self.location.origin) return;
  // 数据接口走网络，不缓存
  if (url.pathname.startsWith('/api/')) return;

  // 页面导航：network-first，保证每次刷新都拿到最新 HTML（含最新版本号）
  if (request.mode === 'navigate') {
    event.respondWith(
      fetch(request, { cache: 'no-store' })
        .then((response) => {
          const copy = response.clone();
          caches.open(CACHE_NAME).then((cache) => cache.put(request, copy));
          return response;
        })
        .catch(() => caches.match(request))
    );
    return;
  }

  // 静态资源：stale-while-revalidate（版本号控制缓存失效）
  event.respondWith(
    caches.open(CACHE_NAME).then(async (cache) => {
      const cached = await cache.match(request);
      // no-store：绕开浏览器 HTTP 磁盘缓存，保证回源拿到最新版本
      const network = fetch(request, { cache: 'no-store' })
        .then((response) => {
          if (response && response.ok) cache.put(request, response.clone());
          return response;
        })
        .catch(() => cached);
      return cached || network;
    })
  );
});
