// Service Worker for SmartSolTech PWA
const CACHE_NAME = 'smartsoltech-v1.0.2';
const STATIC_CACHE_NAME = 'smartsoltech-static-v1.0.2';
const DYNAMIC_CACHE_NAME = 'smartsoltech-dynamic-v1.0.2';

// Files to cache immediately
const STATIC_FILES = [
    '/',
    '/css/main.css',
    '/css/fixes.css',
    '/css/dark-theme.css',
    '/js/main.js',
    '/vendor/jquery/jquery-3.6.0.min.js',
    '/vendor/bootstrap/bootstrap.bundle.min.js',
    '/vendor/bootstrap/bootstrap.min.css',
    '/vendor/adminlte/adminlte.min.js',
    '/vendor/adminlte/adminlte.min.css',
    '/vendor/adminlte/fontawesome.min.css',
    '/images/logo.png',
    '/images/icon-192x192.png',
    '/images/icon-144x144.png',
    '/manifest.json',
    'https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap',
    'https://fonts.googleapis.com/css2?family=Noto+Sans+KR:wght@300;400;500;700&display=swap',
    'https://cdn.jsdelivr.net/npm/tailwindcss@2.2.19/dist/tailwind.min.css',
    'https://unpkg.com/aos@2.3.1/dist/aos.css',
    'https://unpkg.com/aos@2.3.1/dist/aos.js'
];

// Routes to cache dynamically
const DYNAMIC_ROUTES = [
    '/about',
    '/services',
    '/portfolio',
    '/calculator',
    '/contact'
];

// API endpoints to cache
const API_CACHE_PATTERNS = [
    /^\/api\/portfolio/,
    /^\/api\/services/,
    /^\/api\/calculator\/services/
];

// Install event - cache static files
self.addEventListener('install', event => {
    console.log('Service Worker: Installing...');
    
    event.waitUntil(
        caches.open(STATIC_CACHE_NAME)
            .then(cache => {
                console.log('Service Worker: Caching static files');
                return cache.addAll(STATIC_FILES);
            })
            .then(() => {
                console.log('Service Worker: Static files cached');
                return self.skipWaiting();
            })
            .catch(error => {
                console.error('Service Worker: Error caching static files', error);
            })
    );
});

// Activate event - clean up old caches
self.addEventListener('activate', event => {
    console.log('Service Worker: Activating...');
    
    event.waitUntil(
        caches.keys()
            .then(cacheNames => {
                return Promise.all(
                    cacheNames.map(cacheName => {
                        if (cacheName !== STATIC_CACHE_NAME && 
                            cacheName !== DYNAMIC_CACHE_NAME) {
                            console.log('Service Worker: Deleting old cache', cacheName);
                            return caches.delete(cacheName);
                        }
                    })
                );
            })
            .then(() => {
                console.log('Service Worker: Activated');
                return self.clients.claim();
            })
    );
});

// Fetch event - serve cached files or fetch from network
self.addEventListener('fetch', event => {
    const request = event.request;
    const url = new URL(request.url);
    
    // Skip non-GET requests
    if (request.method !== 'GET') {
        return;
    }
    
    // Skip Chrome extension requests
    if (url.protocol === 'chrome-extension:') {
        return;
    }
    
    // Handle different types of requests
    if (isStaticFile(request.url)) {
        event.respondWith(cacheFirst(request));
    } else if (isAPIRequest(request.url)) {
        event.respondWith(networkFirst(request));
    } else if (isDynamicRoute(request.url) || url.pathname === '/') {
        // For main pages, always check network first to ensure language consistency
        event.respondWith(networkFirst(request));
    } else {
        event.respondWith(networkFirst(request));
    }
});

// Cache strategies
async function cacheFirst(request) {
    try {
        const cachedResponse = await caches.match(request);
        if (cachedResponse) {
            return cachedResponse;
        }
        
        const networkResponse = await fetch(request);
        const cache = await caches.open(STATIC_CACHE_NAME);
        cache.put(request, networkResponse.clone());
        return networkResponse;
    } catch (error) {
        console.error('Cache first strategy failed:', error);
        return new Response('Offline', { status: 503 });
    }
}

async function networkFirst(request) {
    try {
        const networkResponse = await fetch(request);
        
        // Cache successful responses
        if (networkResponse.ok) {
            const cache = await caches.open(DYNAMIC_CACHE_NAME);
            cache.put(request, networkResponse.clone());
        }
        
        return networkResponse;
    } catch (error) {
        console.log('Network first: Falling back to cache for', request.url);
        
        const cachedResponse = await caches.match(request);
        if (cachedResponse) {
            return cachedResponse;
        }
        
        // Return offline page for navigation requests
        if (request.mode === 'navigate') {
            return caches.match('/offline.html') || new Response('Offline', { 
                status: 503,
                headers: { 'Content-Type': 'text/html' }
            });
        }
        
        return new Response('Network Error', { status: 503 });
    }
}

async function staleWhileRevalidate(request) {
    try {
        const cache = await caches.open(DYNAMIC_CACHE_NAME);
        const cachedResponse = await cache.match(request);
        
        const fetchPromise = fetch(request).then(networkResponse => {
            if (networkResponse && networkResponse.ok) {
                cache.put(request, networkResponse.clone());
            }
            return networkResponse;
        }).catch(error => {
            console.log('staleWhileRevalidate fetch failed:', error);
            return null;
        });
        
        return cachedResponse || fetchPromise || new Response('Not available', { status: 503 });
    } catch (error) {
        console.error('staleWhileRevalidate error:', error);
        return new Response('Service unavailable', { status: 503 });
    }
}

