/**
 * RSL Inlay Alert System
 *
 * A comprehensive alert system for displaying contextual messages with support
 * for multiple types, animations, auto-dismiss timers, and accessibility features.
 * Supports both static HTML alerts and dynamically generated alerts via JavaScript API.
 *
 * @fileoverview Flexible alert system with accessibility and auto-dismiss support
 * @version 1.0.0
 * @license MIT
 *
 * Key Features:
 * - Five alert types: success, danger, warning, info, default
 * - Dynamic alert generation via JavaScript API
 * - Auto-dismiss with progress bar indicator
 * - Customizable colors, icons, and animations
 * - Full accessibility support (ARIA labels, screen reader helpers)
 * - FontAwesome icon integration
 * - Smooth fade/slide animations
 * - Drop shadow variants
 * - ADA helper integration for auto-dismissed alerts
 *
 * Alert Types:
 * - success: Green, check icon (confirmations, completed actions)
 * - danger: Red, triangle icon (errors, critical warnings)
 * - warning: Yellow, triangle icon (cautions, important notices)
 * - info: Blue, info icon (informational messages)
 * - default: Gray, info icon (general messages)
 *
 * Usage:
 * // Static HTML:
 * <div class="inlay-alert alert-success">
 *   <i class="fas fa-check-circle"></i>
 *   <div class="alert-message">
 *     <h4>Success!</h4>
 *     <p>Your changes have been saved.</p>
 *   </div>
 *   <button class="close"><i class="fas fa-times"></i></button>
 * </div>
 *
 * // Dynamic JavaScript:
 * generateAlert({
 *   type: 'success',
 *   message: 'Success!',
 *   details: 'Your changes have been saved.',
 *   location: '#alertContainer',
 *   timeout: 3000
 * });
 *
 * Public API:
 * - generateAlert(options) - Create and display a dynamic alert
 * - adjustProgressBarColors() - Update progress bar styling
 * - adjustAlertMessageStaticColors() - Update static alert text colors
 * - ADAHelperForAlerts(options) - Create accessible alert helper (if defined)
 */

