class AlertManager {

    constructor() {
        this.alerts = [];
        this.alertContainer = null;
        this.alertIdCounter = 0;

        this.ANIMATION_DURATION = 300;
        this.STACK_SPACING = 2;
        this.DEFAULT_DURATION = 5;

        this.init();
    }

    init() {
        this.createAlertContainer();
    }

    createAlertContainer() {
        this.alertContainer = document.createElement('div');
        this.alertContainer.className = 'alert-container';
        document.body.appendChild(this.alertContainer);
    }

    show(config = {}) {
        const alertConfig = {
            message: config.message || 'Alert message',
            type: config.type || 'success',
            autoDisappear: config.autoDisappear !== false,
            duration: config.duration || this.DEFAULT_DURATION,
            closeable: config.closeable !== false,
            id: `alert-${++this.alertIdCounter}`
        };

        if (!['success', 'warning', 'error'].includes(alertConfig.type)) {
            console.warn(`Alert: Invalid type "${alertConfig.type}". Using "success" instead.`);
            alertConfig.type = 'success';
        }

        const alertElement = this.createAlertElement(alertConfig);

        this.alerts.push({
            id: alertConfig.id,
            element: alertElement,
            config: alertConfig,
            timeoutId: null
        });

        this.alertContainer.appendChild(alertElement);

        this.repositionAlerts();

        setTimeout(() => {
            alertElement.classList.add('alert-show');
        }, 10);

        if (alertConfig.autoDisappear) {
            this.setAutoDisappear(alertConfig.id, alertConfig.duration);
        }

        return alertConfig.id;
    }

    createAlertElement(config) {
        const alertElement = document.createElement('div');
        alertElement.className = `alert alert-${config.type}`;
        alertElement.setAttribute('data-alert-id', config.id);

        alertElement.innerHTML = `
            <div class="alert-content">
                <span class="alert-icon">${this.getAlertIcon(config.type)}</span>
                <span class="alert-message">${this.escapeHtml(config.message)}</span>
                ${config.closeable ? '<button class="alert-close" type="button">&times;</button>' : ''}
            </div>
        `;

        if (config.closeable) {
            const closeButton = alertElement.querySelector('.alert-close');
            closeButton.addEventListener('click', () => {
                this.dismiss(config.id);
            });
        }

        return alertElement;
    }

    getAlertIcon(type) {
        const icons = {
            success: '✓',
            warning: '⚠',
            error: '✕'
        };
        return icons[type] || icons.success;
    }

    escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    setAutoDisappear(alertId, duration) {
        const alert = this.alerts.find(a => a.id === alertId);
        if (alert) {
            alert.timeoutId = setTimeout(() => {
                this.dismiss(alertId);
            }, duration * 1000);
        }
    }

    dismiss(alertId) {
        const alertIndex = this.alerts.findIndex(a => a.id === alertId);
        if (alertIndex === -1) return;

        const alert = this.alerts[alertIndex];

        if (alert.timeoutId) {
            clearTimeout(alert.timeoutId);
        }

        alert.element.classList.add('alert-hide');

        setTimeout(() => {
            if (alert.element.parentNode) {
                alert.element.parentNode.removeChild(alert.element);
            }

            this.alerts.splice(alertIndex, 1);

            this.repositionAlerts();
        }, this.ANIMATION_DURATION);
    }

    dismissAll() {

        const alertsToRemove = [...this.alerts];
        alertsToRemove.forEach(alert => {
            this.dismiss(alert.id);
        });
    }

    repositionAlerts() {
        let cumulativeTop = 0;
        this.alerts.forEach((alert) => {
            alert.element.style.top = `${cumulativeTop}px`;

            const alertRect = alert.element.getBoundingClientRect();
            const alertHeight = alertRect.height || this.getDefaultAlertHeight();
            cumulativeTop += alertHeight + this.STACK_SPACING;
        });
    }

    getDefaultAlertHeight() {

        return 44;
    }

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

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

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

    getActiveCount() {
        return this.alerts.length;
    }

    getActiveAlertIds() {
        return this.alerts.map(alert => alert.id);
    }

    isAlertActive(alertId) {
        return this.alerts.some(alert => alert.id === alertId);
    }

    destroy() {

        this.alerts.forEach(alert => {
            if (alert.timeoutId) {
                clearTimeout(alert.timeoutId);
            }
        });

        if (this.alertContainer && this.alertContainer.parentNode) {
            this.alertContainer.parentNode.removeChild(this.alertContainer);
        }

        this.alerts = [];
        this.alertContainer = null;
    }
}

if (typeof module !== 'undefined' && module.exports) {
    module.exports = AlertManager;
}

if (typeof window !== 'undefined') {
    window.AlertManager = AlertManager;

    window.alertManager = new AlertManager();

    window.showAlert = (config) => window.alertManager.show(config);
    window.showSuccess = (message, options) => window.alertManager.success(message, options);
    window.showWarning = (message, options) => window.alertManager.warning(message, options);
    window.showError = (message, options) => window.alertManager.error(message, options);
    window.dismissAlert = (alertId) => window.alertManager.dismiss(alertId);
    window.dismissAllAlerts = () => window.alertManager.dismissAll();
}