// PWA functionality for Innovaxcess Attendance

class PWAHandler {
    constructor() {
        this.deferredPrompt = null;
        this.installPromptShown = false;
        this.init();
    }

    init() {
        this.listenForInstallPrompt();
        this.checkIfAppIsInstalled();
        this.setupOfflineDetection();
        this.registerBackgroundSync();
        this.requestNotificationPermission();
    }

    // Listen for beforeinstallprompt event
    listenForInstallPrompt() {
        window.addEventListener('beforeinstallprompt', (e) => {
            // Prevent Chrome 67 and earlier from automatically showing the prompt
            e.preventDefault();
            // Stash the event so it can be triggered later
            this.deferredPrompt = e;
            
            // Show install prompt after 5 seconds
            if (!this.installPromptShown) {
                setTimeout(() => {
                    this.showInstallPrompt();
                }, 5000);
            }
        });
    }

    // Show install prompt
    showInstallPrompt() {
        if (this.deferredPrompt && !this.installPromptShown) {
            const promptElement = document.getElementById('pwaInstallPrompt');
            if (promptElement) {
                promptElement.classList.remove('hidden');
                this.installPromptShown = true;
                
                // Add click handler to install button
                document.getElementById('installAppBtn').addEventListener('click', () => {
                    this.installApp();
                });
            }
        }
    }

    // Hide install prompt
    hideInstallPrompt() {
        const promptElement = document.getElementById('pwaInstallPrompt');
        if (promptElement) {
            promptElement.classList.add('hidden');
        }
    }

    // Install app
    async installApp() {
        if (this.deferredPrompt) {
            // Show the install prompt
            this.deferredPrompt.prompt();
            
            // Wait for the user to respond to the prompt
            const choiceResult = await this.deferredPrompt.userChoice;
            
            if (choiceResult.outcome === 'accepted') {
                console.log('User accepted the install prompt');
                this.hideInstallPrompt();
                this.showToast('App installed successfully!', 'success');
            } else {
                console.log('User dismissed the install prompt');
            }
            
            // Clear the deferredPrompt variable
            this.deferredPrompt = null;
        }
    }

    // Check if app is already installed
    checkIfAppIsInstalled() {
        if (window.matchMedia('(display-mode: standalone)').matches || 
            window.navigator.standalone === true) {
            console.log('App is running in standalone mode');
            document.body.classList.add('standalone-mode');
        }
    }

    // Setup offline detection
    setupOfflineDetection() {
        window.addEventListener('online', () => {
            this.updateOnlineStatus(true);
            this.syncOfflineData();
        });

        window.addEventListener('offline', () => {
            this.updateOnlineStatus(false);
        });

        // Initial check
        this.updateOnlineStatus(navigator.onLine);
    }

    // Update online status UI
    updateOnlineStatus(isOnline) {
        const statusElement = document.getElementById('onlineStatus');
        if (statusElement) {
            if (isOnline) {
                statusElement.innerHTML = '<i class="fas fa-wifi mr-1"></i> Online';
                statusElement.className = 'inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-green-100 text-green-800';
            } else {
                statusElement.innerHTML = '<i class="fas fa-wifi-slash mr-1"></i> Offline';
                statusElement.className = 'inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-red-100 text-red-800';
                this.showToast('You are offline. Data will sync when connection is restored.', 'warning');
            }
        }
    }

    // Register background sync
    async registerBackgroundSync() {
        if ('serviceWorker' in navigator && 'SyncManager' in window) {
            const registration = await navigator.serviceWorker.ready;
            
            // Register sync for visits
            try {
                await registration.sync.register('sync-visits');
                console.log('Background sync registered for visits');
            } catch (error) {
                console.log('Background sync registration failed:', error);
            }
            
            // Register sync for leaves
            try {
                await registration.sync.register('sync-leaves');
                console.log('Background sync registered for leaves');
            } catch (error) {
                console.log('Background sync registration failed:', error);
            }
        }
    }

    // Sync offline data
    async syncOfflineData() {
        if ('serviceWorker' in navigator) {
            const registration = await navigator.serviceWorker.ready;
            
            // Trigger sync for visits
            if (registration.sync) {
                try {
                    await registration.sync.register('sync-visits');
                    console.log('Sync triggered for visits');
                } catch (error) {
                    console.log('Sync registration failed:', error);
                }
            }
            
            // Show sync notification
            this.showToast('Syncing offline data...', 'info');
        }
    }