// Helper functions
function isStaticFile(url) {
    return url.includes('/css/') || 
           url.includes('/js/') || 
           url.includes('/images/') ||
           url.includes('/fonts/') ||
           url.includes('googleapis.com') ||
           url.includes('cdnjs.cloudflare.com');
}

function isAPIRequest(url) {
    return url.includes('/api/') || 
           API_CACHE_PATTERNS.some(pattern => pattern.test(url));
}

function isDynamicRoute(url) {
    const pathname = new URL(url).pathname;
    return DYNAMIC_ROUTES.includes(pathname) || 
           pathname.startsWith('/portfolio/') ||
           pathname.startsWith('/services/');
}

// Background sync for form submissions
self.addEventListener('sync', event => {
    console.log('Service Worker: Background sync triggered', event.tag);
    
    if (event.tag === 'contact-form-sync') {
        event.waitUntil(syncContactForms());
    }
});

async function syncContactForms() {
    try {
        const cache = await caches.open(DYNAMIC_CACHE_NAME);
        const requests = await cache.keys();
        
        const contactRequests = requests.filter(request => 
            request.url.includes('/api/contact/submit')
        );
        
        for (const request of contactRequests) {
            try {
                await fetch(request);
                await cache.delete(request);
                console.log('Contact form synced successfully');
            } catch (error) {
                console.error('Failed to sync contact form:', error);
            }
        }
    } catch (error) {
        console.error('Background sync failed:', error);
    }
}

// Push notification handling
self.addEventListener('push', event => {
    console.log('Service Worker: Push received', event);
    
    let data = {};
    if (event.data) {
        data = event.data.json();
    }
    
    const title = data.title || 'SmartSolTech';
    const options = {
        body: data.body || 'You have a new notification',
        icon: '/images/icon-192x192.png',
        badge: '/images/icon-72x72.png',
        tag: data.tag || 'default',
        data: data.url || '/',
        actions: [
            {
                action: 'open',
                title: '열기',
                icon: '/images/icon-open.png'
            },
            {
                action: 'close',
                title: '닫기',
                icon: '/images/icon-close.png'
            }
        ],
        requireInteraction: data.requireInteraction || false,
        silent: data.silent || false,
        vibrate: data.vibrate || [200, 100, 200]
    };
    
    event.waitUntil(
        self.registration.showNotification(title, options)
    );
});

// Notification click handling
self.addEventListener('notificationclick', event => {
    console.log('Service Worker: Notification clicked', event);
    
    event.notification.close();
    
    if (event.action === 'close') {
        return;
    }
    
    const url = event.notification.data || '/';
    
    event.waitUntil(
        clients.matchAll({ type: 'window' }).then(clientList => {
            // Check if window is already open
            for (const client of clientList) {
                if (client.url === url && 'focus' in client) {
                    return client.focus();
                }
            }
            
            // Open new window
            if (clients.openWindow) {
                return clients.openWindow(url);
            }
        })
    );
});

// Handle messages from main thread
self.addEventListener('message', event => {
    console.log('Service Worker: Message received', event.data);
    
    if (event.data && event.data.type === 'SKIP_WAITING') {
        self.skipWaiting();
    }
    
    if (event.data && event.data.type === 'CACHE_URLS') {
        cacheUrls(event.data.urls);
    }
});

async function cacheUrls(urls) {
    try {
        const cache = await caches.open(DYNAMIC_CACHE_NAME);
        await cache.addAll(urls);
        console.log('URLs cached successfully:', urls);
    } catch (error) {
        console.error('Failed to cache URLs:', error);
    }
}

// Periodic background sync (if supported)
self.addEventListener('periodicsync', event => {
    console.log('Service Worker: Periodic sync triggered', event.tag);
    
    if (event.tag === 'content-sync') {
        event.waitUntil(syncContent());
    }
});

async function syncContent() {
    try {
        // Fetch fresh portfolio and services data
        const portfolioResponse = await fetch('/api/portfolio?featured=true');
        const servicesResponse = await fetch('/api/services?featured=true');
        
        if (portfolioResponse.ok && servicesResponse.ok) {
            const cache = await caches.open(DYNAMIC_CACHE_NAME);
            cache.put('/api/portfolio?featured=true', portfolioResponse.clone());
            cache.put('/api/services?featured=true', servicesResponse.clone());
            console.log('Content synced successfully');
        }
    } catch (error) {
        console.error('Content sync failed:', error);
    }
}

// Cache management utilities
async function cleanupCaches() {
    const cacheNames = await caches.keys();
    const currentCaches = [STATIC_CACHE_NAME, DYNAMIC_CACHE_NAME];
    
    return Promise.all(
        cacheNames.map(cacheName => {
            if (!currentCaches.includes(cacheName)) {
                console.log('Deleting old cache:', cacheName);
                return caches.delete(cacheName);
            }
        })
    );
}

// Limit cache size
async function limitCacheSize(cacheName, maxItems) {
    const cache = await caches.open(cacheName);
    const keys = await cache.keys();
    
    if (keys.length > maxItems) {
        const keysToDelete = keys.slice(0, keys.length - maxItems);
        return Promise.all(keysToDelete.map(key => cache.delete(key)));
    }
}

// Performance monitoring
self.addEventListener('fetch', event => {
    if (event.request.url.includes('/api/')) {
        const start = performance.now();
        
        event.respondWith(
            fetch(event.request).then(response => {
                const duration = performance.now() - start;
                
                // Log slow API requests
                if (duration > 2000) {
                    console.warn('Slow API request:', event.request.url, duration + 'ms');
                }
                
                return response;
            })
        );
    }
});

// Error tracking
self.addEventListener('error', event => {
    console.error('Service Worker error:', event.error);
    // Could send to analytics service
});

self.addEventListener('unhandledrejection', event => {
    console.error('Service Worker unhandled rejection:', event.reason);
    // Could send to analytics service
});