// Progressive Web App functionality
// Handles service worker registration and PWA features

class PWAManager {
    constructor() {
        this.swRegistration = null;
        this.vapidPublicKey = null;
        this.pushSubscription = null;
        this.init();
    }

    async init() {
        console.log('PWA: Initializing PWA Manager...');
        
        if ('serviceWorker' in navigator) {
            try {
                this.swRegistration = await navigator.serviceWorker.register('/sw.js');
                console.log('SW: Service Worker registered successfully');
                
                // Listen for updates
                this.swRegistration.addEventListener('updatefound', () => {
                    console.log('SW: New version available');
                    this.showUpdateNotification();
                });
                
            } catch (error) {
                console.log('SW: Service Worker registration failed:', error);
            }
        }

        // Setup PWA install prompt
        this.setupInstallPrompt();
        
        // Setup notifications (if enabled)
        this.setupNotifications();
        
        // Setup push notifications
        this.setupPushNotifications();
        
        // Show manual install option after 5 seconds if no prompt appeared and app not installed
        setTimeout(() => {
            if (!document.getElementById('pwa-install-btn') && !this.isInstalled()) {
                console.log('PWA: No install prompt appeared, showing manual install guide');
                this.showManualInstallButton();
            }
        }, 5000);
    }

    setupInstallPrompt() {
        let deferredPrompt;

        window.addEventListener('beforeinstallprompt', (e) => {
            console.log('PWA: beforeinstallprompt event fired');
            // Prevent Chrome 67 and earlier from automatically showing the prompt
            e.preventDefault();
            deferredPrompt = e;
            
            // Show custom install button
            this.showInstallButton(deferredPrompt);
        });

        window.addEventListener('appinstalled', () => {
            console.log('PWA: App was installed');
            this.hideInstallButton();
        });
        
        // Debug: Check if app is already installed
        if (this.isInstalled()) {
            console.log('PWA: App is already installed (standalone mode)');
            // Hide any existing install buttons
            this.hideInstallButton();
        } else {
            console.log('PWA: App is not installed, waiting for install prompt...');
            console.log('PWA: Current URL:', window.location.href);
            console.log('PWA: Display mode:', window.matchMedia('(display-mode: standalone)').matches ? 'standalone' : 'browser');
            console.log('PWA: User agent:', navigator.userAgent);
        }
        
        // Periodically check if app becomes installed (for cases where user installs via browser menu)
        setInterval(() => {
            if (this.isInstalled()) {
                this.hideInstallButton();
            }
        }, 2000);
    }

    showInstallButton(deferredPrompt) {
        // Don't show install button if app is already installed
        if (this.isInstalled()) {
            console.log('PWA: App already installed, skipping install button');
            return;
        }
        
        // Create install button
        const installBtn = document.createElement('button');
        installBtn.id = 'pwa-install-btn';
        installBtn.className = 'btn btn-primary btn-sm';
        installBtn.innerHTML = '<i class="fas fa-download"></i> Install App';
        installBtn.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 1000;
            box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
        `;

        installBtn.addEventListener('click', async () => {
            if (deferredPrompt) {
                deferredPrompt.prompt();
                const { outcome } = await deferredPrompt.userChoice;
                console.log('PWA: User response to install prompt:', outcome);
                deferredPrompt = null;
                this.hideInstallButton();
            }
        });

        document.body.appendChild(installBtn);
    }

    hideInstallButton() {
        const installBtn = document.getElementById('pwa-install-btn');
        if (installBtn) {
            installBtn.remove();
        }
    }

    showUpdateNotification() {
        // Show update available notification
        const notification = document.createElement('div');
        notification.className = 'alert alert-info alert-dismissible';
        notification.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            z-index: 1050;
            max-width: 300px;
        `;
        
        notification.innerHTML = `
            <strong>Update Available!</strong><br>
            A new version of the app is ready.
            <button type="button" class="btn btn-sm btn-outline-info ms-2" id="update-btn">
                Update Now
            </button>
            <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
        `;

        document.body.appendChild(notification);

        // Handle update
        document.getElementById('update-btn').addEventListener('click', () => {
            if (this.swRegistration && this.swRegistration.waiting) {
                this.swRegistration.waiting.postMessage({ type: 'SKIP_WAITING' });
                window.location.reload();
            }
        });
    }

    async setupNotifications() {
        // Check if notifications are supported and get permission
        if ('Notification' in window) {
            const permission = await this.requestNotificationPermission();
            console.log('Notifications permission:', permission);
        }
    }

    async requestNotificationPermission() {
        if (Notification.permission === 'default') {
            // Only request permission when user interacts with a relevant feature
            // For now, just return the current status
            return Notification.permission;
        }
        return Notification.permission;
    }

    // Show notification (if permission granted)
    showNotification(title, options = {}) {
        if (Notification.permission === 'granted') {
            const notification = new Notification(title, {
                icon: '/icons/icon-192x192.png',
                badge: '/icons/icon-72x72.png',
                tag: 'littleshop-admin',
                ...options
            });

            // Auto-close after 5 seconds
            setTimeout(() => {
                notification.close();
            }, 5000);

            return notification;
        }
    }

