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

const isDevelopment = self.location.hostname === 'localhost' || 
                      self.location.hostname === '127.0.0.1' ||
                      self.location.hostname === '[::1]';

if (isDevelopment) {
  self.addEventListener('install', (event) => {
    console.log('[SW] Development mode detected, skipping installation');
    self.skipWaiting();
  });
  
  self.addEventListener('activate', (event) => {
    console.log('[SW] Development mode detected, unregistering...');
    event.waitUntil(
      self.clients.matchAll().then((clients) => {
        clients.forEach((client) => {
          client.postMessage({ type: 'SW_UNREGISTER' });
        });
      }).then(() => {
        return self.registration.unregister();
      })
    );
  });
  
  self.addEventListener('fetch', (event) => {
    return;
  });
}

const CACHE_VERSION = 'v1.0.0';
const CACHE_NAME = `codigo0-${CACHE_VERSION}`;
const RUNTIME_CACHE = `codigo0-runtime-${CACHE_VERSION}`;

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}`;
};

const STATIC_ASSETS = [
  normalizePath('/'),
  normalizePath('/index.html'),
  normalizePath('/manifest.json'),
  normalizePath('/favicon.ico'),
];

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 Promise.allSettled(
          STATIC_ASSETS.map(url => 
            cache.add(url).catch(err => {
              console.warn(`[SW] Failed to cache ${url}:`, err);
              return null;
            })
          )
        );
      })
      .then(() => {
        console.log('[SW] Static assets cached');
        self.skipWaiting();
      })
      .catch((error) => {
        console.error('[SW] Installation failed:', error);
        self.skipWaiting();
      })
  );
});

self.addEventListener('activate', (event) => {
  console.log('[SW] Activating service worker...');
  
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames
          .filter((cacheName) => {
            return cacheName !== CACHE_NAME && cacheName !== RUNTIME_CACHE;
          })
          .map((cacheName) => {
            console.log('[SW] Deleting old cache:', cacheName);
            return caches.delete(cacheName);
          })
      );
    })
    .then(() => self.clients.claim())
  );
});

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

  if (request.method !== 'GET') {
    return;
  }

  if (url.origin !== location.origin) {
    return;
  }

  if (
    url.hostname === 'localhost' || 
    url.hostname === '127.0.0.1' ||
    url.hostname === '[::1]'
  ) {
    if (
      url.pathname.startsWith('/src/') ||
      url.pathname.startsWith('/@') ||
      url.pathname.startsWith('/node_modules/') ||
      url.pathname.includes('?t=') ||
      url.pathname.endsWith('.tsx') ||
      url.pathname.endsWith('.ts') ||
      url.pathname.includes('node_modules') ||
      url.searchParams.has('import') ||
      url.protocol === 'ws:' ||
      url.protocol === 'wss:'
    ) {
      return;
    }
  }

  if (
    request.destination === 'script' ||
    request.destination === 'style' ||
    request.destination === 'image' ||
    request.destination === 'font' ||
    url.pathname.endsWith('.md') ||
    url.pathname.includes('/assets/')
  ) {
    event.respondWith(cacheFirst(request));
  } else {
    event.respondWith(networkFirst(request));
  }
});

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);
    if (request.destination === 'image') {
      return new Response('', { status: 404 });
    }
    throw error;
  }
}

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;
    }
    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;
  }
}

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);
      })
    );
  }
});