// WebMoney Service Worker - PWA Support
const CACHE_VERSION = 'webmoney-v1.39.0';
const CACHE_STATIC = `${CACHE_VERSION}-static`;
const CACHE_DYNAMIC = `${CACHE_VERSION}-dynamic`;
const CACHE_IMMUTABLE = `${CACHE_VERSION}-immutable`;

// Recursos para cache imediato (install)
const STATIC_ASSETS = [
  '/',
  '/index.html',
  '/manifest.json',
  '/logo-192.png',
  '/logo-512.png',
  '/apple-touch-icon.png',
];

// Estratégia: Cache First com fallback para Network
const CACHE_FIRST_PATTERNS = [
  /\.(png|jpg|jpeg|svg|gif|webp|ico)$/,
  /\.(woff|woff2|ttf|eot)$/,
  /bootstrap-icons/,
];

// Estratégia: Network First com fallback para Cache
const NETWORK_FIRST_PATTERNS = [
  /\/api\//,
];

// Install - cacheia recursos estáticos
self.addEventListener('install', (event) => {
  console.log('[SW] Installing Service Worker...', CACHE_VERSION);
  
  event.waitUntil(
    caches.open(CACHE_STATIC).then((cache) => {
      console.log('[SW] Caching static assets');
      return cache.addAll(STATIC_ASSETS);
    })
    .then(() => self.skipWaiting()) // Ativa imediatamente
  );
});

// Activate - limpa caches antigos
self.addEventListener('activate', (event) => {
  console.log('[SW] Activating Service Worker...', CACHE_VERSION);
  
  event.waitUntil(
    caches.keys().then((cacheNames) => {
      return Promise.all(
        cacheNames
          .filter((name) => name.startsWith('webmoney-') && name !== CACHE_STATIC && name !== CACHE_DYNAMIC && name !== CACHE_IMMUTABLE)
          .map((name) => {
            console.log('[SW] Deleting old cache:', name);
            return caches.delete(name);
          })
      );
    })
    .then(() => self.clients.claim()) // Assume controle imediatamente
  );
});

// Fetch - estratégias de cache
self.addEventListener('fetch', (event) => {
  const { request } = event;
  const url = new URL(request.url);

  // Ignora requisições não-GET
  if (request.method !== 'GET') {
    return;
  }

  // Ignora chrome-extension e outras URLs especiais
  if (!url.protocol.startsWith('http')) {
    return;
  }

  // Cache First para assets estáticos
  if (CACHE_FIRST_PATTERNS.some(pattern => pattern.test(request.url))) {
    event.respondWith(cacheFirst(request));
    return;
  }

  // Network First para API calls
  if (NETWORK_FIRST_PATTERNS.some(pattern => pattern.test(request.url))) {
    event.respondWith(networkFirst(request));
    return;
  }

  // Stale-While-Revalidate para HTML/CSS/JS
  event.respondWith(staleWhileRevalidate(request));
});

// Estratégia: Cache First (imagens, fontes)
async function cacheFirst(request) {
  const cache = await caches.open(CACHE_IMMUTABLE);
  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.log('[SW] Fetch failed for:', request.url);
    // Retorna cache mesmo se expirado
    return cached || new Response('Network error', { status: 408 });
  }
}

// Estratégia: Network First (API)
async function networkFirst(request) {
  const cache = await caches.open(CACHE_DYNAMIC);
  
  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:', request.url);
    const cached = await cache.match(request);
    return cached || new Response(JSON.stringify({ error: 'Offline' }), {
      status: 503,
      headers: { 'Content-Type': 'application/json' }
    });
  }
}

// Estratégia: Stale-While-Revalidate (HTML, CSS, JS)
async function staleWhileRevalidate(request) {
  const cache = await caches.open(CACHE_DYNAMIC);
  const cached = await cache.match(request);

  const fetchPromise = fetch(request).then((response) => {
    if (response.ok) {
      cache.put(request, response.clone());
    }
    return response;
  });

  return cached || fetchPromise;
}

// Mensagens do cliente
self.addEventListener('message', (event) => {
  if (event.data === 'SKIP_WAITING') {
    self.skipWaiting();
  }
  
  if (event.data === 'CLEAR_CACHE') {
    event.waitUntil(
      caches.keys().then((cacheNames) => {
        return Promise.all(
          cacheNames.map((name) => caches.delete(name))
        );
      })
    );
  }
});

console.log('[SW] Service Worker loaded:', CACHE_VERSION);