    // Request notification permission
    async requestNotificationPermission() {
        if ('Notification' in window && Notification.permission === 'default') {
            try {
                const permission = await Notification.requestPermission();
                if (permission === 'granted') {
                    console.log('Notification permission granted');
                    this.subscribeToPushNotifications();
                }
            } catch (error) {
                console.log('Error requesting notification permission:', error);
            }
        }
    }

    // Subscribe to push notifications
    async subscribeToPushNotifications() {
        if ('serviceWorker' in navigator && 'PushManager' in window) {
            try {
                const registration = await navigator.serviceWorker.ready;
                const subscription = await registration.pushManager.subscribe({
                    userVisibleOnly: true,
                    applicationServerKey: this.urlBase64ToUint8Array('{{ env("VAPID_PUBLIC_KEY") }}')
                });
                
                // Send subscription to server
                await this.sendSubscriptionToServer(subscription);
                console.log('Push notification subscription successful');
            } catch (error) {
                console.log('Failed to subscribe to push notifications:', error);
            }
        }
    }

    // Send subscription to server
    async sendSubscriptionToServer(subscription) {
        const response = await fetch('/api/push-subscribe', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
            },
            body: JSON.stringify(subscription)
        });
        
        if (!response.ok) {
            throw new Error('Failed to send subscription to server');
        }
    }

    // Convert base64 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;
    }

    // Show toast notification
    showToast(message, type = 'info') {
        const toast = document.createElement('div');
        toast.className = `fixed bottom-4 left-4 right-4 md:left-auto md:right-4 md:w-80 p-4 rounded-lg shadow-lg text-white ${
            type === 'success' ? 'bg-green-500' : 
            type === 'error' ? 'bg-red-500' : 
            type === 'warning' ? 'bg-yellow-500' : 
            'bg-blue-500'
        } transform translate-y-full transition-transform duration-300 z-50`;
        
        toast.innerHTML = `
            <div class="flex items-center">
                <i class="fas fa-${
                    type === 'success' ? 'check-circle' : 
                    type === 'error' ? 'exclamation-triangle' : 
                    type === 'warning' ? 'exclamation-circle' : 
                    'info-circle'
                } mr-3 text-lg"></i>
                <div class="flex-1">${message}</div>
                <button onclick="this.parentElement.parentElement.remove()" class="ml-3 text-white/80 hover:text-white">
                    <i class="fas fa-times"></i>
                </button>
            </div>
        `;
        
        document.body.appendChild(toast);
        
        // Animate in
        setTimeout(() => {
            toast.classList.remove('translate-y-full');
        }, 100);
        
        // Auto remove
        setTimeout(() => {
            toast.classList.add('translate-y-full');
            setTimeout(() => {
                if (toast.parentNode) {
                    toast.parentNode.removeChild(toast);
                }
            }, 300);
        }, 5000);
    }

    // Save data for offline use
    async saveOfflineData(storeName, data) {
        if ('indexedDB' in window) {
            try {
                const db = await this.openDB();
                const tx = db.transaction(storeName, 'readwrite');
                const store = tx.objectStore(storeName);
                await store.put(data);
                await tx.done;
                
                console.log(`Data saved offline in ${storeName}:`, data);
                
                // Request background sync
                if ('serviceWorker' in navigator && 'SyncManager' in window) {
                    const registration = await navigator.serviceWorker.ready;
                    await registration.sync.register(`sync-${storeName}`);
                }
                
                return true;
            } catch (error) {
                console.error('Error saving offline data:', error);
                return false;
            }
        }
        return false;
    }

    // Open IndexedDB
    openDB() {
        return new Promise((resolve, reject) => {
            const request = indexedDB.open('InnovaxcessDB', 1);
            
            request.onerror = () => reject(request.error);
            request.onsuccess = () => resolve(request.result);
            
            request.onupgradeneeded = (event) => {
                const db = event.target.result;
                
                // Create object stores if they don't exist
                if (!db.objectStoreNames.contains('pendingVisits')) {
                    db.createObjectStore('pendingVisits', { keyPath: 'id' });
                }
                if (!db.objectStoreNames.contains('pendingLeaves')) {
                    db.createObjectStore('pendingLeaves', { keyPath: 'id' });
                }
                if (!db.objectStoreNames.contains('locationData')) {
                    db.createObjectStore('locationData', { keyPath: 'timestamp' });
                }
            };
        });
    }

    // Check for app updates
    checkForUpdates() {
        if ('serviceWorker' in navigator) {
            navigator.serviceWorker.ready.then(registration => {
                registration.update();
            });
        }
    }
}