    // Show manual install button for browsers that don't auto-prompt
    showManualInstallButton() {
        // Don't show install button if app is already installed
        if (this.isInstalled()) {
            console.log('PWA: App already installed, skipping manual install button');
            return;
        }
        
        console.log('PWA: Showing manual install button');
        const installBtn = document.createElement('button');
        installBtn.id = 'pwa-install-btn';
        installBtn.className = 'btn btn-primary btn-sm';
        installBtn.innerHTML = '<i class="fas fa-mobile-alt"></i> Install as App';
        installBtn.style.cssText = `
            position: fixed;
            bottom: 20px;
            right: 20px;
            z-index: 1000;
            box-shadow: 0 4px 12px rgba(37, 99, 235, 0.3);
        `;

        installBtn.addEventListener('click', () => {
            const isChrome = navigator.userAgent.includes('Chrome');
            const isEdge = navigator.userAgent.includes('Edge');
            const isFirefox = navigator.userAgent.includes('Firefox');
            
            let instructions = 'To install this app:\\n\\n';
            
            if (isChrome || isEdge) {
                instructions += '1. Look for the install icon (⬇️) in the address bar\\n';
                instructions += '2. Or click the browser menu (⋮) → "Install LittleShop Admin"\\n';
                instructions += '3. Or check if there\'s an "Install app" option in the browser menu';
            } else if (isFirefox) {
                instructions += '1. Firefox doesn\'t support PWA installation yet\\n';
                instructions += '2. You can bookmark this page for easy access\\n';
                instructions += '3. Or use Chrome/Edge for the full PWA experience';
            } else {
                instructions += '1. Look for an install or "Add to Home Screen" option\\n';
                instructions += '2. Check your browser menu for app installation\\n';
                instructions += '3. Or bookmark this page for quick access';
            }
            
            alert(instructions);
        });

        document.body.appendChild(installBtn);
    }

    // Check if app is installed
    isInstalled() {
        return window.matchMedia('(display-mode: standalone)').matches ||
               window.navigator.standalone === true;
    }

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

