/**
 * PWA Handler
 * SSCI Office Platform - Progressive Web App Management
 */

class PWAHandler {
    constructor() {
        this.deferredPrompt = null;
        this.isAppInstalled = false;
        this.installPromptShownTime = 0;
        this.init();
    }

    /**
     * Initialize PWA
     */
    init() {
        console.log('Initializing PWA handler');
        this.checkAppInstalled();
        this.setupInstallPrompt();
        this.registerServiceWorker();
        this.setupOfflineIndicator();
        this.setupPushNotifications();
    }

    /**
     * Check if app is already installed
     */
    checkAppInstalled() {
        // Check if running as installed PWA
        if (window.navigator.standalone === true) {
            this.isAppInstalled = true;
            console.log('App is running in standalone mode');
            return;
        }

        // Check display mode
        if (window.matchMedia('(display-mode: standalone)').matches) {
            this.isAppInstalled = true;
            console.log('App is installed (display-mode)');
            return;
        }

        window.addEventListener('beforeinstallprompt', () => {
            this.isAppInstalled = false;
        });

        window.addEventListener('appinstalled', () => {
            this.isAppInstalled = true;
            this.showInstallNotification();
            localStorage.setItem('appInstalled', 'true');
        });
    }

    /**
     * Setup install prompt
     */
    setupInstallPrompt() {
        window.addEventListener('beforeinstallprompt', (e) => {
            // Prevent the mini-infobar from appearing
            e.preventDefault();
            // Stash the event for later
            this.deferredPrompt = e;
            console.log('Install prompt available');
            // Show install prompt
            this.showInstallPrompt();
        });

        // For desktop/laptop - show install button if PWA
        if (!this.isAppInstalled && 'serviceWorker' in navigator) {
            this.checkInstallability();
        }
    }

    /**
     * Check if PWA is installable
     */
    checkInstallability() {
        // Show a banner for non-installed PWAs on desktop
        const installPromptDismissed = localStorage.getItem('installPromptDismissed');
        const dismissTime = installPromptDismissed ? parseInt(installPromptDismissed) : 0;

        // Show again after 7 days
        if (Date.now() - dismissTime > 7 * 24 * 60 * 60 * 1000) {
            this.showInstallBanner();
        }
    }

    /**
     * Show install banner
     */
    showInstallBanner() {
        if (this.isAppInstalled || !document.body) return;

        // Check if banner already exists
        if (document.getElementById('pwaInstallBanner')) return;

        const banner = document.createElement('div');
        banner.id = 'pwaInstallBanner';
        banner.className = 'fixed top-0 left-0 right-0 z-50 bg-gradient-to-r from-blue-600 to-blue-800 text-white shadow-lg animate-slide-down';
        banner.innerHTML = `
            <div style="max-width: 1200px; margin: 0 auto; padding: 16px; display: flex; align-items: center; justify-content: space-between; gap: 16px;">
                <div style="display: flex; align-items: center; gap: 12px; flex: 1;">
                    <i class="fas fa-mobile-alt" style="font-size: 24px;"></i>
                    <div>
                        <p style="margin: 0; font-weight: bold; font-size: 16px;">Install SSCI Office</p>
                        <p style="margin: 4px 0 0 0; font-size: 14px; opacity: 0.9;">Get instant access to the app on your device</p>
                    </div>
                </div>
                <div style="display: flex; gap: 8px; flex-wrap: wrap;">
                    <button id="pwaInstallBtn" style="background: white; color: #2563eb; border: none; padding: 10px 20px; border-radius: 4px; font-weight: bold; cursor: pointer; transition: all 0.3s ease; white-space: nowrap;">
                        <i class="fas fa-download"></i> Install App
                    </button>
                    <button id="pwaDismissBtn" style="background: rgba(255,255,255,0.2); color: white; border: none; padding: 10px 20px; border-radius: 4px; cursor: pointer; transition: all 0.3s ease; white-space: nowrap;">
                        Dismiss
                    </button>
                </div>
            </div>
        `;

        document.body.insertBefore(banner, document.body.firstChild);

        document.getElementById('pwaInstallBtn').addEventListener('click', () => {
            this.promptInstall();
        });

        document.getElementById('pwaDismissBtn').addEventListener('click', () => {
            banner.remove();
            localStorage.setItem('installPromptDismissed', Date.now().toString());
        });
    }

    /**
     * Show install prompt (traditional)
     */
    showInstallPrompt() {
        if (!this.deferredPrompt || this.isAppInstalled) return;

        // Check if user previously dismissed the prompt recently
        const dismissed = localStorage.getItem('installPromptDismissed');
        if (dismissed && Date.now() - parseInt(dismissed) < 7 * 24 * 60 * 60 * 1000) {
            return;
        }

        this.showInstallBanner();
    }

    /**
     * Prompt install
     */
    promptInstall() {
        if (!this.deferredPrompt) {
            console.log('Install prompt not available');
            return;
        }

        this.deferredPrompt.prompt();
        this.deferredPrompt.userChoice.then((choiceResult) => {
            if (choiceResult.outcome === 'accepted') {
                console.log('App installation accepted');
                localStorage.setItem('appInstalled', 'true');
                this.isAppInstalled = true;
                const banner = document.getElementById('pwaInstallBanner');
                if (banner) banner.remove();
            } else {
                console.log('App installation rejected');
            }
            this.deferredPrompt = null;
        });
    }

