/**
 * Service Worker — Titipin Ba Be PWA
 * Strategi: Cache First untuk asset statis, Network First untuk halaman.
 */

const SW_VERSION   = 'titipin-v1';
const CACHE_STATIC = `${SW_VERSION}-static`;
const CACHE_PAGES  = `${SW_VERSION}-pages`;

// Asset statis yang selalu di-cache saat install
const STATIC_ASSETS = [
    '/offline.html',
    '/manifest.json',
    '/icons/icon-192.png',
    '/icons/icon-512.png',
];

// ── Install ──────────────────────────────────────────────────────────────────
self.addEventListener('install', (event) => {
    event.waitUntil(
        caches.open(CACHE_STATIC).then((cache) => {
            return cache.addAll(STATIC_ASSETS);
        })
    );
    // Aktifkan SW baru segera tanpa menunggu tab lama tutup
    self.skipWaiting();
});

// ── Activate ─────────────────────────────────────────────────────────────────
self.addEventListener('activate', (event) => {
    event.waitUntil(
        caches.keys().then((keys) => {
            return Promise.all(
                keys
                    .filter((key) => key !== CACHE_STATIC && key !== CACHE_PAGES)
                    .map((key) => caches.delete(key))
            );
        })
    );
    // Ambil alih semua tab yang terbuka segera
    self.clients.claim();
});

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

    // Abaikan request non-GET dan dari origin lain
    if (request.method !== 'GET') return;
    if (url.origin !== self.location.origin) return;

    // Abaikan Livewire, API, dan admin
    if (url.pathname.startsWith('/livewire/')) return;
    if (url.pathname.startsWith('/admin')) return;

    // Asset statis (build Vite: /build/assets/) — Cache First
    if (url.pathname.startsWith('/build/') || isStaticAsset(url.pathname)) {
        event.respondWith(cacheFirst(request));
        return;
    }

    // Halaman Store — Network First dengan offline fallback
    if (url.pathname.startsWith('/store') || url.pathname === '/') {
        event.respondWith(networkFirstWithOfflineFallback(request));
        return;
    }
});

// ── Strategies ────────────────────────────────────────────────────────────────

/**
 * Cache First: gunakan cache jika ada, fetch jika tidak.
 * Cocok untuk asset yang jarang berubah.
 */
async function cacheFirst(request) {
    const cached = await caches.match(request);
    if (cached) return cached;

    try {
        const response = await fetch(request);
        if (response.ok) {
            const cache = await caches.open(CACHE_STATIC);
            cache.put(request, response.clone());
        }
        return response;
    } catch {
        return new Response('Asset tidak tersedia offline.', { status: 503 });
    }
}

/**
 * Network First: coba fetch, fallback ke cache, lalu ke offline.html.
 * Cocok untuk halaman yang butuh data terbaru.
 */
async function networkFirstWithOfflineFallback(request) {
    try {
        const response = await fetch(request);
        if (response.ok) {
            // Cache halaman yang berhasil dimuat
            const cache = await caches.open(CACHE_PAGES);
            cache.put(request, response.clone());
        }
        return response;
    } catch {
        // Coba dari cache halaman
        const cached = await caches.match(request);
        if (cached) return cached;

        // Fallback ke offline page
        const offline = await caches.match('/offline.html');
        return offline || new Response('<h1>Offline</h1>', {
            headers: { 'Content-Type': 'text/html' },
            status: 503,
        });
    }
}

// ── Helpers ───────────────────────────────────────────────────────────────────

function isStaticAsset(pathname) {
    return (
        pathname.endsWith('.js') ||
        pathname.endsWith('.css') ||
        pathname.endsWith('.png') ||
        pathname.endsWith('.jpg') ||
        pathname.endsWith('.jpeg') ||
        pathname.endsWith('.webp') ||
        pathname.endsWith('.svg') ||
        pathname.endsWith('.ico') ||
        pathname.endsWith('.woff2') ||
        pathname.endsWith('.woff')
    );
}

// ── Push Notification (Fondasi) ───────────────────────────────────────────────
// Siap untuk Sprint berikutnya jika diperlukan
self.addEventListener('push', (event) => {
    if (!event.data) return;
    const data = event.data.json();
    self.registration.showNotification(data.title || 'Titipin Ba Be', {
        body: data.body || '',
        icon: '/icons/icon-192.png',
        badge: '/icons/icon-192.png',
    });
});