        try {
            // Get VAPID public key from server
            await this.getVapidPublicKey();
            
            // Check if user is already subscribed
            await this.checkPushSubscription();
            
            // Simple logic: only show prompt if user is not subscribed
            if (!this.pushSubscription) {
                // Check if we've already asked this session
                if (!sessionStorage.getItem('pushNotificationPromptShown')) {
                    this.showPushNotificationSetup();
                    sessionStorage.setItem('pushNotificationPromptShown', 'true');
                }
            } else {
                console.log('PWA: User already subscribed to push notifications');
            }
            
        } catch (error) {
            console.error('PWA: Failed to setup push notifications:', error);
        }
    }

    async getVapidPublicKey() {
        try {
            const response = await fetch('/api/push/vapid-key');
            if (response.ok) {
                const data = await response.json();
                this.vapidPublicKey = data.publicKey;
                console.log('PWA: VAPID public key retrieved');
            } else {
                throw new Error('Failed to get VAPID public key');
            }
        } catch (error) {
            console.error('PWA: Error getting VAPID public key:', error);
            throw error;
        }
    }

    async checkPushSubscription() {
        if (!this.swRegistration) {
            return;
        }

        try {
            this.pushSubscription = await this.swRegistration.pushManager.getSubscription();
            if (this.pushSubscription) {
                console.log('PWA: User has active push subscription');
            } else {
                console.log('PWA: User is not subscribed to push notifications');
            }
        } catch (error) {
            console.error('PWA: Error checking push subscription:', error);
        }
    }

    async subscribeToPushNotifications() {
        if (!this.swRegistration || !this.vapidPublicKey) {
            throw new Error('Service worker or VAPID key not available');
        }

        try {
            // Check current permission status
            if (Notification.permission === 'denied') {
                throw new Error('Notification permission was denied. Please enable notifications in your browser settings.');
            }
            
            // Request notification permission if not already granted
            let permission = Notification.permission;
            if (permission === 'default') {
                permission = await Notification.requestPermission();
            }
            
            if (permission !== 'granted') {
                throw new Error('Notification permission is required for push notifications. Please allow notifications and try again.');
            }

            // Subscribe to push notifications
            const subscription = await this.swRegistration.pushManager.subscribe({
                userVisibleOnly: true,
                applicationServerKey: this.urlBase64ToUint8Array(this.vapidPublicKey)
            });

            // Send subscription to server with timeout
            console.log('PWA: Sending subscription to server...');
            const controller = new AbortController();
            const timeoutId = setTimeout(() => controller.abort(), 10000); // 10 second timeout
            
            const response = await fetch('/api/push/subscribe', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    endpoint: subscription.endpoint,
                    p256dh: btoa(String.fromCharCode(...new Uint8Array(subscription.getKey('p256dh')))),
                    auth: btoa(String.fromCharCode(...new Uint8Array(subscription.getKey('auth'))))
                }),
                credentials: 'same-origin',
                signal: controller.signal
            });
            
            clearTimeout(timeoutId);
            console.log('PWA: Server response received:', response.status, response.statusText);

            if (response.ok) {
                this.pushSubscription = subscription;
                console.log('PWA: Successfully subscribed to push notifications');
                this.hidePushNotificationSetup();
                return true;
            } else {
                throw new Error('Failed to save push subscription to server');
            }
        } catch (error) {
            console.error('PWA: Failed to subscribe to push notifications:', error);
            throw error;
        }
    }

    async unsubscribeFromPushNotifications() {
        if (!this.pushSubscription) {
            return true;
        }

        try {
            // Unsubscribe from push manager
            await this.pushSubscription.unsubscribe();

            // Notify server
            await fetch('/api/push/unsubscribe', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    endpoint: this.pushSubscription.endpoint
                }),
                credentials: 'same-origin'
            });

            this.pushSubscription = null;
            console.log('PWA: Successfully unsubscribed from push notifications');
            return true;
        } catch (error) {
            console.error('PWA: Failed to unsubscribe from push notifications:', error);
            throw error;
        }
    }

    showPushNotificationSetup() {
        // Check if setup UI already exists
        if (document.getElementById('push-notification-setup')) {
            return;
        }

        const setupDiv = document.createElement('div');
        setupDiv.id = 'push-notification-setup';
        setupDiv.className = 'alert alert-info alert-dismissible';
        setupDiv.style.cssText = `
            position: fixed;
            top: 80px;
            right: 20px;
            z-index: 1050;
            max-width: 350px;
        `;
        
        setupDiv.innerHTML = `
            <div class="d-flex align-items-center">
                <i class="fas fa-bell me-2"></i>
                <div class="flex-grow-1">
                    <strong>Push Notifications</strong><br>
                    <small>Get notified of new orders and updates</small>
                </div>
                <div class="ms-2">
                    <button type="button" class="btn btn-sm btn-primary" id="subscribe-push-btn">Enable</button>
                </div>
            </div>
            <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
        `;

        document.body.appendChild(setupDiv);

        // Add event listener for subscribe button
        const subscribeBtn = document.getElementById('subscribe-push-btn');

        if (subscribeBtn) {
            subscribeBtn.addEventListener('click', async () => {
                subscribeBtn.disabled = true;
                subscribeBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-1"></i>Subscribing...';
                
                try {
                    // Add timeout to prevent infinite hanging
                    const subscriptionPromise = this.subscribeToPushNotifications();
                    const timeoutPromise = new Promise((_, reject) => 
                        setTimeout(() => reject(new Error('Push subscription timed out after 15 seconds. This may be due to network connectivity or browser push service issues.')), 15000)
                    );
                    
                    await Promise.race([subscriptionPromise, timeoutPromise]);
                    
                    this.showNotification('Push notifications enabled!', {
                        body: 'You will now receive notifications for new orders and updates.'
                    });
                } catch (error) {
                    console.error('PWA: Push subscription failed:', error);
                    
                    // Provide user-friendly error messages
                    let userMessage = error.message;
                    if (error.message.includes('permission')) {
                        userMessage = 'Please allow notifications when your browser asks, then try again.';
                    } else if (error.message.includes('timeout')) {
                        userMessage = 'Push notification setup timed out. This may be due to network or browser issues. Please try again or check your internet connection.';
                    }
                    
                    alert('Failed to enable push notifications: ' + userMessage);
                    subscribeBtn.disabled = false;
                    subscribeBtn.innerHTML = 'Enable';
                }
            });
        }
    }

    hidePushNotificationSetup() {
        const setupDiv = document.getElementById('push-notification-setup');
        if (setupDiv) {
            setupDiv.remove();
            console.log('PWA: Push notification setup hidden');
        }
    }

    async sendTestNotification() {
        try {
            const response = await fetch('/api/push/test', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    title: 'Test Notification',
                    body: 'This is a test push notification from LittleShop Admin!'
                }),
                credentials: 'same-origin'
            });

            const result = await response.json();
            if (response.ok) {
                console.log('PWA: Test notification sent successfully');
                return true;
            } else {
                throw new Error(result.error || 'Failed to send test notification');
            }
        } catch (error) {
            console.error('PWA: Failed to send test notification:', error);
            throw error;
        }
    }

    // Helper function to convert VAPID key
    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;
    }
}

// Initialize PWA Manager
const pwaManager = new PWAManager();
window.pwaManager = pwaManager;

// Expose notification functions globally
window.showNotification = (title, options) => pwaManager.showNotification(title, options);
window.sendTestPushNotification = () => pwaManager.sendTestNotification();
window.subscribeToPushNotifications = () => pwaManager.subscribeToPushNotifications();
window.unsubscribeFromPushNotifications = () => pwaManager.unsubscribeFromPushNotifications();