/**
 * MYP Platform - CSS Caching Service Worker
 * Intelligentes Caching für optimierte CSS-Performance
 */

const CACHE_NAME = 'myp-css-cache-v1.0';
const CSS_CACHE_NAME = 'myp-css-resources-v1.0';

// Kritische CSS-Ressourcen für sofortiges Caching
const CRITICAL_CSS_RESOURCES = [
  '/static/css/caching-optimizations.css',
  '/static/css/optimization-animations.css',
  '/static/css/glassmorphism.css',
  '/static/css/professional-theme.css',
  '/static/css/tailwind.min.css'
];

// Nicht-kritische CSS-Ressourcen für Prefetching
const NON_CRITICAL_CSS_RESOURCES = [
  '/static/css/components.css',
  '/static/css/printers.css',
  '/static/fontawesome/css/all.min.css'
];

// CSS-spezifische Konfiguration
const CSS_CACHE_CONFIG = {
  maxAge: 24 * 60 * 60 * 1000, // 24 Stunden
  maxEntries: 50,
  networkTimeoutSeconds: 5
};

// Service Worker Installation
self.addEventListener('install', event => {
  console.log('[CSS-SW] Service Worker wird installiert...');
  
  event.waitUntil(
    caches.open(CSS_CACHE_NAME)
      .then(cache => {
        console.log('[CSS-SW] Kritische CSS-Ressourcen werden gecacht...');
        return cache.addAll(CRITICAL_CSS_RESOURCES);
      })
      .then(() => {
        console.log('[CSS-SW] Installation abgeschlossen');
        return self.skipWaiting();
      })
      .catch(error => {
        console.error('[CSS-SW] Fehler bei Installation:', error);
      })
  );
});

// Service Worker Aktivierung
self.addEventListener('activate', event => {
  console.log('[CSS-SW] Service Worker wird aktiviert...');
  
  event.waitUntil(
    caches.keys()
      .then(cacheNames => {
        return Promise.all(
          cacheNames.map(cacheName => {
            // Alte Caches löschen
            if (cacheName !== CACHE_NAME && cacheName !== CSS_CACHE_NAME) {
              console.log('[CSS-SW] Alter Cache wird gelöscht:', cacheName);
              return caches.delete(cacheName);
            }
          })
        );
      })
      .then(() => {
        console.log('[CSS-SW] Aktivierung abgeschlossen');
        return self.clients.claim();
      })
      .then(() => {
        // Nicht-kritische Ressourcen im Hintergrund prefetchen
        return prefetchNonCriticalResources();
      })
  );
});

// CSS-Request-Behandlung mit Cache-First-Strategie
self.addEventListener('fetch', event => {
  const { request } = event;
  
  // Nur CSS-Requests verarbeiten
  if (!request.url.includes('.css') && !request.url.includes('/static/css/')) {
    return;
  }
  
  event.respondWith(
    handleCSSRequest(request)
  );
});

// CSS-Request-Handler mit intelligenter Cache-Strategie
async function handleCSSRequest(request) {
  const url = new URL(request.url);
  
  try {
    // 1. Cache-First für CSS-Dateien
    const cachedResponse = await caches.match(request);
    
    if (cachedResponse) {
      console.log('[CSS-SW] Cache-Hit für:', url.pathname);
      
      // Hintergrund-Update für kritische Ressourcen
      if (CRITICAL_CSS_RESOURCES.some(resource => url.pathname.includes(resource))) {
        updateCacheInBackground(request);
      }
      
      return cachedResponse;
    }
    
    // 2. Network-Request mit Timeout
    const networkResponse = await fetchWithTimeout(request, CSS_CACHE_CONFIG.networkTimeoutSeconds * 1000);
    
    if (networkResponse && networkResponse.ok) {
      // Response für Cache klonen
      const responseToCache = networkResponse.clone();
      
      // Asynchron cachen
      cacheResponse(request, responseToCache);
      
      console.log('[CSS-SW] Network-Response für:', url.pathname);
      return networkResponse;
    }
    
    // 3. Fallback für kritische CSS
    return await getFallbackCSS(request);
    
  } catch (error) {
    console.error('[CSS-SW] Fehler bei CSS-Request:', error);
    return await getFallbackCSS(request);
  }
}

// Network-Request mit Timeout
function fetchWithTimeout(request, timeout) {
  return new Promise((resolve, reject) => {
    const timer = setTimeout(() => {
      reject(new Error('Network timeout'));
    }, timeout);
    
    fetch(request)
      .then(response => {
        clearTimeout(timer);
        resolve(response);
      })
      .catch(error => {
        clearTimeout(timer);
        reject(error);
      });
  });
}

// Response asynchron cachen
async function cacheResponse(request, response) {
  try {
    const cache = await caches.open(CSS_CACHE_NAME);
    await cache.put(request, response);
    
    // Cache-Größe prüfen und ggf. alte Einträge löschen
    await maintainCacheSize();
    
  } catch (error) {
    console.error('[CSS-SW] Fehler beim Cachen:', error);
  }
}

// Cache-Größe überwachen und bereinigen
async function maintainCacheSize() {
  try {
    const cache = await caches.open(CSS_CACHE_NAME);
    const requests = await cache.keys();
    
    if (requests.length > CSS_CACHE_CONFIG.maxEntries) {
      console.log('[CSS-SW] Cache-Bereinigung wird durchgeführt...');
      
      // Älteste Einträge löschen (LRU-ähnlich)
      const excessCount = requests.length - CSS_CACHE_CONFIG.maxEntries;
      for (let i = 0; i < excessCount; i++) {
        await cache.delete(requests[i]);
      }
    }
  } catch (error) {
    console.error('[CSS-SW] Fehler bei Cache-Wartung:', error);
  }
}

