// Real-time notification system for competition events

class NotificationManager {
    constructor(eventId, userId = 'anonymous') {
        this.eventId = eventId;
        this.userId = userId;
        this.latestId = 0;
        this.pollingInterval = null;
        this.pollingRate = 3000; // 3 seconds
        this.toastContainer = null;
        this.isActive = true;
        this.notifications = [];
        this.connectionStatus = 'connecting'; // 'connected', 'disconnected', 'connecting'
        this.retryCount = 0;
        this.maxRetries = 5;
        this.apiAvailable = false;
        this.localMode = false; // If true, only use local notifications
        this.categoryFilters = new Set(); // Set of categories to show, empty = show all
        this.categoryColors = {
            'general': 'info',
            'competition': 'primary',
            'participant': 'success',
            'judge': 'light',
            'system': 'secondary',
            'heat': 'danger',
            'scoring': 'info',
            'technical': 'dark'
        };
        
        this.init();
    }
    
    init() {
        this.createToastContainer();
        
        // Test API availability first
        this.testConnection().then(available => {
            if (available) {
                this.apiAvailable = true;
                this.startPolling();
            } else {
                console.warn('Notification API not available, using local mode only');
                this.localMode = true;
                this.connectionStatus = 'local';
                this.updateConnectionStatus();
            }
        });
        
        // Handle page visibility change
        document.addEventListener('visibilitychange', () => {
            if (document.hidden) {
                this.pausePolling();
            } else {
                this.resumePolling();
            }
        });
        
        // Handle before unload
        window.addEventListener('beforeunload', () => {
            this.stopPolling();
        });
    }
    
    createToastContainer() {
        // Remove existing container if any
        const existing = document.querySelector('.notification-toast-container');
        if (existing) {
            existing.remove();
        }
        
        this.toastContainer = document.createElement('div');
        this.toastContainer.className = 'notification-toast-container position-fixed bottom-0 end-0 p-3';
        this.toastContainer.style.zIndex = '9999';
        this.toastContainer.style.maxWidth = '400px';
        document.body.appendChild(this.toastContainer);
    }
    