(function() {
    'use strict';

    /**
     * Alert type configurations
     * @const
     * @type {Object<string, {color: string, icon: string}>}
     */
    const alertTypes = {
        'success': {
            'color': '#28a745',
            'icon': 'fa-check-circle'
        },
        'danger': {
            'color': '#dc3545',
            'icon': 'fa-exclamation-triangle'
        },
        'warning': {
            'color': '#ffc107',
            'icon': 'fa-exclamation-triangle'
        },
        'info': {
            'color': '#17a2b8',
            'icon': 'fa-info-circle'
        },
        'default': {
            'color': '#6c757d',
            'icon': 'fa-info-circle'
        }
    };

    /**
     * Initialize close button handlers for static alerts
     * Attaches click handlers to all close buttons in static HTML alerts
     */
    function initCloseButtons() {
        const closeButtons = document.querySelectorAll('.inlay-alert .close');
        closeButtons.forEach(function(button) {
            button.addEventListener('click', function(e) {
                const alert = e.target.closest('.inlay-alert');
                if (alert) {
                    alert.style.opacity = '0';
                    setTimeout(function() {
                        alert.style.display = 'none';
                    }, 150);
                }
            });
        });
    }

    /**
     * Initialize text colors for static alerts
     * Automatically adjusts text color based on background color for optimal contrast
     */
    function initStaticAlertColors() {
        const staticAlerts = document.querySelectorAll('.inlay-alert');
        staticAlerts.forEach(function(alert) {
            const backgroundColor = window.getComputedStyle(alert).backgroundColor;
            const textColor = isLight(backgroundColor)
                ? adjustColor(backgroundColor, 70)
                : adjustColor(backgroundColor, -70);
            alert.style.setProperty('--text-color', textColor);
        });
    }

    /**
     * Generate and display a dynamic alert
     *
     * Creates a fully customizable alert with optional auto-dismiss, animations,
     * and accessibility features. Supports color overrides, custom icons, and
     * callbacks for show/hide events.
     *
     * @param {Object} obj - Alert configuration object
     * @param {string} obj.type - Alert type: 'success', 'danger', 'warning', 'info', or 'default'
     * @param {string} obj.message - Alert title/heading text
     * @param {string} obj.details - Alert body/description text
     * @param {string} obj.location - Container selector (must start with # or .)
     * @param {string} [obj.dropShadow=''] - Drop shadow class: 'alert-dropshadow-a', 'alert-dropshadow-b', etc.
     * @param {string} [obj.wrapMessage='false'] - If 'true', wraps details in a border div
     * @param {string} [obj.animation=''] - Animation class: 'fade-slide-up', 'fade-slide-down', etc.
     * @param {string} [obj.overrideIcon] - Custom FontAwesome icon class (e.g., 'fa-user')
     * @param {string} [obj.overrideBackgroundColor] - Custom background color (hex, rgb, etc.)
     * @param {string} [obj.overrideTextColor] - Custom text color (hex, rgb, etc.)
     * @param {string} [obj.overrideTitleColor] - Custom title/heading color
     * @param {string} [obj.overrideIconColor] - Custom icon color
     * @param {string} [obj.overrideCloseColor] - Custom close button color
     * @param {number} [obj.timeout] - Auto-dismiss after milliseconds (shows progress bar)
     * @param {Function} [obj.onShow] - Callback fired when alert is shown
     * @param {Function} [obj.onClose] - Callback fired when alert is closed
     *
     * @example
     * generateAlert({
     *   type: 'success',
     *   message: 'Saved!',
     *   details: 'Your changes have been saved successfully.',
     *   location: '#alertContainer',
     *   timeout: 3000,
     *   animation: 'fade-slide-up'
     * });
     *
     * @example
     * // Custom styled alert
     * generateAlert({
     *   type: 'info',
     *   message: 'Custom Alert',
     *   details: 'This alert uses custom colors.',
     *   location: '.alert-zone',
     *   overrideBackgroundColor: '#f0f8ff',
     *   overrideTitleColor: '#1e90ff',
     *   overrideIcon: 'fa-star',
     *   dropShadow: 'alert-dropshadow-c'
     * });
     */
    function generateAlert(obj) {
        const {
            type,
            message,
            details,
            location,
            dropShadow,
            wrapMessage,
            overrideBackgroundColor,
            overrideTextColor,
            overrideTitleColor,
            overrideIconColor,
            overrideCloseColor,
            timeout,
            overrideIcon,
            animation,
            onShow,
            onClose,
        } = obj;

        // Locate the container element
        let alertContainer;
        if (location.startsWith('#')) {
            alertContainer = document.getElementById(location.slice(1));
        } else if (location.startsWith('.')) {
            alertContainer = document.querySelector(location);
        } else {
            console.error('Location must start with a # (for an ID) or a . (for a class)');
            return;
        }

        if (!alertContainer) {
            console.error('Alert container not found:', location);
            return;
        }

        // Determine alert colors and icon
        const alertType = alertTypes[type] || alertTypes.default;
        const backgroundColor = overrideBackgroundColor || alertType.color;

        let textColor;
        try {
            textColor = overrideTextColor || (isLight(backgroundColor)
                ? adjustColor(backgroundColor, 70)
                : adjustColor(backgroundColor, -70));
        } catch (error) {
            console.warn("Invalid background color, defaulting text color to black.");
            textColor = "#000000";
        }

        const iconType = overrideIcon || alertType.icon;

        // Create alert element
        const alertElement = document.createElement('div');
        alertElement.setAttribute("role", "alert");
        alertElement.setAttribute("aria-label", `${type}: ${message} ${details}`);
        alertElement.className = `inlay-alert dynamic ${dropShadow || ''} ${animation || ''}`;
        alertElement.style.backgroundColor = backgroundColor;
        alertElement.style.color = textColor;

        // Build alert HTML
        const alertMessage = message
            ? `<h4 style="color: ${overrideTitleColor || textColor};">${message}</h4>`
            : '';

        const icon = typeof overrideIconColor !== 'undefined'
            ? `<i class="fas ${iconType}" aria-hidden="true" style="color: ${overrideIconColor || textColor};"></i>`
            : `<i class="fas ${iconType}" aria-hidden="true"></i>`;

        const closeIcon = typeof overrideCloseColor !== 'undefined'
            ? `<button class="close" aria-label="Close" style="color: ${overrideCloseColor || textColor};"><i class="fas fa-times closer" aria-hidden="true"></i></button>`
            : `<button class="close" aria-label="Close"><i class="fas fa-times closer" aria-hidden="true"></i></button>`;

        const alertDetails = details
            ? wrapMessage === 'true'
                ? `<div class="message-wrapper"><p><div class="alert-message-around">${details}</div></p></div>`
                : `<div class="message-wrapper"><p>${details}</p></div>`
            : '';

        alertElement.innerHTML = `
            <div class="alert-content">
                ${icon}
                <div class="alert-message">
                ${alertMessage}
                ${alertDetails}
                </div>
                ${closeIcon}
            </div>
        `;

        // Attach close button handler
        alertElement.querySelector('.close').addEventListener('click', () => {
            alertElement.style.opacity = '0';
            setTimeout(() => {
                if (alertElement.parentNode === alertContainer) {
                    alertContainer.removeChild(alertElement);
                }
                if (onClose) onClose();
            }, 500);
        });

        // Add to DOM
        alertContainer.appendChild(alertElement);

        // Fire onShow callback
        if (onShow) onShow();

        // Setup auto-dismiss if timeout is specified
        if (timeout) {
            setupAutoDismiss(alertElement, alertContainer, timeout, type, message, details, obj, onClose);
        }

        // Apply text color adjustments
        if (!overrideTextColor) {
            adjustTextColor(alertElement);
        }
        adjustAlertMessageStaticColors();
    }

    /**
     * Setup auto-dismiss functionality with progress bar
     *
     * Creates a visual progress bar and handles automatic alert removal
     * after the specified timeout. Integrates with ADA helper for screen
     * reader accessibility when alerts are auto-dismissed.
     *
     * @param {HTMLElement} alertElement - The alert element to dismiss
     * @param {HTMLElement} alertContainer - Parent container
     * @param {number} timeout - Milliseconds before auto-dismiss
     * @param {string} type - Alert type
     * @param {string} message - Alert message
     * @param {string} details - Alert details
     * @param {Object} obj - Original alert configuration object
     * @param {Function} [onClose] - Close callback
     */
    function setupAutoDismiss(alertElement, alertContainer, timeout, type, message, details, obj, onClose) {
        // Create and add progress bar
        const progressBar = document.createElement('div');
        progressBar.className = 'progress-bar';
        progressBar.style.animationDuration = `${timeout}ms`;
        alertElement.appendChild(progressBar);

        const ariaLabel = `${type}: ${message} ${details}`;
        let adaElement = null;

        setTimeout(() => {
            const visibleDuration = Math.round(timeout / 1000);
            const removalTime = new Date().toLocaleTimeString();

            // Create ADA helper for screen readers if available
            if (typeof ADAHelperForAlerts === 'function') {
                const enhancedAriaLabel = `${ariaLabel}. This alert was displayed for ${visibleDuration} seconds and was removed at ${removalTime}.`;
                const containerChildCountBefore = alertContainer.children.length;

                ADAHelperForAlerts({
                    location: obj.location,
                    ariaLabel: enhancedAriaLabel,
                    additionalClass: 'adaContentJump',
                    allowClose: true
                });

                // Find and properly hide the ADA helper element
                if (alertContainer.children.length > containerChildCountBefore) {
                    adaElement = alertContainer.lastChild;
                    if (adaElement) {
                        setupADAElement(adaElement);
                    }
                }
            }

            // Fade out and remove alert
            alertElement.style.opacity = '0';
            setTimeout(() => {
                if (alertElement.parentNode === alertContainer) {
                    alertContainer.removeChild(alertElement);
                }

                // Clean up ADA helper after delay
                if (adaElement && adaElement.parentNode === alertContainer) {
                    setTimeout(() => {
                        if (adaElement.parentNode === alertContainer) {
                            alertContainer.removeChild(adaElement);
                        }
                    }, 30000); // Keep for 30 seconds for screen reader users
                }

                if (onClose) onClose();
            }, 500);
        }, timeout);
    }

    /**
     * Setup ADA helper element with screen reader only styles
     *
     * Applies CSS to hide element visually while keeping it accessible
     * to screen readers. Handles focus events to show/hide the element.
     *
     * @param {HTMLElement} adaElement - The ADA helper element
     */
    function setupADAElement(adaElement) {
        adaElement.classList.add('ada-alert-helper');

        // Apply screen-reader-only styles
        adaElement.style.position = 'absolute';
        adaElement.style.clip = 'rect(1px, 1px, 1px, 1px)';
        adaElement.style.clipPath = 'inset(50%)';
        adaElement.style.width = '1px';
        adaElement.style.height = '1px';
        adaElement.style.margin = '-1px';
        adaElement.style.overflow = 'hidden';
        adaElement.style.padding = '0';
        adaElement.style.whiteSpace = 'nowrap';
        adaElement.style.border = '0';

        const skipLink = adaElement.querySelector('.skip-link');
        if (skipLink) {
            skipLink.style.removeProperty('display');

            // Show wrapper on focus
            skipLink.addEventListener('focus', function() {
                adaElement.style.position = 'static';
                adaElement.style.clip = 'auto';
                adaElement.style.clipPath = 'none';
                adaElement.style.width = 'auto';
                adaElement.style.height = 'auto';
                adaElement.style.margin = '0';
                adaElement.style.overflow = 'visible';
            });

            // Hide wrapper on blur
            skipLink.addEventListener('blur', function() {
                adaElement.style.position = 'absolute';
                adaElement.style.clip = 'rect(1px, 1px, 1px, 1px)';
                adaElement.style.clipPath = 'inset(50%)';
                adaElement.style.width = '1px';
                adaElement.style.height = '1px';
                adaElement.style.margin = '-1px';
                adaElement.style.overflow = 'hidden';
            });
        }
    }

    /**
     * Adjust progress bar colors based on alert background
     *
     * Automatically lightens or darkens progress bar color for optimal
     * visibility against the alert background color.
     *
     * @example
     * adjustProgressBarColors();
     */
    function adjustProgressBarColors() {
        const alerts = document.querySelectorAll('.inlay-alert');
        alerts.forEach(function(alert) {
            const progressBar = alert.querySelector('.progress-bar');
            if (progressBar) {
                const bgColor = window.getComputedStyle(alert).backgroundColor;
                const progressBarColor = isLight(bgColor)
                    ? adjustColor(bgColor, -100)
                    : adjustColor(bgColor, 100);
                progressBar.style.backgroundColor = progressBarColor;
            }
        });
    }

    /**
     * Initialize on DOM ready
     */
    document.addEventListener('DOMContentLoaded', function() {
        initCloseButtons();
        initStaticAlertColors();
        adjustProgressBarColors();
    });

    /**
     * Expose public API
     * These functions are expected to be defined globally (not in IIFE scope)
     * for integration with other RSL components
     */
    window.generateAlert = generateAlert;
    window.adjustProgressBarColors = adjustProgressBarColors;

})();
