/**
 * PWA Helper Functions
 * Handles service worker registration and PWA installation
 */

// Get URL path from config or default
const URL_PATH = typeof APP_CONFIG !== 'undefined' ? APP_CONFIG.urlPath : '/birthday_reminder';

// Service Worker Registration
if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
        navigator.serviceWorker.register(URL_PATH + '/public/service-worker.js')
            .then((registration) => {
                console.log('[PWA] Service Worker registered successfully:', registration.scope);
                
                // Check for updates periodically
                setInterval(() => {
                    registration.update();
                }, 60000); // Check every minute
                
                // Handle service worker updates
                registration.addEventListener('updatefound', () => {
                    const newWorker = registration.installing;
                    
                    newWorker.addEventListener('statechange', () => {
                        if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
                            // New service worker available
                            showUpdateNotification();
                        }
                    });
                });
            })
            .catch((error) => {
                console.error('[PWA] Service Worker registration failed:', error);
            });
    });
}

// Show update notification
function showUpdateNotification() {
    if (confirm('A new version is available! Reload to update?')) {
        window.location.reload();
    }
}

// PWA Installation
let deferredPrompt;

// Detect iOS
function isIOS() {
    return /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
}

// Detect if running standalone (already installed)
function isStandalone() {
    return window.matchMedia('(display-mode: standalone)').matches ||
           window.navigator.standalone === true;
}

// Check if install prompt was dismissed
function wasInstallPromptDismissed() {
    return localStorage.getItem('installPromptDismissed') === 'true' ||
           localStorage.getItem('iosInstallPromptDismissed') === 'true';
}

// Show appropriate install prompt based on device
function showInstallPrompt() {
    // Don't show if already installed or dismissed
    if (isStandalone() || wasInstallPromptDismissed()) {
        console.log('[PWA] Install prompt suppressed (standalone or dismissed)');
        return;
    }

    if (isIOS()) {
        // Show iOS instructions
        const iosPrompt = document.getElementById('iosInstallPrompt');
        if (iosPrompt) {
            console.log('[PWA] Showing iOS install instructions');
            iosPrompt.classList.remove('d-none');
        }
    }
    // For Android/Desktop, wait for beforeinstallprompt event
}

// Capture the install prompt event (Android/Desktop Chrome)
window.addEventListener('beforeinstallprompt', (event) => {
    console.log('[PWA] Install prompt available');

    // Prevent the mini-infobar from appearing
    event.preventDefault();

    // Store the event for later use
    deferredPrompt = event;

    // Show the permanent install button
    const installAppBtn = document.getElementById('installAppBtn');
    if (installAppBtn && !isStandalone()) {
        installAppBtn.classList.remove('d-none');
    }

    // Show install prompt banner if not dismissed
    if (!wasInstallPromptDismissed()) {
        const installPrompt = document.getElementById('installPrompt');
        if (installPrompt) {
            installPrompt.classList.remove('d-none');
        }
    }
});

// Function to handle install button click
async function handleInstallClick() {
    if (isIOS()) {
        // Show iOS instructions
        const iosPrompt = document.getElementById('iosInstallPrompt');
        if (iosPrompt) {
            iosPrompt.classList.remove('d-none');
            // Remove dismissal flag to show prompt again
            localStorage.removeItem('iosInstallPromptDismissed');
        }
        return;
    }

    if (!deferredPrompt) {
        console.log('[PWA] Install prompt not available');
        showToast('Install option not available. Try refreshing the page.', 'info');
        return;
    }

    // Show the install prompt
    deferredPrompt.prompt();

    // Wait for the user's response
    const { outcome } = await deferredPrompt.userChoice;
    console.log('[PWA] User choice:', outcome);

    if (outcome === 'accepted') {
        console.log('[PWA] User accepted the install prompt');
        // Clear dismissal flags
        localStorage.removeItem('installPromptDismissed');
    } else {
        console.log('[PWA] User dismissed the install prompt');
    }

    // Clear the deferred prompt
    deferredPrompt = null;

    // Hide the install banner and button
    const installPrompt = document.getElementById('installPrompt');
    if (installPrompt) {
        installPrompt.classList.add('d-none');
    }

    const installAppBtn = document.getElementById('installAppBtn');
    if (installAppBtn) {
        installAppBtn.classList.add('d-none');
    }
}