// Initialize PWA functionality
document.addEventListener('DOMContentLoaded', function() {
    window.PWA = new PWAHandler();
    
    // Add online status indicator to header
    const header = document.querySelector('header');
    if (header) {
        const statusIndicator = document.createElement('div');
        statusIndicator.id = 'onlineStatus';
        statusIndicator.className = 'inline-flex items-center px-2 py-1 rounded text-xs font-medium ml-2';
        statusIndicator.innerHTML = navigator.onLine ? 
            '<i class="fas fa-wifi mr-1"></i> Online' : 
            '<i class="fas fa-wifi-slash mr-1"></i> Offline';
        statusIndicator.className += navigator.onLine ? 
            ' bg-green-100 text-green-800' : ' bg-red-100 text-red-800';
        
        const userInfo = header.querySelector('.flex.items-center');
        if (userInfo) {
            userInfo.appendChild(statusIndicator);
        }
    }
    
    // Add install prompt component if not exists
    if (!document.getElementById('pwaInstallPrompt')) {
        const promptHTML = `
            <div id="pwaInstallPrompt" class="fixed bottom-4 right-4 max-w-sm bg-white rounded-lg shadow-xl border border-gray-200 z-50 hidden">
                <div class="p-4">
                    <div class="flex items-start">
                        <div class="flex-shrink-0 pt-1">
                            <div class="w-10 h-10 rounded-lg bg-gradient-to-r from-blue-500 to-blue-600 flex items-center justify-center">
                                <i class="fas fa-download text-white"></i>
                            </div>
                        </div>
                        <div class="ml-3 flex-1">
                            <h3 class="text-sm font-semibold text-gray-900">Install Innovaxcess App</h3>
                            <p class="mt-1 text-sm text-gray-600">Install this app on your device for better experience and offline access.</p>
                            <div class="mt-3 flex space-x-2">
                                <button id="installAppBtn" class="flex-1 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium py-2 px-3 rounded transition duration-200">
                                    Install App
                                </button>
                                <button onclick="window.PWA.hideInstallPrompt()" class="flex-1 bg-gray-200 hover:bg-gray-300 text-gray-800 text-sm font-medium py-2 px-3 rounded transition duration-200">
                                    Not Now
                                </button>
                            </div>
                        </div>
                        <button onclick="window.PWA.hideInstallPrompt()" class="ml-2 text-gray-400 hover:text-gray-600">
                            <i class="fas fa-times"></i>
                        </button>
                    </div>
                </div>
            </div>
        `;
        document.body.insertAdjacentHTML('beforeend', promptHTML);
    }
});

// Add to homescreen for iOS
function addToHomeScreen() {
    if (window.navigator.standalone) {
        return false;
    }
    
    if (/iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream) {
        const addToHomeMessage = document.getElementById('addToHomeMessage');
        if (addToHomeMessage) {
            addToHomeMessage.classList.remove('hidden');
        }
        return true;
    }
    return false;
}

// Check if running in standalone mode
function isRunningStandalone() {
    return (window.matchMedia('(display-mode: standalone)').matches) || 
           (window.navigator.standalone) || 
           (document.referrer.includes('android-app://'));
}

// Show iOS install instructions
function showIOSInstallInstructions() {
    const instructions = `
        <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
            <div class="bg-white rounded-xl max-w-md w-full p-6">
                <div class="text-center">
                    <div class="w-16 h-16 mx-auto mb-4 text-blue-600">
                        <i class="fas fa-share-square text-4xl"></i>
                    </div>
                    <h3 class="text-xl font-bold text-gray-800 mb-2">Add to Home Screen</h3>
                    <p class="text-gray-600 mb-4">To install this app on your iOS device:</p>
                    <ol class="text-left text-gray-700 space-y-2 mb-6">
                        <li>1. Tap the Share button <i class="fas fa-share ml-1"></i></li>
                        <li>2. Scroll down and tap "Add to Home Screen"</li>
                        <li>3. Tap "Add" in the top right corner</li>
                    </ol>
                    <button onclick="this.parentElement.parentElement.parentElement.remove()" 
                            class="w-full bg-blue-600 hover:bg-blue-700 text-white font-medium py-3 px-4 rounded-lg">
                        Got it!
                    </button>
                </div>
            </div>
        </div>
    `;
    document.body.insertAdjacentHTML('beforeend', instructions);
}