// service-worker.js
const PRECACHE = 'maps-precache-v1';
const RUNTIME = 'maps-runtime-v1';
// Ресурсы для предварительного кеширования
const PRECACHE_URLS = [
  '/modules/maps/frontend/index.html',
  '/modules/maps/frontend/route-handler.js',
  '/modules/maps/config/route.json',
  '/modules/maps/audio/altes_rathaus.mp3',
  '/modules/maps/audio/st_lorenz.mp3',
  '/modules/maps/audio/residenz.mp3',
  '/modules/maps/audio/cambodunum.mp3',
  'https://unpkg.com/leaflet/dist/leaflet.css',
  'https://unpkg.com/leaflet/dist/leaflet.js'
];

self.addEventListener('install', event => {
  event.waitUntil((async () => {
    const cache = await caches.open(PRECACHE);
    for (const url of PRECACHE_URLS) {
      try {
        await cache.add(url);
      } catch (err) {
        console.warn('Не удалось закешировать:', url, err);
      }
    }
  })().then(() => self.skipWaiting()));
});

self.addEventListener('activate', event => {
  const currentCaches = [PRECACHE, RUNTIME];
  event.waitUntil((async () => {
    const cacheNames = await caches.keys();
    await Promise.all(
      cacheNames.map(name => {
        if (!currentCaches.includes(name)) {
          return caches.delete(name);
        }
      })
    );
    await self.clients.claim();
  })());
});

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

  // Навигация по URL: network-first, fallback на index.html
  if (request.mode === 'navigate') {
    event.respondWith((async () => {
      try {
        return await fetch(request);
      } catch (err) {
        const cache = await caches.open(PRECACHE);
        const cached = await cache.match('/modules/maps/frontend/index.html');
        return cached || new Response('Offline', { status: 503, headers: { 'Content-Type': 'text/html' } });
      }
    })());
    return;
  }

  // OSM тайлы: cache-first
  if (url.host === 'tile.openstreetmap.org') {
    event.respondWith((async () => {
      const cache = await caches.open(RUNTIME);
      const cached = await cache.match(request);
      if (cached) return cached;
      try {
        const response = await fetch(request);
        await cache.put(request, response.clone());
        return response;
      } catch (err) {
        return cached || new Response(null, { status: 504 });
      }
    })());
    return;
  }

  // Пред-кеш ресурсы: cache-first
  if (PRECACHE_URLS.includes(url.pathname)) {
    event.respondWith(
      caches.match(request).then(response => response || fetch(request))
    );
    return;
  }

  // Аудио и маршрут: cache-first с runtime caching
  if (url.pathname.startsWith('/modules/maps/audio/') || url.pathname.endsWith('/route.json')) {
    event.respondWith((async () => {
      const cached = await caches.match(request);
      if (cached) return cached;
      try {
        const response = await fetch(request);
        const cache = await caches.open(RUNTIME);
        cache.put(request, response.clone());
        return response;
      } catch (err) {
        return new Response(null, { status: 404 });
      }
    })());
    return;
  }

  // По умолчанию: пытаемся из кеша, иначе сеть
  event.respondWith(
    caches.match(request).then(response => response || fetch(request).catch(() => new Response(null, { status: 504 })))
  );
});