// Handle install button click (set up after DOM loads)
document.addEventListener('DOMContentLoaded', () => {
    // Show install prompt on page load
    showInstallPrompt();

    // Handle permanent install button in header
    const installAppBtn = document.getElementById('installAppBtn');
    if (installAppBtn) {
        installAppBtn.addEventListener('click', handleInstallClick);

        // Show button for iOS even without beforeinstallprompt
        if (isIOS() && !isStandalone()) {
            installAppBtn.classList.remove('d-none');
        }
    }

    // Handle banner install button
    const installButton = document.getElementById('install-pwa-button');
    if (installButton) {
        installButton.addEventListener('click', handleInstallClick);
    }

    // Handle close button on Android/Desktop install prompt
    const installPromptClose = document.querySelector('#installPrompt .btn-close');
    if (installPromptClose) {
        installPromptClose.addEventListener('click', () => {
            localStorage.setItem('installPromptDismissed', 'true');
        });
    }

    // Handle close button on iOS install prompt
    const iosInstallPromptClose = document.querySelector('#iosInstallPrompt .btn-close');
    if (iosInstallPromptClose) {
        iosInstallPromptClose.addEventListener('click', () => {
            localStorage.setItem('iosInstallPromptDismissed', 'true');
        });
    }
});

// Detect if app is installed
window.addEventListener('appinstalled', () => {
    console.log('[PWA] App installed successfully');

    // Hide install prompt
    const installPrompt = document.getElementById('installPrompt');
    if (installPrompt) {
        installPrompt.classList.add('d-none');
    }

    // Hide install button
    const installAppBtn = document.getElementById('installAppBtn');
    if (installAppBtn) {
        installAppBtn.classList.add('d-none');
    }

    // Clear dismissal flags
    localStorage.removeItem('installPromptDismissed');
    localStorage.removeItem('iosInstallPromptDismissed');

    // Show success message
    showToast('App installed successfully!', 'success');
});

// Check if running as PWA
function isPWA() {
    return window.matchMedia('(display-mode: standalone)').matches ||
           window.navigator.standalone === true;
}

// Show toast notification
function showToast(message, type = 'info') {
    const toast = document.createElement('div');
    toast.className = `toast-notification toast-${type}`;
    toast.textContent = message;
    toast.style.cssText = `
        position: fixed;
        bottom: 20px;
        left: 50%;
        transform: translateX(-50%);
        background: ${type === 'success' ? '#28a745' : type === 'error' ? '#dc3545' : '#17a2b8'};
        color: white;
        padding: 15px 25px;
        border-radius: 25px;
        box-shadow: 0 4px 12px rgba(0,0,0,0.3);
        z-index: 10000;
        animation: slideUp 0.3s ease-out;
    `;
    
    document.body.appendChild(toast);
    
    setTimeout(() => {
        toast.style.animation = 'slideDown 0.3s ease-out';
        setTimeout(() => {
            document.body.removeChild(toast);
        }, 300);
    }, 3000);
}

// Add CSS animations
const style = document.createElement('style');
style.textContent = `
    @keyframes slideUp {
        from {
            transform: translateX(-50%) translateY(100px);
            opacity: 0;
        }
        to {
            transform: translateX(-50%) translateY(0);
            opacity: 1;
        }
    }
    
    @keyframes slideDown {
        from {
            transform: translateX(-50%) translateY(0);
            opacity: 1;
        }
        to {
            transform: translateX(-50%) translateY(100px);
            opacity: 0;
        }
    }
`;
document.head.appendChild(style);

// VAPID public key for push notifications
const VAPID_PUBLIC_KEY = 'BEl62iUYgUivxIkv69yViEuiBIa-Ib9-SkvMeAtA3LFgDzkrxZJjSgSnfckjBJuBkr3qBUYIHBQFLXYp5Nksh8U';

// Push Notification Support
async function requestNotificationPermission() {
    if (!('Notification' in window)) {
        console.log('[PWA] Notifications not supported');
        showToast('Notifications are not supported on this device', 'error');
        return false;
    }
    
    if (Notification.permission === 'granted') {
        console.log('[PWA] Notification permission already granted');
        return true;
    }
    
    if (Notification.permission === 'denied') {
        console.log('[PWA] Notification permission denied');
        showToast('Notification permission was denied. Please enable it in your browser settings.', 'error');
        return false;
    }
    
    // Request permission
    const permission = await Notification.requestPermission();
    
    if (permission === 'granted') {
        console.log('[PWA] Notification permission granted');
        return true;
    } else {
        console.log('[PWA] Notification permission denied by user');
        showToast('Notification permission denied', 'error');
        return false;
    }
}

