/**
 * Notification System
 * 
 * This module handles real-time notifications using WebSockets,
 * as well as notifications display, management, and settings.
 */

// Notification system namespace
const NotificationSystem = (function() {
    // Private variables
    let webSocket;
    let connected = false;
    let notificationCount = 0;
    let notifications = [];
    let notificationSettings = null;
    let notificationSound;
    
    // DOM elements
    let notificationDropdown;
    let notificationBadge;
    let notificationList;
    
    /**
     * Initialize the notification system
     */
    function init() {
        // Initialize DOM elements
        notificationDropdown = document.getElementById('notification-dropdown');
        notificationBadge = document.getElementById('notification-badge');
        notificationList = document.getElementById('notification-list');
        
        // Initialize notification sound
        notificationSound = new Audio('/frontend/assets/sounds/notification.mp3');
        
        // Load notification settings
        loadSettings();
        
        // Connect to WebSocket
        connectWebSocket();
        
        // Load initial notifications
        loadNotifications();
        
        // Set up event listeners
        setupEventListeners();
    }
    
    /**
     * Connect to WebSocket server
     */
    function connectWebSocket() {
        // Create WebSocket connection
        const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
        const host = window.location.hostname;
        const port = 8080; // WebSocket server port
        
        webSocket = new WebSocket(`${protocol}//${host}:${port}`);
        
        // WebSocket event handlers
        webSocket.onopen = handleWebSocketOpen;
        webSocket.onmessage = handleWebSocketMessage;
        webSocket.onclose = handleWebSocketClose;
        webSocket.onerror = handleWebSocketError;
    }
    
    /**
     * Handle WebSocket open event
     */
    function handleWebSocketOpen() {
        console.log('WebSocket connected');
        connected = true;
        
        // Authenticate with WebSocket server
        authenticate();
    }
    
    /**
     * Authenticate with WebSocket server
     */
    function authenticate() {
        if (connected) {
            // Get user info from session
            const userId = USER_ID; // Should be set globally
            const userType = USER_TYPE; // Should be set globally
            const authToken = AUTH_TOKEN; // Should be set globally
            
            // Send authentication message
            webSocket.send(JSON.stringify({
                type: 'authenticate',
                user_id: userId,
                user_type: userType,
                auth_token: authToken
            }));
        }
    }
    
    /**
     * Handle WebSocket message event
     * 
     * @param {MessageEvent} event WebSocket message event
     */
    function handleWebSocketMessage(event) {
        try {
            const message = JSON.parse(event.data);
            
            // Handle different message types
            switch (message.type) {
                case 'auth_response':
                    handleAuthResponse(message);
                    break;
                case 'notification':
                    handleNotification(message.data);
                    break;
                case 'status_update':
                    // Handle status update if needed
                    break;
                case 'error':
                    console.error('WebSocket error:', message.message);
                    break;
                default:
                    console.log('Unknown message type:', message.type);
            }
        } catch (error) {
            console.error('Error processing WebSocket message:', error);
        }
    }
    
    /**
     * Handle authentication response
     * 
     * @param {Object} response Authentication response
     */
    function handleAuthResponse(response) {
        if (response.success) {
            console.log('WebSocket authentication successful');
        } else {
            console.error('WebSocket authentication failed:', response.message);
            // Retry authentication after a delay
            setTimeout(authenticate, 5000);
        }
    }
    
    /**
     * Handle WebSocket close event
     */
    function handleWebSocketClose() {
        console.log('WebSocket disconnected');
        connected = false;
        
        // Reconnect after a delay
        setTimeout(connectWebSocket, 5000);
    }
    
    /**
     * Handle WebSocket error event
     * 
     * @param {Event} error WebSocket error event
     */
    function handleWebSocketError(error) {
        console.error('WebSocket error:', error);
        connected = false;
    }
    
    /**
     * Handle incoming notification
     * 
     * @param {Object} notification Notification object
     */
    function handleNotification(notification) {
        // Add notification to list
        notifications.unshift(notification);
        
        // Update notification count
        notificationCount++;
        updateNotificationBadge();
        
        // Display notification
        displayNotification(notification);
        
        // Play sound if enabled
        playNotificationSound();
    }
    
    /**
     * Load notification settings
     */
    function loadSettings() {
        // Get user info from session
        const userId = USER_ID; // Should be set globally
        const userType = USER_TYPE; // Should be set globally
        
        // Fetch settings from API
        fetch(`/api/notifications/settings.php?user_id=${userId}&user_type=${userType}`)
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    notificationSettings = data.data;
                    console.log('Notification settings loaded:', notificationSettings);
                } else {
                    console.error('Error loading notification settings:', data.message);
                }
            })
            .catch(error => {
                console.error('Error fetching notification settings:', error);
            });
    }
    
    /**
     * Load initial notifications
     */
    function loadNotifications() {
        // Get user info from session
        const userId = USER_ID; // Should be set globally
        const userType = USER_TYPE; // Should be set globally
        
        // Fetch notifications from API
        fetch(`/api/notifications/list.php?user_id=${userId}&user_type=${userType}&limit=10&offset=0`)
            .then(response => response.json())
            .then(data => {
                if (data.success) {
                    // Store notifications
                    notifications = data.data.notifications;
                    
                    // Count unread notifications
                    notificationCount = notifications.filter(notification => notification.is_read === 0).length;
                    updateNotificationBadge();
                    
                    // Render notifications
                    renderNotificationList();
                } else {
                    console.error('Error loading notifications:', data.message);
                }
            })
            .catch(error => {
                console.error('Error fetching notifications:', error);
            });
    }
    
    /**
     * Update notification badge
     */
    function updateNotificationBadge() {
        if (notificationBadge) {
            notificationBadge.textContent = notificationCount;
            notificationBadge.style.display = notificationCount > 0 ? 'block' : 'none';
        }
    }
    
    /**
     * Render notification list
     */
    function renderNotificationList() {
        if (!notificationList) return;
        
        // Clear list
        notificationList.innerHTML = '';
        
        // Add notifications
        if (notifications.length === 0) {
            notificationList.innerHTML = '<div class="dropdown-item text-center">No notifications</div>';
        } else {
            notifications.slice(0, 5).forEach(notification => {
                const item = createNotificationItem(notification);
                notificationList.appendChild(item);
            });
            
            // Add "View all" link
            const viewAllItem = document.createElement('a');
            viewAllItem.href = '/adminlte/notifications.php';
            viewAllItem.className = 'dropdown-item dropdown-footer';
            viewAllItem.textContent = 'See All Notifications';
            notificationList.appendChild(viewAllItem);
        }
    }
    
    /**
     * Create notification item element
     * 
     * @param {Object} notification Notification object
     * @return {HTMLElement} Notification item element
     */
    function createNotificationItem(notification) {
        const item = document.createElement('div');
        item.className = 'dropdown-item';
        item.dataset.notificationId = notification.id;
        
        // Add read/unread class
        if (notification.is_read === 0) {
            item.classList.add('unread');
        }
        
        // Set notification icon based on type
        let icon = 'fas fa-bell';
        let iconColor = 'text-info';
        
        switch (notification.type) {
            case 'info':
                icon = 'fas fa-info-circle';
                iconColor = 'text-info';
                break;
            case 'success':
                icon = 'fas fa-check-circle';
                iconColor = 'text-success';
                break;
            case 'warning':
                icon = 'fas fa-exclamation-triangle';
                iconColor = 'text-warning';
                break;
            case 'error':
                icon = 'fas fa-times-circle';
                iconColor = 'text-danger';
                break;
            case 'assignment':
                icon = 'fas fa-user-check';
                iconColor = 'text-primary';
                break;
            case 'announcement':
                icon = 'fas fa-bullhorn';
                iconColor = 'text-purple';
                break;
            case 'event':
                icon = 'fas fa-calendar-alt';
                iconColor = 'text-success';
                break;
            case 'payment':
                icon = 'fas fa-credit-card';
                iconColor = 'text-warning';
                break;
            case 'membership':
                icon = 'fas fa-id-card';
                iconColor = 'text-info';
                break;
        }
        
        // Format date
        const date = new Date(notification.created_at);
        const formattedDate = date.toLocaleString();
        
        // Create HTML
        item.innerHTML = `
            <div class="media">
                <div class="mr-3">
                    <i class="${icon} ${iconColor}" style="font-size: 24px;"></i>
                </div>
                <div class="media-body">
                    <h3 class="dropdown-item-title">
                        ${notification.title}
                        <span class="float-right text-sm ${iconColor}"><i class="fas fa-circle"></i></span>
                    </h3>
                    <p class="text-sm">${notification.message}</p>
                    <p class="text-sm text-muted"><i class="far fa-clock mr-1"></i> ${formattedDate}</p>
                </div>
            </div>
        `;
        
        // Add click event to mark as read
        item.addEventListener('click', () => {
            markAsRead(notification.id);
        });
        
        return item;
    }
    
    /**
     * Display browser notification
     * 
     * @param {Object} notification Notification object
     */
    function displayNotification(notification) {
        // Check if browser notifications are enabled in settings
        if (!notificationSettings || !notificationSettings.browser_notifications) {
            return;
        }
        
        // Check if browser supports notifications
        if (!("Notification" in window)) {
            console.warn("This browser does not support desktop notification");
            return;
        }
        
        // Check if we have permission
        if (Notification.permission === "granted") {
            // Create notification
            createBrowserNotification(notification);
        } else if (Notification.permission !== "denied") {
            // Request permission
            Notification.requestPermission().then(permission => {
                if (permission === "granted") {
                    createBrowserNotification(notification);
                }
            });
        }
    }
    
    /**
     * Create browser notification
     * 
     * @param {Object} notification Notification object
     */
    function createBrowserNotification(notification) {
        const options = {
            body: notification.message,
            icon: '/frontend/assets/images/logo.png',
            tag: `notification-${notification.id}`
        };
        
        const browserNotification = new Notification(notification.title, options);
        
        // Handle click on notification
        browserNotification.onclick = function() {
            window.focus();
            markAsRead(notification.id);
            this.close();
        };
        
        // Auto-close after 10 seconds
        setTimeout(() => {
            browserNotification.close();
        }, 10000);
    }
    
    /**
     * Play notification sound
     */
    function playNotificationSound() {
        // Check if sound notifications are enabled in settings
        if (!notificationSettings || !notificationSettings.sound_notifications) {
            return;
        }
        
        // Play sound
        if (notificationSound) {
            notificationSound.play().catch(error => {
                console.warn('Error playing notification sound:', error);
            });
        }
    }
    
    /**
     * Mark notification as read
     * 
     * @param {number} notificationId Notification ID
     */
    function markAsRead(notificationId) {
        // Get user info from session
        const userId = USER_ID; // Should be set globally
        const userType = USER_TYPE; // Should be set globally
        
        // Send API request
        fetch('/api/notifications/mark-read.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify({
                notification_id: notificationId,
                user_id: userId,
                user_type: userType
            })
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                // Update notification in list
                const index = notifications.findIndex(notification => notification.id === notificationId);
                if (index !== -1) {
                    // Check if notification was unread
                    if (notifications[index].is_read === 0) {
                        // Decrement count
                        notificationCount--;
                        updateNotificationBadge();
                    }
                    
                    // Mark as read
                    notifications[index].is_read = 1;
                    
                    // Re-render list
                    renderNotificationList();
                }
            } else {
                console.error('Error marking notification as read:', data.message);
            }
        })
        .catch(error => {
            console.error('Error sending mark as read request:', error);
        });
    }
    
    /**
     * Set up event listeners
     */
    function setupEventListeners() {
        // Notification dropdown toggle
        if (notificationDropdown) {
            notificationDropdown.addEventListener('click', function(event) {
                // Prevent default action (for <a> tags)
                event.preventDefault();
                
                // Toggle dropdown
                $(this).parent().toggleClass('show');
                $(this).next('.dropdown-menu').toggleClass('show');
            });
        }
        
        // Close dropdown when clicking outside
        document.addEventListener('click', function(event) {
            if (notificationDropdown && !notificationDropdown.contains(event.target) && 
                notificationList && !notificationList.contains(event.target)) {
                $(notificationDropdown).parent().removeClass('show');
                $(notificationList).removeClass('show');
            }
        });
    }
    
    /**
     * Create and send a notification
     * 
     * @param {Object} notificationData Notification data
     * @return {Promise} Promise with response
     */
    function createNotification(notificationData) {
        return fetch('/api/notifications/create.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(notificationData)
        })
        .then(response => response.json());
    }
    
    /**
     * Update notification settings
     * 
     * @param {Object} settings New settings
     * @return {Promise} Promise with response
     */
    function updateSettings(settings) {
        // Get user info from session
        const userId = USER_ID; // Should be set globally
        const userType = USER_TYPE; // Should be set globally
        
        // Add user info to settings
        const data = {
            ...settings,
            user_id: userId,
            user_type: userType
        };
        
        return fetch('/api/notifications/settings.php', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json'
            },
            body: JSON.stringify(data)
        })
        .then(response => response.json())
        .then(data => {
            if (data.success) {
                // Update local settings
                notificationSettings = settings;
            }
            return data;
        });
    }
    
    // Public API
    return {
        init,
        createNotification,
        updateSettings,
        markAsRead
    };
})();

// Initialize notification system when document is ready
document.addEventListener('DOMContentLoaded', function() {
    NotificationSystem.init();
});
