/**
 * ============================================================================
 * push-manager.js - Client-side Push Notification Manager
 * Handles: Permission requests, subscription, badge updates
 * ============================================================================
 */

(function(window) {
    'use strict';

    const PushManager = {
        // Configuration
        config: {
            vapidPublicKey: null, // Will be fetched from server
            apiEndpoint: '/ajax/push-subscription.php',
            swPath: '/pwa/service-worker.js',
        },

        // State
        state: {
            isSupported: false,
            isSubscribed: false,
            subscription: null,
            permission: 'default',
        },

        /**
         * Initialize push notification system
         */
        async init() {
            console.log('[PushManager] Initializing...');

            // Check browser support
            if (!('serviceWorker' in navigator) || !('PushManager' in window)) {
                console.warn('[PushManager] Push notifications not supported');
                this.state.isSupported = false;
                return;
            }

            this.state.isSupported = true;
            this.state.permission = Notification.permission;

            // Wait for service worker to be ready
            try {
                await navigator.serviceWorker.ready;
                
                // Fetch VAPID public key from server
                await this.fetchVapidKey();
                
                // Check if already subscribed
                await this.checkSubscription();
                
                // Set up UI buttons if they exist
                this.setupUI();
                
                console.log('[PushManager] Initialized successfully');
                
            } catch (error) {
                console.error('[PushManager] Initialization failed:', error);
            }
        },

        /**
         * Fetch VAPID public key from server
         */
        async fetchVapidKey() {
            try {
                const response = await fetch('/ajax/get-vapid-key.php');
                const data = await response.json();
                
                if (data.success) {
                    this.config.vapidPublicKey = data.publicKey;
                    console.log('[PushManager] VAPID key loaded');
                } else {
                    throw new Error('Failed to fetch VAPID key');
                }
            } catch (error) {
                console.error('[PushManager] VAPID key fetch failed:', error);
                throw error;
            }
        },

        /**
         * Check current subscription status
         */
        async checkSubscription() {
            try {
                const registration = await navigator.serviceWorker.ready;
                const subscription = await registration.pushManager.getSubscription();
                
                this.state.subscription = subscription;
                this.state.isSubscribed = subscription !== null;
                
                console.log('[PushManager] Subscription status:', this.state.isSubscribed);
                
                return subscription;
                
            } catch (error) {
                console.error('[PushManager] Check subscription failed:', error);
                return null;
            }
        },

        /**
         * Request notification permission and subscribe
         */
        async requestPermission() {
            if (!this.state.isSupported) {
                alert('Push notifications are not supported in your browser.');
                return false;
            }

            try {
                // Request permission
                const permission = await Notification.requestPermission();
                this.state.permission = permission;

                if (permission === 'granted') {
                    console.log('[PushManager] Permission granted');
                    
                    // Subscribe to push
                    await this.subscribe();
                    
                    // Show success message
                    if (typeof showToast === 'function') {
                        showToast('Push notifications enabled! 🔔', 'success');
                    }
                    
                    // Send test notification
                    await this.sendTestNotification();
                    
                    return true;
                    
                } else if (permission === 'denied') {
                    console.log('[PushManager] Permission denied');
                    
                    if (typeof showToast === 'function') {
                        showToast('Notifications blocked. Enable them in browser settings.', 'warning');
                    }
                    
                    return false;
                    
                } else {
                    console.log('[PushManager] Permission dismissed');
                    return false;
                }
                
            } catch (error) {
                console.error('[PushManager] Permission request failed:', error);
                return false;
            }
        },

        /**
         * Subscribe to push notifications
         */
        async subscribe() {
            try {
                const registration = await navigator.serviceWorker.ready;

                // Convert VAPID key to Uint8Array
                const applicationServerKey = this.urlBase64ToUint8Array(this.config.vapidPublicKey);

                // Subscribe
                const subscription = await registration.pushManager.subscribe({
                    userVisibleOnly: true,
                    applicationServerKey: applicationServerKey
                });

                this.state.subscription = subscription;
                this.state.isSubscribed = true;

                console.log('[PushManager] Subscribed:', subscription.endpoint);

                // Send subscription to server
                await this.sendSubscriptionToServer(subscription);

                return subscription;

            } catch (error) {
                console.error('[PushManager] Subscribe failed:', error);
                
                if (typeof showToast === 'function') {
                    showToast('Failed to enable notifications', 'error');
                }
                
                throw error;
            }
        },

        /**
         * Unsubscribe from push notifications
         */
        async unsubscribe() {
            try {
                if (!this.state.subscription) {
                    return;
                }

                await this.state.subscription.unsubscribe();
                
                // Remove from server
                await this.removeSubscriptionFromServer(this.state.subscription);

                this.state.subscription = null;
                this.state.isSubscribed = false;

                console.log('[PushManager] Unsubscribed');
                
                if (typeof showToast === 'function') {
                    showToast('Push notifications disabled', 'info');
                }

            } catch (error) {
                console.error('[PushManager] Unsubscribe failed:', error);
            }
        },

        /**
         * Send subscription to server
         */
        async sendSubscriptionToServer(subscription) {
            try {
                const response = await fetch(this.config.apiEndpoint, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        action: 'subscribe',
                        subscription: subscription.toJSON()
                    })
                });

                const data = await response.json();
                
                if (data.success) {
                    console.log('[PushManager] Subscription saved to server');
                } else {
                    console.error('[PushManager] Failed to save subscription:', data.message);
                }

            } catch (error) {
                console.error('[PushManager] Send subscription failed:', error);
            }
        },

        /**
         * Remove subscription from server
         */
        async removeSubscriptionFromServer(subscription) {
            try {
                const response = await fetch(this.config.apiEndpoint, {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                    },
                    body: JSON.stringify({
                        action: 'unsubscribe',
                        endpoint: subscription.endpoint
                    })
                });

                const data = await response.json();
                console.log('[PushManager] Subscription removed from server');

            } catch (error) {
                console.error('[PushManager] Remove subscription failed:', error);
            }
        },

        /**
         * Send test notification
         */
        async sendTestNotification() {
            try {
                const response = await fetch('/ajax/send-test-notification.php', {
                    method: 'POST'
                });

                const data = await response.json();
                
                if (data.success) {
                    console.log('[PushManager] Test notification sent');
                }

            } catch (error) {
                console.error('[PushManager] Test notification failed:', error);
            }
        },

        /**
         * Update app badge (call from service worker or client)
         */
        async updateBadge(count) {
            if ('setAppBadge' in navigator) {
                try {
                    if (count > 0) {
                        await navigator.setAppBadge(count);
                        console.log('[PushManager] Badge updated:', count);
                    } else {
                        await navigator.clearAppBadge();
                        console.log('[PushManager] Badge cleared');
                    }
                } catch (error) {
                    console.error('[PushManager] Badge update failed:', error);
                }
            }
        },

        /**
         * Clear app badge
         */
        async clearBadge() {
            if ('clearAppBadge' in navigator) {
                try {
                    await navigator.clearAppBadge();
                    console.log('[PushManager] Badge cleared');
                } catch (error) {
                    console.error('[PushManager] Badge clear failed:', error);
                }
            }
        },

        /**
         * Set up UI elements (enable/disable buttons)
         */
        setupUI() {
            // Enable notifications button
            const enableBtn = document.getElementById('enable-push-notifications');
            if (enableBtn) {
                if (this.state.isSubscribed) {
                    enableBtn.textContent = '🔔 Notifications Enabled';
                    enableBtn.classList.add('btn-success');
                    enableBtn.disabled = true;
                } else {
                    enableBtn.addEventListener('click', () => this.requestPermission());
                }
            }

            // Settings toggle
            const settingsToggle = document.getElementById('push-notification-toggle');
            if (settingsToggle) {
                settingsToggle.checked = this.state.isSubscribed;
                settingsToggle.addEventListener('change', async (e) => {
                    if (e.target.checked) {
                        await this.requestPermission();
                    } else {
                        await this.unsubscribe();
                    }
                });
            }
        },

        /**
         * Helper: 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;
        }
    };

    // Expose globally
    window.AIMSPushManager = PushManager;

    // Auto-initialize when DOM is ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => PushManager.init());
    } else {
        PushManager.init();
    }

})(window);