// Subscribe to push notifications
async function subscribeToPushNotifications() {
    try {
        // First request permission
        const hasPermission = await requestNotificationPermission();
        
        if (!hasPermission) {
            return null;
        }
        
        // Wait for service worker to be ready
        const registration = await navigator.serviceWorker.ready;
        
        // Check if already subscribed
        let subscription = await registration.pushManager.getSubscription();
        
        if (!subscription) {
            // Subscribe to push notifications
            subscription = await registration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: urlBase64ToUint8Array(VAPID_PUBLIC_KEY)
            });
            
            console.log('[PWA] Push subscription created:', subscription);
        } else {
            console.log('[PWA] Using existing push subscription');
        }
        
        // ALWAYS send subscription to server (even if it already exists in browser)
        // This ensures the database has the subscription
        const response = await fetch(`${APP_CONFIG.urlPath}/api/notifications/subscribe`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(subscription.toJSON())
        });
        
        if (!response.ok) {
            throw new Error('Failed to save subscription on server');
        }
        
        const result = await response.json();
        console.log('[PWA] Subscription saved on server:', result);
        
        showToast('Notifications enabled! You will receive daily reminders.', 'success');
        
        return subscription;
    } catch (error) {
        console.error('[PWA] Push subscription failed:', error);
        showToast('Failed to enable notifications: ' + error.message, 'error');
        return null;
    }
}

// Unsubscribe from push notifications
async function unsubscribeFromPushNotifications() {
    try {
        const registration = await navigator.serviceWorker.ready;
        const subscription = await registration.pushManager.getSubscription();
        
        if (!subscription) {
            console.log('[PWA] No active subscription to unsubscribe from');
            return true;
        }
        
        // Unsubscribe from push manager
        await subscription.unsubscribe();
        
        // Remove subscription from server
        await fetch(`${APP_CONFIG.urlPath}/api/notifications/unsubscribe`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(subscription.toJSON())
        });
        
        console.log('[PWA] Successfully unsubscribed from push notifications');
        showToast('Notifications disabled', 'info');
        
        return true;
    } catch (error) {
        console.error('[PWA] Unsubscribe failed:', error);
        showToast('Failed to disable notifications', 'error');
        return false;
    }
}

// Check notification subscription status
async function checkNotificationStatus() {
    try {
        if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
            return { supported: false, subscribed: false };
        }
        
        const registration = await navigator.serviceWorker.ready;
        const subscription = await registration.pushManager.getSubscription();
        
        return {
            supported: true,
            subscribed: subscription !== null,
            permission: Notification.permission
        };
    } catch (error) {
        console.error('[PWA] Failed to check notification status:', error);
        return { supported: false, subscribed: false };
    }
}

// Helper function to convert VAPID key
function urlBase64ToUint8Array(base64String) {
    const padding = '='.repeat((4 - base64String.length % 4) % 4);
    const base64 = (base64String + padding)
        .replace(/\-/g, '+')
        .replace(/_/g, '/');
    
    const rawData = window.atob(base64);
    const outputArray = new Uint8Array(rawData.length);
    
    for (let i = 0; i < rawData.length; ++i) {
        outputArray[i] = rawData.charCodeAt(i);
    }
    
    return outputArray;
}

// Check online/offline status
window.addEventListener('online', () => {
    console.log('[PWA] Back online');
    showToast('You are back online!', 'success');
});

window.addEventListener('offline', () => {
    console.log('[PWA] Gone offline');
    showToast('You are offline. Some features may be limited.', 'info');
});

// Initialize notifications on page load
async function initializeNotifications() {
    try {
        const status = await checkNotificationStatus();
        
        if (!status.supported) {
            console.log('[PWA] Push notifications not supported on this device');
            return;
        }
        
        console.log('[PWA] Notification status:', status);
        
        // If permission is granted, ensure subscription is saved to server
        if (status.permission === 'granted') {
            if (!status.subscribed) {
                console.log('[PWA] Permission granted but not subscribed, subscribing...');
                await subscribeToPushNotifications();
            } else {
                // Even if subscribed in browser, send to server to ensure database has it
                console.log('[PWA] Verifying subscription with server...');
                const registration = await navigator.serviceWorker.ready;
                const subscription = await registration.pushManager.getSubscription();
                
                if (subscription) {
                    // Send to server silently (don't show toast)
                    try {
                        await fetch(`${APP_CONFIG.urlPath}/api/notifications/subscribe`, {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json'
                            },
                            body: JSON.stringify(subscription.toJSON())
                        });
                        console.log('[PWA] Subscription verified with server');
                    } catch (error) {
                        console.error('[PWA] Failed to verify subscription with server:', error);
                    }
                }
            }
        }
    } catch (error) {
        console.error('[PWA] Failed to initialize notifications:', error);
    }
}

// Log PWA status
console.log('[PWA] Running as PWA:', isPWA());
console.log('[PWA] Online status:', navigator.onLine);

// Initialize notifications when service worker is ready
if ('serviceWorker' in navigator && 'PushManager' in window) {
    navigator.serviceWorker.ready.then(() => {
        initializeNotifications();
    });
}