// Hintergrund-Update für kritische Ressourcen
async function updateCacheInBackground(request) {
  try {
    const response = await fetch(request);
    if (response && response.ok) {
      const cache = await caches.open(CSS_CACHE_NAME);
      await cache.put(request, response.clone());
      console.log('[CSS-SW] Hintergrund-Update für:', request.url);
    }
  } catch (error) {
    console.log('[CSS-SW] Hintergrund-Update fehlgeschlagen:', error);
  }
}

// Fallback-CSS für kritische Requests
async function getFallbackCSS(request) {
  const url = new URL(request.url);
  
  // Minimales Fallback-CSS für kritische Komponenten
  const fallbackCSS = `
    /* Fallback CSS für Offline-Nutzung */
    body { 
      font-family: system-ui, sans-serif; 
      margin: 0; 
      padding: 20px;
      background: #f8fafc;
      color: #1f2937;
    }
    .offline-notice {
      background: #fef3c7;
      border: 1px solid #f59e0b;
      border-radius: 8px;
      padding: 16px;
      margin-bottom: 20px;
      text-align: center;
    }
    .btn {
      background: #0073ce;
      color: white;
      border: none;
      padding: 8px 16px;
      border-radius: 4px;
      cursor: pointer;
    }
    .card {
      background: white;
      border: 1px solid #e5e7eb;
      border-radius: 8px;
      padding: 16px;
      margin-bottom: 16px;
    }
  `;
  
  return new Response(fallbackCSS, {
    headers: {
      'Content-Type': 'text/css',
      'Cache-Control': 'no-cache'
    }
  });
}

// Nicht-kritische Ressourcen im Hintergrund prefetchen
async function prefetchNonCriticalResources() {
  try {
    const cache = await caches.open(CSS_CACHE_NAME);
    
    for (const resource of NON_CRITICAL_CSS_RESOURCES) {
      try {
        const request = new Request(resource);
        const cachedResponse = await cache.match(request);
        
        if (!cachedResponse) {
          const response = await fetch(request);
          if (response && response.ok) {
            await cache.put(request, response);
            console.log('[CSS-SW] Prefetch erfolgreich für:', resource);
          }
        }
      } catch (error) {
        console.log('[CSS-SW] Prefetch fehlgeschlagen für:', resource);
      }
    }
  } catch (error) {
    console.error('[CSS-SW] Fehler beim Prefetching:', error);
  }
}

// Message-Handler für Cache-Management
self.addEventListener('message', event => {
  const { type, data } = event.data;
  
  switch (type) {
    case 'SKIP_WAITING':
      self.skipWaiting();
      break;
      
    case 'CLEAR_CSS_CACHE':
      clearCSSCache().then(() => {
        event.ports[0].postMessage({ success: true });
      });
      break;
      
    case 'PREFETCH_CSS':
      prefetchSpecificCSS(data.urls).then(() => {
        event.ports[0].postMessage({ success: true });
      });
      break;
      
    case 'GET_CACHE_STATS':
      getCacheStats().then(stats => {
        event.ports[0].postMessage(stats);
      });
      break;
  }
});

// CSS-Cache leeren
async function clearCSSCache() {
  try {
    await caches.delete(CSS_CACHE_NAME);
    console.log('[CSS-SW] CSS-Cache wurde geleert');
  } catch (error) {
    console.error('[CSS-SW] Fehler beim Leeren des CSS-Cache:', error);
  }
}

// Spezifische CSS-Dateien prefetchen
async function prefetchSpecificCSS(urls) {
  try {
    const cache = await caches.open(CSS_CACHE_NAME);
    
    for (const url of urls) {
      try {
        const response = await fetch(url);
        if (response && response.ok) {
          await cache.put(url, response);
          console.log('[CSS-SW] Spezifisches Prefetch für:', url);
        }
      } catch (error) {
        console.log('[CSS-SW] Spezifisches Prefetch fehlgeschlagen für:', url);
      }
    }
  } catch (error) {
    console.error('[CSS-SW] Fehler beim spezifischen Prefetching:', error);
  }
}

// Cache-Statistiken abrufen
async function getCacheStats() {
  try {
    const cache = await caches.open(CSS_CACHE_NAME);
    const requests = await cache.keys();
    
    return {
      cssEntries: requests.length,
      maxEntries: CSS_CACHE_CONFIG.maxEntries,
      cacheUtilization: (requests.length / CSS_CACHE_CONFIG.maxEntries) * 100,
      cachedUrls: requests.map(req => req.url)
    };
  } catch (error) {
    console.error('[CSS-SW] Fehler beim Abrufen der Cache-Stats:', error);
    return { error: error.message };
  }
}

// Performance-Monitoring
self.addEventListener('install', () => {
  console.log('[CSS-SW] Installation gestartet um:', new Date().toISOString());
});

self.addEventListener('activate', () => {
  console.log('[CSS-SW] Aktivierung abgeschlossen um:', new Date().toISOString());
});

// Globaler Error-Handler
self.addEventListener('error', event => {
  console.error('[CSS-SW] Globaler Fehler:', event.error);
});

self.addEventListener('unhandledrejection', event => {
  console.error('[CSS-SW] Unbehandelte Promise-Rejection:', event.reason);
});

console.log('[CSS-SW] CSS-Caching Service Worker geladen'); 