/**
 * A reusable Modal class for creating and managing modal dialogs.
 */
class Modal {
    /**
     * @param {object} options
     * @param {string} options.title - The title to display in the modal header.
     * @param {string} options.content - The HTML content to display in the modal body.
     * @param {string} [options.size=''] - An optional CSS class for sizing (e.g., 'large-modal').
     * @param {string} [options.footer=''] - Optional HTML content for the modal footer.
     * @param {function} [options.onClose] - A callback function to execute when the modal is closed.
     */
    constructor(options = {}) {
        this.title = options.title || '';
        this.content = options.content || '';
        this.size = options.size || '';
        this.footer = options.footer || '';
        this.onClose = options.onClose || null;

        this.modalElement = null;
        this.previouslyFocusedElement = null; // To store the element that had focus before modal opened
        this.boundKeydownHandler = this._handleKeydown.bind(this);
    }

    _render() {
        const modalId = `modal-${Date.now()}`;
        const modalHTML = `
            <div class="modal-overlay active" id="${modalId}">
                <div class="modal ${this.size}">
                    <div class="modal-header">
                        <h3>${this.title}</h3>
                        <button class="close-btn" aria-label="Close">&times;</button>
                    </div>
                    <div class="modal-body">
                        ${this.content}
                    </div>
                    ${this.footer ? `<div class="modal-footer">${this.footer}</div>` : ''}
                </div>
            </div>
        `;
        document.body.insertAdjacentHTML('beforeend', modalHTML);
        this.modalElement = document.getElementById(modalId);
    }

    _trapFocus() {
        const focusableElements = this.modalElement.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
        const firstFocusableElement = focusableElements[0];
        const lastFocusableElement = focusableElements[focusableElements.length - 1];

        if (firstFocusableElement) {
            firstFocusableElement.focus();
        }
    }

    _addEventListeners() {
        this.modalElement.addEventListener('click', (e) => {
            if (e.target === this.modalElement || e.target.closest('.close-btn')) {
                this.close();
            } else if (e.target.closest('.modal')) {
                // Prevent clicks inside the modal from closing it
            }
        });
        document.addEventListener('keydown', this.boundKeydownHandler);
    }

    _removeEventListeners() {
        document.removeEventListener('keydown', this.boundKeydownHandler);
    }

    _handleKeydown(e) {
        if (e.key === 'Escape') {
            this.close();
        }
    }

    show() {
        this.previouslyFocusedElement = document.activeElement; // Store the currently focused element

        // Remove any existing modals to avoid stacking issues
        document.querySelectorAll('.modal-overlay').forEach(m => m.remove());
        this._render();
        this._addEventListeners();
        document.body.classList.add('modal-open'); // Add class to body to prevent scrolling
        this._trapFocus(); // Trap focus within the modal
        return this.modalElement;
    }

    close() {
        if (!this.modalElement) return;
        this.modalElement.remove();
        this._removeEventListeners();
        document.body.classList.remove('modal-open'); // Remove class from body
        if (this.previouslyFocusedElement) {
            this.previouslyFocusedElement.focus(); // Return focus to the element that opened the modal
        }
        if (this.onClose) this.onClose();
    }
}