    /**
     * Show install notification
     */
    showInstallNotification() {
        if (typeof showToast === 'function') {
            showToast('success', 'SSCI Office has been installed successfully!');
        }
    }

    /**
     * Setup offline indicator
     */
    setupOfflineIndicator() {
        const updateOnlineStatus = () => {
            const indicator = document.getElementById('onlineIndicator');
            if (!indicator) return;

            if (navigator.onLine) {
                indicator.classList.add('hidden');
            } else {
                indicator.classList.remove('hidden');
            }
        };

        window.addEventListener('online', updateOnlineStatus);
        window.addEventListener('offline', updateOnlineStatus);

        // Initial check
        if (!navigator.onLine) {
            updateOnlineStatus();
        }
    }

    /**
     * Setup push notifications
     */
    setupPushNotifications() {
        if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
            console.log('Push notifications not supported');
            return;
        }

        navigator.serviceWorker.ready.then(registration => {
            // Check if user is already subscribed
            registration.pushManager.getSubscription().then(subscription => {
                if (subscription) {
                    console.log('Already subscribed to push notifications');
                    return;
                }

                // Ask for permission
                if (Notification.permission === 'granted') {
                    this.subscribeToPushNotifications(registration);
                } else if (Notification.permission !== 'denied') {
                    Notification.requestPermission().then(permission => {
                        if (permission === 'granted') {
                            this.subscribeToPushNotifications(registration);
                        }
                    });
                }
            });
        });
    }

    /**
     * Subscribe to push notifications
     */
    subscribeToPushNotifications(registration) {
        // Fetch VAPID key from server
        fetch('?page=api&endpoint=push/vapid-key')
            .then(response => response.json())
            .then(data => {
                if (data.vapidKey) {
                    const vapidKey = data.vapidKey;
                    registration.pushManager.subscribe({
                        userVisibleOnly: true,
                        applicationServerKey: this.urlBase64ToUint8Array(vapidKey)
                    }).then(subscription => {
                        console.log('✓ Push subscription successful');
                        // Send subscription to server
                        this.savePushSubscription(subscription);
                    }).catch(error => {
                        console.error('Push subscription error:', error);
                    });
                } else {
                    console.warn('VAPID key not configured on server');
                }
            })
            .catch(error => {
                console.error('Error fetching VAPID key:', error);
            });
    }

    /**
     * Convert VAPID key to Uint8Array
     */
    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;
    }

    /**
     * Save push subscription to server
     */
    savePushSubscription(subscription) {
        // Convert ArrayBuffer keys to base64
        const p256dh = subscription.getKey('p256dh');
        const auth = subscription.getKey('auth');
        
        const subscriptionData = {
            endpoint: subscription.endpoint,
            keys: {
                p256dh: this.arrayBufferToBase64(p256dh),
                auth: this.arrayBufferToBase64(auth)
            }
        };

        fetch('?page=api&endpoint=push/subscribe', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(subscriptionData)
        }).then(response => response.json())
          .then(data => {
              if (data.success) {
                  console.log('✓ Push subscription saved to server');
                  localStorage.setItem('pushSubscribed', 'true');
              } else {
                  console.error('Push subscription error:', data.error);
              }
          })
          .catch(error => {
              console.error('Error saving push subscription:', error);
          });
    }

    /**
     * Convert ArrayBuffer to Base64
     */
    arrayBufferToBase64(buffer) {
        const bytes = new Uint8Array(buffer);
        let binary = '';
        for (let i = 0; i < bytes.byteLength; i++) {
            binary += String.fromCharCode(bytes[i]);
        }
        return window.btoa(binary);
    }

    /**
     * Register service worker
     */
    registerServiceWorker() {
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.register('/service-worker.js')
                .then(registration => {
                    console.log('Service Worker registered:', registration);
                    this.checkForUpdates(registration);
                    this.setupUpdateListener(registration);
                })
                .catch(error => {
                    console.error('Service Worker registration failed:', error);
                });
        }
    }

    /**
     * Setup update listener for service worker updates
     */
    setupUpdateListener(registration) {
        registration.addEventListener('updatefound', () => {
            const newWorker = registration.installing;
            
            newWorker.addEventListener('statechange', () => {
                if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
                    // New service worker available
                    if (typeof showToast === 'function') {
                        showToast('info', 'App update available. Refresh to get the latest version.');
                    }
                }
            });
        });
    }

    /**
     * Check for service worker updates
     */
    checkForUpdates(registration) {
        // Check for updates every hour
        setInterval(() => {
            registration.update();
        }, 60 * 60 * 1000);
    }
}

// Initialize PWA handler when DOM is ready
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', () => {
        const pwaHandler = new PWAHandler();
        window.pwaHandler = pwaHandler;
    });
} else {
    const pwaHandler = new PWAHandler();
    window.pwaHandler = pwaHandler;
}

// Expose install method globally
window.installApp = () => {
    if (window.pwaHandler) {
        window.pwaHandler.promptInstall();
    }
};