    async sendNotification(type, title, message = '', data = {}, category = 'general') {
        // If in local mode, just show local toast
        if (this.localMode || !this.apiAvailable) {
            this.showLocalToast(type, title, message, category);
            return { success: true, local: true };
        }
        
        try {
            const formData = new FormData();
            formData.append('action', 'send_notification');
            formData.append('event_id', this.eventId);
            formData.append('type', type);
            formData.append('title', title);
            formData.append('message', message);
            formData.append('user_id', this.userId);
            formData.append('data', JSON.stringify(data));
            formData.append('category', category);
            
            // Determine correct API path based on current location
            let apiUrl = '/v2/api/notification_api.php';
            if (window.location.pathname.includes('/admin/')) {
                apiUrl = '../api/notification_api.php';
            } else if (window.location.pathname.includes('/judge/')) {
                apiUrl = '../api/notification_api.php';
            }
            
            const response = await fetch(apiUrl, {
                method: 'POST',
                body: formData
            });
            
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }
            
            // Check if response is actually JSON
            const contentType = response.headers.get('content-type');
            if (!contentType || !contentType.includes('application/json')) {
                const text = await response.text();
                console.error('Expected JSON but received:', text.substring(0, 200));
                throw new Error('Server returned non-JSON response. Switching to local mode.');
            }
            
            const result = await response.json();
            
            if (!result.success) {
                throw new Error(result.error || 'Failed to send notification');
            }
            
            return result;
            
        } catch (error) {
            console.error('Error sending notification:', error);
            // Switch to local mode if API fails
            this.localMode = true;
            this.apiAvailable = false;
            this.updateConnectionStatus();
            
            // Show a fallback local toast
            this.showLocalToast(type, title, message + ' (Local mode - API unavailable)', category);
            return { success: true, local: true, error: error.message };
        }
    }
    
    async pollNotifications() {
        if (!this.isActive || this.localMode || !this.apiAvailable) return;
        
        try {
            // Determine correct API path based on current location
            let apiUrl = `/v2/api/notification_api.php?action=get_notifications&event_id=${this.eventId}&since=${this.latestId}&limit=20&user_id=${this.userId}`;
            if (window.location.pathname.includes('/admin/')) {
                apiUrl = `../api/notification_api.php?action=get_notifications&event_id=${this.eventId}&since=${this.latestId}&limit=20&user_id=${this.userId}`;
            } else if (window.location.pathname.includes('/judge/')) {
                apiUrl = `../api/notification_api.php?action=get_notifications&event_id=${this.eventId}&since=${this.latestId}&limit=20&user_id=${this.userId}`;
            }
            
            const response = await fetch(apiUrl);
            
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }
            
            // Check if response is actually JSON
            const contentType = response.headers.get('content-type');
            if (!contentType || !contentType.includes('application/json')) {
                const text = await response.text();
                console.error('Expected JSON but received:', text.substring(0, 200));
                throw new Error('Server returned non-JSON response. Switching to local mode.');
            }
            
            const data = await response.json();
            console.log('Polling response:', data);
            
            if (data.success && data.notifications.length > 0) {
                data.notifications.forEach(notification => {
                    // Check if this notification should be shown based on category filters
                    if (this.shouldShowNotification(notification)) {
                        // Check if we already have this notification to avoid duplicates
                        const alreadyShown = this.notifications.find(n => n.id === notification.id);
                        if (!alreadyShown) {
                            this.showToast(notification);
                        }
                    }
                });
                
                this.latestId = data.latest_id;
                // Only add new notifications to avoid duplicates
                data.notifications.forEach(notification => {
                    const exists = this.notifications.find(n => n.id === notification.id);
                    if (!exists) {
                        this.notifications.push(notification);
                    }
                });
            }
            
            // Connection successful
            if (this.connectionStatus !== 'connected') {
                this.connectionStatus = 'connected';
                this.retryCount = 0;
                this.updateConnectionStatus();
            }
            
        } catch (error) {
            console.error('Error polling notifications:', error);
            
            this.retryCount++;
            
            // If too many failures, switch to local mode
            if (this.retryCount > this.maxRetries) {
                console.warn('Too many API failures, switching to local mode');
                this.localMode = true;
                this.apiAvailable = false;
                this.connectionStatus = 'local';
                this.updateConnectionStatus();
                return;
            }
            
            this.connectionStatus = 'disconnected';
            this.updateConnectionStatus();
            
            // Exponential backoff for retries
            const retryDelay = Math.min(1000 * Math.pow(2, this.retryCount), 30000);
            setTimeout(() => {
                if (this.isActive && !this.localMode) {
                    this.pollNotifications();
                }
            }, retryDelay);
        }
    }
    
    // Check if notification should be shown based on category filters
    shouldShowNotification(notification) {
        // If no filters set, show all notifications
        if (this.categoryFilters.size === 0) {
            return true;
        }
        
        // Check if notification category is in the filter set
        return this.categoryFilters.has(notification.category || 'general');
    }
    
    // Set category filters (array of category names to show)
    setCategoryFilters(categories = []) {
        this.categoryFilters.clear();
        categories.forEach(category => this.categoryFilters.add(category));
    }
    
    // Add a category to filters
    addCategoryFilter(category) {
        this.categoryFilters.add(category);
    }
    
    // Remove a category from filters
    removeCategoryFilter(category) {
        this.categoryFilters.delete(category);
    }
    
    // Clear all category filters (show all notifications)
    clearCategoryFilters() {
        this.categoryFilters.clear();
    }
    
    updateConnectionStatus() {
        // Update any UI indicators for connection status
        const indicator = document.getElementById('liveStatusIndicator');
        if (indicator) {
            if (this.connectionStatus === 'connected') {
                indicator.innerHTML = '<i class="fas fa-circle me-1"></i>LIVE';
                indicator.className = 'badge bg-success live-pulse';
            } else if (this.connectionStatus === 'disconnected') {
                indicator.innerHTML = '<i class="fas fa-exclamation-triangle me-1"></i>DISCONNECTED';
                indicator.className = 'badge bg-danger';
            } else if (this.connectionStatus === 'local') {
                indicator.innerHTML = '<i class="fas fa-desktop me-1"></i>LOCAL';
                indicator.className = 'badge bg-warning';
            }
        }
    }
    
    showToast(notification) {
        // Check if notification is older than 40 seconds
        const notificationTime = new Date(notification.created_at).getTime();
        const currentTime = new Date().getTime();
        const ageInSeconds = (currentTime - notificationTime) / 1000;
        
        // Don't show toast notifications older than 40 seconds
        if (ageInSeconds > 40) {
            console.log(`Skipping toast for notification older than 40 seconds (${Math.round(ageInSeconds)}s old):`, notification.title);
            return;
        }
        
        const toast = this.createToastElement(notification);
        this.toastContainer.appendChild(toast);
        
        // Animate in
        setTimeout(() => {
            toast.classList.add('show');
        }, 100);
        
        // Auto-remove after duration based on type
        const duration = this.getToastDuration(notification.type);
        setTimeout(() => {
            this.removeToast(toast);
        }, duration);
        
        // Add sound notification for important messages
        this.playNotificationSound(notification.type);
    }
    
    // Fallback method for local toasts when API is unavailable
    showLocalToast(type, title, message = '', category = 'general') {
        const localNotification = {
            id: 'local_' + Date.now(),
            type: type,
            title: title,
            message: message,
            category: category,
            created_at: new Date().toISOString(),
            user_id: this.userId
        };
        
        this.showToast(localNotification);
    }
    
    createToastElement(notification) {
        const toast = document.createElement('div');
        
        // Use category-specific color if available, otherwise use notification type
        const colorType = this.categoryColors[notification.category] || notification.type;
        
        toast.className = `toast notification-toast bg-${colorType} border-0 mb-2`;
        toast.setAttribute('role', 'alert');
        toast.setAttribute('aria-live', 'assertive');
        toast.setAttribute('aria-atomic', 'true');
        toast.setAttribute('data-notification-id', notification.id);
        toast.setAttribute('data-category', notification.category || 'general');
        
        const iconMap = {
            'success': 'fa-check-circle',
            'danger': 'fa-exclamation-circle',
            'warning': 'fa-exclamation-triangle',
            'info': 'fa-info-circle'
        };
        
        const time = new Date(notification.created_at).toLocaleTimeString();
        const categoryBadge = notification.category ? `<span class="badge bg-light text-dark opacity-75 me-2">${notification.category}</span>` : '';
        
        toast.innerHTML = `
            <div class="toast-header bg-transparent tborder-0">
                <i class="fas ${iconMap[notification.type]} me-2"></i>
                <strong class="me-auto">${this.escapeHtml(notification.title)}</strong>
                ${categoryBadge}
                <small class="opacity-75">${time}</small>
                <button type="button" class="btn-close btn-close-white ms-2" aria-label="Close"></button>
            </div>
            ${notification.message ? `
                <div class="toast-body border-top border-light border-opacity-25">
                    ${notification.message}
                </div>
            ` : ''}
        `;
        
        // Add close button functionality
        const closeBtn = toast.querySelector('.btn-close');
        closeBtn.addEventListener('click', () => {
            this.removeToast(toast);
            this.markAsRead(notification.id);
        });
        
        return toast;
    }
    
    removeToast(toast) {
        toast.classList.remove('show');
        toast.style.opacity = '0';
        toast.style.transform = 'translateX(100%)';
        
        setTimeout(() => {
            if (toast.parentNode) {
                toast.parentNode.removeChild(toast);
            }
        }, 300);
    }
    
    getToastDuration(type) {
        const durations = {
            'danger': 30000,   // 30 seconds for errors
            'warning': 20000,  // 20 seconds for warnings
            'success': 15000,  // 15 seconds for success
            'info': 10000      // 10 seconds for info
        };
        
        return durations[type] || 15000;
    }
    
    playNotificationSound(type) {
        // Only play sound for important notifications
        if (type === 'danger' || type === 'warning') {
            try {
                // Create a simple beep sound
                const audioContext = new (window.AudioContext || window.webkitAudioContext)();
                const oscillator = audioContext.createOscillator();
                const gainNode = audioContext.createGain();
                
                oscillator.connect(gainNode);
                gainNode.connect(audioContext.destination);
                
                oscillator.frequency.value = type === 'danger' ? 800 : 600;
                oscillator.type = 'sine';
                
                gainNode.gain.setValueAtTime(0.1, audioContext.currentTime);
                gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.3);
                
                oscillator.start(audioContext.currentTime);
                oscillator.stop(audioContext.currentTime + 0.3);
            } catch (error) {
                // Ignore audio errors
            }
        }
    }
    
    async markAsRead(notificationId) {
        try {
            console.log('Marking notification as read:', notificationId, 'User:', this.userId);
            
            const formData = new FormData();
            formData.append('action', 'dismiss_notification');
            formData.append('notification_id', notificationId);
            formData.append('user_id', this.userId);
            
            // Try different API paths based on current location
            let apiUrl = '/v2/api/notification_api.php';
            if (window.location.pathname.includes('/admin/')) {
                apiUrl = '../api/notification_api.php';
            } else if (window.location.pathname.includes('/judge/')) {
                apiUrl = '../api/notification_api.php';
            }
            
            const response = await fetch(apiUrl, {
                method: 'POST',
                body: formData
            });
            
            if (response.ok) {
                const data = await response.json();
                if (data.success) {
                    console.log('Notification marked as read successfully');
                    // Remove from local tracking to prevent re-showing
                    this.notifications = this.notifications.filter(n => n.id !== notificationId);
                } else {
                    console.error('Failed to mark notification as read:', data.message);
                }
            } else {
                console.error('HTTP error marking notification as read:', response.status);
            }
        } catch (error) {
            console.error('Error marking notification as read:', error);
        }
    }
    
    startPolling() {
        this.stopPolling(); // Clear any existing interval
        this.isActive = true;
        
        // Initial poll
        this.pollNotifications();
        
        // Set up regular polling
        this.pollingInterval = setInterval(() => {
            this.pollNotifications();
        }, this.pollingRate);
    }
    
    stopPolling() {
        this.isActive = false;
        if (this.pollingInterval) {
            clearInterval(this.pollingInterval);
            this.pollingInterval = null;
        }
    }
    
    pausePolling() {
        this.isActive = false;
    }
    
    resumePolling() {
        this.isActive = true;
    }
    
    // Helper method to escape HTML
    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }
    
    // Public methods for sending specific competition notifications
    async notifyParticipantOnStart(bibNumber, participantName) {
        return this.sendNotification('info', 
            `🏁 Participant #${bibNumber} On Start`, 
            `${participantName} is now on the starting line`,
            { type: 'participant_on_start', bib: bibNumber, name: participantName },
            'participant'
        );
    }
    
    // Method to test API connectivity
    async testConnection() {
        try {
            // Determine correct API path based on current location
            let apiUrl = `/v2/api/notification_api.php?action=get_notifications&event_id=${this.eventId}&since=0&limit=1&user_id=${this.userId}`;
            if (window.location.pathname.includes('/admin/')) {
                apiUrl = `../api/notification_api.php?action=get_notifications&event_id=${this.eventId}&since=0&limit=1&user_id=${this.userId}`;
            } else if (window.location.pathname.includes('/judge/')) {
                apiUrl = `../api/notification_api.php?action=get_notifications&event_id=${this.eventId}&since=0&limit=1&user_id=${this.userId}`;
            }
            
            const response = await fetch(apiUrl);
            
            if (!response.ok) {
                throw new Error(`HTTP ${response.status}: ${response.statusText}`);
            }
            
            const contentType = response.headers.get('content-type');
            if (!contentType || !contentType.includes('application/json')) {
                throw new Error('API not returning JSON');
            }
            
            const data = await response.json();
            console.log('Connection test result:', data);
            return data.success;
            
        } catch (error) {
            console.error('Connection test failed:', error);
            return false;
        }
    }
    
    async notifyParticipantCompleted(bibNumber, participantName) {
        return this.sendNotification('success', 
            `🏆 Participant #${bibNumber} Completed`, 
            `${participantName} has finished their run`,
            { type: 'participant_completed', bib: bibNumber, name: participantName },
            'participant'
        );
    }
    
    async notifyParticipantStarted(bibNumber, participantName) {
        return this.sendNotification('warning', 
            `🚀 Participant #${bibNumber} Started`, 
            `${participantName} has begun their performance`,
            { type: 'participant_started', bib: bibNumber, name: participantName },
            'participant'
        );
    }
    
    async notifyNextParticipant(bibNumber, participantName) {
        return this.sendNotification('info', 
            `⏭️ Next Participant Ready`, 
            `#${bibNumber} ${participantName} is now next in queue`,
            { type: 'next_participant', bib: bibNumber, name: participantName },
            'participant'
        );
    }
    
    async notifyHeatActivated(heatNumber, runNumber) {
        return this.sendNotification('success', 
            `🔥 Heat ${heatNumber} Activated`, 
            `Run ${runNumber} is now active and competition is live`,
            { type: 'heat_activated', heat: heatNumber, run: runNumber },
            'heat'
        );
    }
    
    async notifyHeatDeactivated(heatNumber) {
        return this.sendNotification('warning', 
            `⏸️ Heat ${heatNumber} Deactivated`, 
            `Competition has been paused or stopped`,
            { type: 'heat_deactivated', heat: heatNumber },
            'heat'
        );
    }
    
    async notifyEmergencyStop() {
        return this.sendNotification('danger', 
            `🚨 EMERGENCY STOP`, 
            `Competition has been immediately stopped - all activities halted`,
            { type: 'emergency_stop' },
            'system'
        );
    }
    
    async notifyAutoAdvance(fromBib, toBib, toName) {
        return this.sendNotification('info', 
            `⚡ Auto-Advanced`, 
            `Moved from #${fromBib} to #${toBib} ${toName}`,
            { type: 'auto_advance', from_bib: fromBib, to_bib: toBib, to_name: toName },
            'competition'
        );
    }
    
    // Additional category-specific notification methods
    async notifyJudgeAction(action, details) {
        return this.sendNotification('info', 
            `👨‍💼 Judge Action: ${action}`, 
            details,
            { type: 'judge_action', action: action },
            'judge'
        );
    }
    
    async notifyScoreUpdate(participantBib, score, judge) {
        return this.sendNotification('success', 
            `📊 Score Updated`, 
            `#${participantBib} - Score: ${score} (Judge: ${judge})`,
            { type: 'score_update', bib: participantBib, score: score, judge: judge },
            'scoring'
        );
    }
    
    async notifyScoreApproval(participantBib, participantName, score, judge, heat, run, additionalData = {}) {
        // Create styled HTML message for toast
        let styledMessage = `
            <div class="d-flex align-items-center">
                <div class="me-2">
                    <span class="badge bg-primary css-bib fs-7">#${participantBib}</span>
                    <strong>${participantName}</strong>
                </div>
                <div class="ms-auto">
                    <span class="badge bg-success judge_score approved fs-7">${score}</span>
                </div>
            </div>
        `;
        
        // Add current result and rank if available
        if (additionalData.current_result !== undefined && additionalData.current_result !== null) {
            styledMessage += `
                <div class="mt-2 d-flex align-items-center">
                    <small class=" me-2">Result:</small>
                    <span class="badge bg-warning fs-7">${additionalData.current_result}</span>
            `;
            
            if (additionalData.rank_position) {
                styledMessage += `
                    <small class=" ms-2 me-2">Rank:</small>
                    <span class="badge bg-info fs-7">#${additionalData.rank_position}</span>
                `;
            }
            
            if (additionalData.approved_count && additionalData.total_judges) {
                styledMessage += `
                    <small class=" ms-2 me-2">Progress:</small>
                    <span class="badge bg-secondary">${additionalData.approved_count}/${additionalData.total_judges}</span>
                `;
            }
            
            styledMessage += `</div>`;
        }
        
        // Show judge scores breakdown if available (compact version)
        if (additionalData.all_scores && additionalData.all_scores.length > 0) {
            styledMessage += `<div class="mt-2">`;
            additionalData.all_scores.forEach(s => {
                const statusClass = s.approved ? 'approved bg-success' : 'bg-secondary';
                const statusIcon = s.approved ? '' : '⏳';
                styledMessage += `<span class="badge ${statusClass} judge_score me-1" title="${s.judge}">${s.score}${statusIcon}</span>`;
            });
            styledMessage += `</div>`;
        }
        
        // Simple text version for scrolling bar
        let textMessage = `#${participantBib} ${participantName} - Score: ${score} approved`;
        if (additionalData.current_result !== undefined && additionalData.current_result !== null) {
            textMessage += ` | Result: ${additionalData.current_result}`;
        }
        if (additionalData.rank_position) {
            textMessage += ` | Rank: #${additionalData.rank_position}`;
        }
        
        return this.sendNotification('success', 
            `✅ Score Approved`, 
            styledMessage,
            { 
                type: 'score_approval', 
                bib: participantBib, 
                name: participantName, 
                score: score, 
                judge: judge, 
                heat: heat, 
                run: run,
                text_message: textMessage,
                ...additionalData
            },
            'judge'
        );
    }
    
    async notifyBulkScoreApproval(participantBib, participantName, scoreCount, heat, run, additionalData = {}) {
        // Create styled HTML message for toast
        let styledMessage = `
            <div class="d-flex align-items-center">
                <div class="me-2">
                    <span class="badge bg-primary css-bib">#${participantBib}</span>
                    <strong>${participantName}</strong>
                </div>
                <div class="ms-auto">
                    <span class="badge bg-success">${scoreCount} scores</span>
                    <span class="badge bg-success ms-1">✅ ALL</span>
                </div>
            </div>
        `;
        
        // Add final result and rank
        if (additionalData.final_result !== undefined && additionalData.final_result !== null) {
            styledMessage += `
                <div class="mt-2 d-flex align-items-center">
                    <small class=" me-2">Final Result:</small>
                    <span class="badge bg-warning fs-7">${additionalData.final_result}</span>
            `;
            
            if (additionalData.rank_position) {
                styledMessage += `
                    <small class=" ms-2 me-2">Final Rank:</small>
                    <span class="badge bg-info fs-7">#${additionalData.rank_position}</span>
                `;
            }
            
            styledMessage += `</div>`;
        }
        
        // Show all judge scores (compact version)
        if (additionalData.all_scores && additionalData.all_scores.length > 0) {
            styledMessage += `<div class="mt-2">`;
            additionalData.all_scores.forEach(s => {
                const statusClass = s.approved ? 'approved bg-success' : 'bg-secondary';
                const statusIcon = s.approved ? '' : '⏳';
                styledMessage += `<span class="badge ${statusClass} judge_score me-1" title="${s.judge}">${s.score}${statusIcon}</span>`;
            });
            styledMessage += `</div>`;
        }
        
        // Simple text version for scrolling bar
        let textMessage = `#${participantBib} ${participantName} - All ${scoreCount} scores approved`;
        if (additionalData.final_result !== undefined && additionalData.final_result !== null) {
            textMessage += ` | Final: ${additionalData.final_result}`;
        }
        if (additionalData.rank_position) {
            textMessage += ` | Rank: #${additionalData.rank_position}`;
        }
        
        return this.sendNotification('success', 
            `✅ All Scores Approved`, 
            styledMessage,
            { 
                type: 'bulk_score_approval', 
                bib: participantBib, 
                name: participantName, 
                count: scoreCount, 
                heat: heat, 
                run: run,
                text_message: textMessage,
                ...additionalData
            },
            'judge'
        );
    }
    
    async notifySystemStatus(status, message) {
        return this.sendNotification('warning', 
            `⚙️ System Status: ${status}`, 
            message,
            { type: 'system_status', status: status },
            'technical'
        );
    }
    
    async notifyGeneralAnnouncement(title, message) {
        return this.sendNotification('info', 
            title, 
            message,
            { type: 'general_announcement' },
            'general'
        );
    }
    
    // Clear all notifications for this event
    async clearAllNotifications() {
        try {
            const formData = new FormData();
            formData.append('action', 'clear_all');
            formData.append('event_id', this.eventId);
            
            // Determine correct API path based on current location
            let apiUrl = '/v2/api/notification_api.php';
            if (window.location.pathname.includes('/admin/')) {
                apiUrl = '../api/notification_api.php';
            } else if (window.location.pathname.includes('/judge/')) {
                apiUrl = '../api/notification_api.php';
            }
            
            const response = await fetch(apiUrl, {
                method: 'POST',
                body: formData
            });
            
            const result = await response.json();
            
            if (response.ok) {
                // Clear local toast container
                this.toastContainer.innerHTML = '';
                this.notifications = [];
                this.latestId = 0;
            }
            
            return result;
        } catch (error) {
            console.error('Error clearing notifications:', error);
            throw error;
        }
    }
}

// Export for use in other scripts
window.NotificationManager = NotificationManager;
