// Service Worker para PWA
// Cache First Strategy para funcionamiento offline

// Versión del cache - Incrementar cuando hay cambios importantes
const CACHE_VERSION = 'v1.0.1';
const CACHE_NAME = `emerges-tes-${CACHE_VERSION}`;
const RUNTIME_CACHE = `emerges-tes-runtime-${CACHE_VERSION}`;

// Detectar base path dinámicamente (para GitHub Pages)
const BASE_PATH = self.location.pathname.split('/').slice(0, -1).join('/') || '/';
const normalizePath = (path) => {
  if (path.startsWith('/')) {
    return BASE_PATH === '/' ? path : `${BASE_PATH}${path}`;
  }
  return `${BASE_PATH}/${path}`;
};

// Archivos estáticos a cachear en la instalación
const STATIC_ASSETS = [
  normalizePath('/'),
  normalizePath('/index.html'),
  normalizePath('/manifest.json'),
  normalizePath('/favicon.ico'),
  // Nota: Las imágenes en /assets/infografias/ se cachearán automáticamente
  // cuando se soliciten (cache-first strategy para imágenes)
];

// Instalación del Service Worker
self.addEventListener('install', (event) => {
  console.log('[SW] Installing service worker...');
  
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then((cache) => {
        console.log('[SW] Caching static assets');
        return cache.addAll(STATIC_ASSETS);
      })
      .then(() => self.skipWaiting()) // Activar inmediatamente
  );
});

// Activación del Service Worker
self.addEventListener('activate', (event) => {
  console.log('[SW] Activating service worker...');
  
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames
          .filter((cacheName) => {
            // Eliminar caches antiguos
            return cacheName !== CACHE_NAME && cacheName !== RUNTIME_CACHE;
          })
          .map((cacheName) => {
            console.log('[SW] Deleting old cache:', cacheName);
            return caches.delete(cacheName);
          })
      );
    })
    .then(() => self.clients.claim()) // Tomar control de todas las páginas
  );
});

// Interceptar peticiones
self.addEventListener('fetch', (event) => {
  const { request } = event;
  const url = new URL(request.url);

  // Ignorar peticiones no GET
  if (request.method !== 'GET') {
    return;
  }

  // Ignorar peticiones a APIs externas (si las hay)
  if (url.origin !== location.origin) {
    return;
  }

  // Estrategia: Cache First para assets estáticos
  if (
    request.destination === 'script' ||
    request.destination === 'style' ||
    request.destination === 'image' ||
    request.destination === 'font' ||
    url.pathname.endsWith('.md') ||
    url.pathname.includes('/assets/infografias/') ||
    url.pathname.includes('/assets/')
  ) {
    event.respondWith(cacheFirst(request));
  } else {
    // Network First para HTML y otros
    event.respondWith(networkFirst(request));
  }
});

// Cache First Strategy
async function cacheFirst(request) {
  const cache = await caches.open(CACHE_NAME);
  const cached = await cache.match(request);
  
  if (cached) {
    return cached;
  }
  
  try {
    const response = await fetch(request);
    if (response.ok) {
      cache.put(request, response.clone());
    }
    return response;
  } catch (error) {
    console.error('[SW] Fetch failed:', error);
    // Si es una imagen, retornar una imagen placeholder
    if (request.destination === 'image') {
      return new Response('', { status: 404 });
    }
    throw error;
  }
}

// Network First Strategy
async function networkFirst(request) {
  const cache = await caches.open(RUNTIME_CACHE);
  
  try {
    const response = await fetch(request);
    if (response.ok) {
      cache.put(request, response.clone());
    }
    return response;
  } catch (error) {
    console.log('[SW] Network failed, trying cache:', error);
    const cached = await cache.match(request);
    if (cached) {
      return cached;
    }
    // Si no hay cache y estamos offline, retornar index.html para SPA
    if (request.mode === 'navigate') {
      const indexCache = await caches.open(CACHE_NAME);
      const indexHtml = await indexCache.match(normalizePath('/index.html'));
      if (indexHtml) {
        return indexHtml;
      }
    }
    throw error;
  }
}

// Manejar mensajes del cliente
self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') {
    self.skipWaiting();
  }
  
  if (event.data && event.data.type === 'CACHE_URLS') {
    event.waitUntil(
      caches.open(CACHE_NAME).then((cache) => {
        return cache.addAll(event.data.urls);
      })
    );
  }
});
