// Notification System Module
// Advanced notifications with variants, queue management, and accessibility
(function() {
    'use strict';

    AppModules.require('ui-controls');
    AppModules.register('notifications');

    // Notification configuration
    const NotificationConfig = {
        maxNotifications: 5, // Maximum notifications shown simultaneously
        defaultDuration: 4000, // Default auto-dismiss duration (ms)
        duration: {
            success: 3000,
            error: 7000,
            warning: 5000,
            info: 4000
        },
        position: 'top-right', // top-right, top-left, bottom-right, bottom-left, center
        positionClasses: {
            'top-right': '',
            'top-left': 'notifications-container--left',
            'bottom-right': 'notifications-container--bottom',
            'bottom-left': 'notifications-container--bottom notifications-container--left',
            'center': 'notifications-container--center'
        }
    };

    // Notification queue and state
    let notificationQueue = [];
    let activeNotifications = [];
    let notificationCounter = 0;

    // DOM elements
    let notificationsContainer = null;

    // Notification class
    class Notification {
        constructor(options = {}) {
            this.id = `notification-${++notificationCounter}`;
            this.title = options.title || '';
            this.message = options.message || '';
            this.type = options.type || 'info'; // success, error, warning, info, default
            this.duration = options.duration === 0 ? 0 : (options.duration || NotificationConfig.duration[this.type] || NotificationConfig.defaultDuration);
            this.actions = options.actions || [];
            this.position = options.position || NotificationConfig.position;
            this.persistent = options.persistent || false;
            this.icon = options.icon !== undefined ? options.icon : true;
            this.timestamp = Date.now();
            this.element = null;
        }

        createElement() {
            const notification = document.createElement('div');
            notification.id = this.id;
            notification.className = `notification notification--${this.type}`;
            notification.setAttribute('role', 'alert');
            notification.setAttribute('aria-live', 'assertive');
            notification.setAttribute('aria-atomic', 'true');

            let html = '';

            // Icon
            if (this.icon) {
                html += '<div class="notification__icon" aria-hidden="true"></div>';
            }

            // Content
            html += '<div class="notification__content">';
            if (this.title) {
                html += `<div class="notification__title">${escapeHtml(this.title)}</div>`;
            }
            html += `<div class="notification__message">${escapeHtml(this.message)}</div>`;
            html += '</div>';

            // Actions
            if (this.actions.length > 0) {
                html += '<div class="notification__actions">';
                this.actions.forEach(action => {
                    const actionId = `action-${this.id}-${action.id || action.label.toLowerCase().replace(/\s+/g, '-')}`;
                    html += `<button class="notification__action" data-action-id="${actionId}" aria-label="${escapeHtml(action.label)}">${escapeHtml(action.label)}</button>`;
                });
                html += '</div>';
            }

            // Progress bar for auto-dismissing notifications
            if (this.duration > 0) {
                html += '<div class="notification__progress"><div class="notification__progress-bar"></div></div>';
            }

            notification.innerHTML = html;

            // Add close button if no custom actions
            if (this.actions.length === 0) {
                const closeBtn = document.createElement('button');
                closeBtn.className = 'notification__action';
                closeBtn.setAttribute('aria-label', 'Close notification');
                closeBtn.innerHTML = '×';
                closeBtn.addEventListener('click', () => this.dismiss());
                notification.appendChild(closeBtn);
            }

            // Set progress bar animation duration
            if (this.duration > 0) {
                const progressBar = notification.querySelector('.notification__progress-bar');
                if (progressBar) {
                    progressBar.style.animationDuration = `${this.duration}ms`;
                }
            }

            // Bind action handlers
            this.actions.forEach((action, index) => {
                const actionBtn = notification.querySelector(`[data-action-id="action-${this.id}-${action.id || action.label.toLowerCase().replace(/\s+/g, '-')}"]`);
                if (actionBtn && action.handler) {
                    actionBtn.addEventListener('click', () => {
                        action.handler(this);
                    });
                }
            });

            this.element = notification;
            return notification;
        }

        show() {
            if (!notificationsContainer) return;

            // Create element if not exists
            if (!this.element) {
                this.createElement();
            }

            // Add position class
            const positionClass = NotificationConfig.positionClasses[this.position] || '';
            notificationsContainer.className = `notifications-container ${positionClass}`;

            // Add to container
            notificationsContainer.appendChild(this.element);

            // Set up auto-dismiss if duration is set
            if (this.duration > 0) {
                this.timeoutId = setTimeout(() => {
                    this.dismiss();
                }, this.duration);
            }

            // Pause timeout on hover
            this.element.addEventListener('mouseenter', () => {
                if (this.timeoutId) {
                    clearTimeout(this.timeoutId);
                    this.timeoutId = null;
                }
            });

            this.element.addEventListener('mouseleave', () => {
                if (this.duration > 0 && !this.dismissed) {
                    this.timeoutId = setTimeout(() => {
                        this.dismiss();
                    }, this.duration);
                }
            });

            return this;
        }

        dismiss() {
            if (this.dismissed) return;
            this.dismissed = true;

            // Clear timeout
            if (this.timeoutId) {
                clearTimeout(this.timeoutId);
                this.timeoutId = null;
            }

            // Add exit animation
            if (this.element) {
                this.element.classList.add('exiting');

                // Remove after animation
                setTimeout(() => {
                    if (this.element && this.element.parentNode) {
                        this.element.parentNode.removeChild(this.element);
                    }
                    removeFromActive(this);
                    processQueue();
                }, 300);
            }
        }

        update(options = {}) {
            if (options.message !== undefined) {
                this.message = options.message;
                const messageEl = this.element.querySelector('.notification__message');
                if (messageEl) {
                    messageEl.textContent = this.message;
                }
            }

            if (options.title !== undefined) {
                this.title = options.title;
                const titleEl = this.element.querySelector('.notification__title');
                if (titleEl) {
                    titleEl.textContent = this.title;
                }
            }
        }
    }

    // Queue management functions
    function addToQueue(notification) {
        notificationQueue.push(notification);

        // Process queue if not at max capacity
        if (activeNotifications.length < NotificationConfig.maxNotifications) {
            processQueue();
        }
    }

    function removeFromActive(notification) {
        const index = activeNotifications.indexOf(notification);
        if (index > -1) {
            activeNotifications.splice(index, 1);
        }
    }

    function processQueue() {
        // Remove any notifications that have been dismissed
        activeNotifications = activeNotifications.filter(n => !n.dismissed);

        // Show queued notifications if space available
        while (activeNotifications.length < NotificationConfig.maxNotifications && notificationQueue.length > 0) {
            const notification = notificationQueue.shift();
            activeNotifications.push(notification);
            notification.show();
        }
    }

    // Public API functions
    function show(options = {}) {
        if (typeof options === 'string') {
            options = { message: options };
        }

        const notification = new Notification(options);
        addToQueue(notification);
        return notification;
    }

    function success(message, options = {}) {
        return show(Object.assign({
            message,
            type: 'success'
        }, options));
    }

    function error(message, options = {}) {
        return show(Object.assign({
            message,
            type: 'error'
        }, options));
    }

    function warning(message, options = {}) {
        return show(Object.assign({
            message,
            type: 'warning'
        }, options));
    }

    function info(message, options = {}) {
        return show(Object.assign({
            message,
            type: 'info'
        }, options));
    }

    function dismissAll() {
        // Clear queue
        notificationQueue = [];

        // Dismiss all active notifications
        activeNotifications.forEach(notification => {
            notification.dismiss();
        });
        activeNotifications = [];
    }

    function clearQueue() {
        notificationQueue = [];
    }

    function setConfig(newConfig = {}) {
        Object.assign(NotificationConfig, newConfig);

        // Update container class if position changed
        if (notificationsContainer && newConfig.position) {
            const positionClass = NotificationConfig.positionClasses[newConfig.position] || '';
            notificationsContainer.className = `notifications-container ${positionClass}`;
        }
    }

    // Utility functions
    function escapeHtml(text) {
        const map = {
            '&': '&',
            '<': '<',
            '>': '>',
            '"': '"',
            "'": '&#039;'
        };
        return (text || '').replace(/[&<>"']/g, m => map[m]);
    }

    // Initialize the notification system
    function initialize() {
        // Get container element
        notificationsContainer = document.getElementById('notificationsContainer');

        if (!notificationsContainer) {
            console.warn('Notification container element not found. Notifications will not be displayed.');
            return;
        }

        // Set initial position class
        const positionClass = NotificationConfig.positionClasses[NotificationConfig.position] || '';
        notificationsContainer.className = `notifications-container ${positionClass}`;

        // Add keyboard navigation support
        document.addEventListener('keydown', handleKeyboardNavigation);

        // Add container click delegation
        notificationsContainer.addEventListener('click', handleContainerClick);

        AppLogger.log('Notification system initialized');
    }

    // Keyboard navigation handler
    function handleKeyboardNavigation(event) {
        // Close notification on Escape
        if (event.key === 'Escape') {
            const activeNotification = activeNotifications[activeNotifications.length - 1];
            if (activeNotification) {
                activeNotification.dismiss();
                event.preventDefault();
            }
        }
    }

    // Container click handler for delegation
    function handleContainerClick(event) {
        // Handle close button clicks
        if (event.target.classList.contains('notification__action') &&
            event.target.textContent === '×') {
            const notificationEl = event.target.closest('.notification');
            if (notificationEl) {
                const notificationId = notificationEl.id;
                const notification = activeNotifications.find(n => n.id === notificationId);
                if (notification) {
                    notification.dismiss();
                }
            }
        }
    }

    // Legacy toast support - redirect to new system
    function legacyShowToast(message, duration) {
        const toastElement = document.getElementById('toast');
        if (toastElement) {
            toastElement.style.display = 'none';
        }

        // Show using new system instead
        show({
            message,
            duration: duration === 0 ? 0 : duration,
            type: 'info',
            position: 'bottom'
        });
    }

    function legacyHideToast() {
        // Legacy function - kept for compatibility, but new system is auto-managing
        AppLogger.warn('hideToast() called - this is deprecated. Notifications auto-manage themselves now.');
    }

    // Update ui-controls module to use new notification system
    function updateUIControls() {
        if (window.UIControls && window.UIControls.showToast) {
            window.UIControls.showToast = legacyShowToast;
            window.UIControls.hideToast = legacyHideToast;
        }
    }

    // Public API
    window.Notifications = {
        show: show,
        success: success,
        error: error,
        warning: warning,
        info: info,
        dismissAll: dismissAll,
        clearQueue: clearQueue,
        setConfig: setConfig,
        config: NotificationConfig
    };

    // Initialize on DOM ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initialize);
    } else {
        initialize();
    }

    // Update UI controls after a short delay to ensure they load
    setTimeout(updateUIControls, 100);

    AppLogger.log('Notification system module loaded');

})();
