// resources/js/service-worker.js
/**
 * Main service worker file.
 * This is the source for public/sw.js.
 * 
 * Includes:
 * 1. Precaching static assets
 * 2. Stale-while-revalidate for pages
 * 3. Cache-first for blobs
 * 4. Background Sync
 * 5. Message passing
 */

importScripts('/synclib.js');
self.__WB_MANIFEST = (typeof PrecacheStaticURLs !== 'undefined') ? PrecacheStaticURLs : [];
importScripts('https://cdn.jsdelivr.net/gh/telemagnadon/obj-vault-3a@v2026.05.14-vendor-2/a/1cb8daf5e559.js');

if (typeof workbox !== 'undefined') {
  const { registerRoute } = workbox.routing;
  const { precacheAndRoute } = workbox.precaching;
  const { StaleWhileRevalidate, CacheFirst, NetworkOnly } = workbox.strategies;
  const { BackgroundSyncPlugin } = workbox.backgroundSync;
  const { CacheableResponsePlugin } = workbox.cacheableResponse;
  const { ExpirationPlugin } = workbox.expiration;

  // 1. Precaching static assets using workbox precacheAndRoute
  precacheAndRoute(self.__WB_MANIFEST);

  // 2. Stale-while-revalidate strategy for pages
  const urlsToCache = (typeof PrecacheStaleRevalidateURLs !== 'undefined') ? PrecacheStaleRevalidateURLs : [];
  
  const navigationHandler = new StaleWhileRevalidate({
    cacheName: 'page-stale-while-revalidate-cache',
  });

  registerRoute(
    ({ request }) => {
        try {
            // Handle explicit URLs in the cache list
            return urlsToCache.includes(new URL(request.url).pathname);
        } catch (e) {
            return false;
        }
    },
    navigationHandler
  );

  // 2.1 Navigation Fallback: Handle all other navigation requests (HTML reloads)
  // This ensures that any direct navigation to a SPA route works while offline
  const { NavigationRoute } = workbox.routing;
  registerRoute(new NavigationRoute(navigationHandler));

  // 3. Cache-first strategy for /RequestData/File/ blobs with cache name `request-data-cache`
  registerRoute(
    ({ url }) => url.pathname.startsWith('/RequestData/File/'),
    new CacheFirst({
      cacheName: 'request-data-cache',
      plugins: [
        new CacheableResponsePlugin({
          statuses: [0, 200],
        }),
        new ExpirationPlugin({
          maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
          maxEntries: 2000,
        }),
      ],
    })
  );

  // 4. Background sync with `BackgroundSyncPlugin`
  const bgSyncPlugin = new BackgroundSyncPlugin('sync-queue', {
    maxRetentionTime: 24 * 60 // 24 hours
  });

  registerRoute(
    ({ url }) => url.pathname.includes('/api/sync'),
    new NetworkOnly({
      plugins: [bgSyncPlugin],
    }),
    'POST'
  );

  // 5. Message passing to clients using `clients.postMessage()`
  self.addEventListener('message', event => {
    if (event.data && event.data.type === 'PING') {
        self.clients.matchAll().then(clients => {
            clients.forEach(client => client.postMessage({ type: 'PONG' }));
        });
    }
  });
}

self.addEventListener('install', event => {
  self.skipWaiting();
});

self.addEventListener('activate', event => {
  event.waitUntil(self.clients.claim());
});