class Cards {

    constructor(options = {}) {

        if (!options.cards || !Array.isArray(options.cards)) {
            throw new Error('Cards component requires an array of card configurations');
        }

        if (!options.containerId) {
            throw new Error('Cards component requires a containerId');
        }

        this.cards = options.cards;
        this.multiSelect = options.multiSelect || false;
        this.required = options.required || false;
        this.onChange = options.onChange || (() => {});
        this.containerId = options.containerId;
        this.gridLayout = options.gridLayout || 'auto';

        this.selectedCards = new Set();
        this.element = null;
        this.cardElements = [];

        this.init();
    }

    init() {
        this.createContainer();
        this.createCards();
        this.setupEventListeners();
        this.updateLayout();
    }

    createContainer() {
        const container = document.getElementById(this.containerId);
        if (!container) {
            throw new Error(`Container element with ID "${this.containerId}" not found`);
        }

        this.element = document.createElement('div');
        this.element.className = 'cards-component';
        this.element.setAttribute('data-grid-layout', this.gridLayout);
        this.element.setAttribute('data-card-count', this.cards.length);

        container.appendChild(this.element);
    }

    createCards() {
        this.cardElements = [];

        this.cards.forEach((cardConfig, index) => {
            const cardElement = this.createCardElement(cardConfig, index);
            this.cardElements.push(cardElement);
            this.element.appendChild(cardElement);
        });
    }

    createCardElement(cardConfig, index) {
        const card = document.createElement('div');
        card.className = 'card';
        card.setAttribute('data-card-index', index);
        card.setAttribute('data-card-value', cardConfig.value || index);
        card.setAttribute('tabindex', '0');
        card.setAttribute('role', 'button');
        card.setAttribute('aria-pressed', 'false');

        const cardContent = `
            <div class="card-inner">
                ${cardConfig.image ? `<div class="card-image">
                    <img src="${this.escapeHtml(cardConfig.image)}" alt="${this.escapeHtml(cardConfig.title)}" />
                    ${cardConfig.pdf ? `<button class="card-expand-btn" type="button" aria-label="View full PDF" title="View full PDF">
                        <span class="expand-icon">📄</span>
                    </button>` : cardConfig.image ? `<button class="card-expand-btn" type="button" aria-label="View full image" title="View full image">
                        <span class="expand-icon">⛶</span>
                    </button>` : ''}
                </div>` : ''}
                <div class="card-content">
                    <h3 class="card-title">${this.escapeHtml(cardConfig.title)}</h3>
                    ${cardConfig.content ? `<div class="card-text">${cardConfig.content}</div>` : ''}
                </div>
                <div class="card-selection-indicator">
                    <span class="selection-icon">✓</span>
                </div>
            </div>
        `;

        card.innerHTML = cardContent;
        return card;
    }

    setupEventListeners() {

        this.element.addEventListener('click', (e) => {

            const expandBtn = e.target.closest('.card-expand-btn');
            if (expandBtn) {
                e.stopPropagation();
                this.handleExpandClick(expandBtn);
                return;
            }

            const card = e.target.closest('.card');
            if (card) {
                this.handleCardClick(card);
            }
        });

        this.element.addEventListener('keydown', (e) => {
            const expandBtn = e.target.closest('.card-expand-btn');
            if (expandBtn && (e.key === 'Enter' || e.key === ' ')) {
                e.preventDefault();
                e.stopPropagation();
                this.handleExpandClick(expandBtn);
                return;
            }

            const card = e.target.closest('.card');
            if (card && (e.key === 'Enter' || e.key === ' ')) {
                e.preventDefault();
                this.handleCardClick(card);
            }
        });
    }

    handleExpandClick(expandBtn) {
        const card = expandBtn.closest('.card');
        const cardIndex = parseInt(card.getAttribute('data-card-index'));
        const cardConfig = this.cards[cardIndex];

        if (cardConfig.pdf) {
            this.showFullScreenPDF(cardConfig.pdf, cardConfig.title);
        } else if (cardConfig.image) {
            this.showFullScreenImage(cardConfig.image, cardConfig.title);
        }
    }

    showFullScreenImage(imageSrc, imageTitle) {

        const modal = document.createElement('div');
        modal.className = 'card-image-modal';
        modal.setAttribute('role', 'dialog');
        modal.setAttribute('aria-modal', 'true');
        modal.setAttribute('aria-label', `Full screen view of ${imageTitle}`);

        modal.innerHTML = `
            <div class="modal-backdrop"></div>
            <div class="modal-content">
                <button class="modal-close" type="button" aria-label="Close full screen view" title="Close (Esc)">
                    <span class="close-icon">✕</span>
                </button>
                <img src="${this.escapeHtml(imageSrc)}" alt="${this.escapeHtml(imageTitle)}" class="modal-image" />
                <div class="modal-title">${this.escapeHtml(imageTitle)}</div>
            </div>
        `;

        document.body.appendChild(modal);
        document.body.style.overflow = 'hidden';

        modal.focus();

        const closeModal = () => {
            document.body.removeChild(modal);
            document.body.style.overflow = '';
        };

        modal.querySelector('.modal-backdrop').addEventListener('click', closeModal);

        modal.querySelector('.modal-close').addEventListener('click', closeModal);

        const handleKeydown = (e) => {
            if (e.key === 'Escape') {
                closeModal();
                document.removeEventListener('keydown', handleKeydown);
            }
        };
        document.addEventListener('keydown', handleKeydown);

        modal.addEventListener('DOMNodeRemoved', () => {
            document.removeEventListener('keydown', handleKeydown);
        });
    }

    showFullScreenPDF(pdfSrc, pdfTitle) {
        window.open(this.escapeHtml(pdfSrc), '_blank');
    }

    handleCardClick(cardElement) {
        const cardIndex = parseInt(cardElement.getAttribute('data-card-index'));

        if (this.multiSelect) {

            if (this.selectedCards.has(cardIndex)) {
                this.deselectCard(cardIndex);
            } else {
                this.selectCard(cardIndex);
            }
        } else {

            if (this.selectedCards.has(cardIndex)) {

                this.deselectCard(cardIndex);
            } else {

                this.clearSelection();
                this.selectCard(cardIndex);
            }
        }

        this.updateVisualState();
        this.triggerChange();
    }

    selectCard(cardIndex) {
        this.selectedCards.add(cardIndex);
        const cardElement = this.cardElements[cardIndex];
        cardElement.classList.add('selected');
        cardElement.setAttribute('aria-pressed', 'true');
    }

    deselectCard(cardIndex) {
        this.selectedCards.delete(cardIndex);
        const cardElement = this.cardElements[cardIndex];
        cardElement.classList.remove('selected');
        cardElement.setAttribute('aria-pressed', 'false');
    }

    clearSelection() {
        this.selectedCards.clear();
        this.cardElements.forEach(card => {
            card.classList.remove('selected');
            card.setAttribute('aria-pressed', 'false');
        });
    }

    updateVisualState() {
        this.cardElements.forEach((card, index) => {
            if (this.selectedCards.has(index)) {
                card.classList.add('selected');
                card.setAttribute('aria-pressed', 'true');
            } else {
                card.classList.remove('selected');
                card.setAttribute('aria-pressed', 'false');
            }
        });
    }

    updateLayout() {
        const cardCount = this.cards.length;
        let layoutClass = 'cards-auto';

        if (this.gridLayout === 'auto') {
            if (cardCount <= 2) {
                layoutClass = 'cards-center-2';
            } else if (cardCount <= 4) {
                layoutClass = 'cards-2x2';
            } else if (cardCount <= 6) {
                layoutClass = 'cards-3x2';
            } else {
                layoutClass = 'cards-auto';
            }
        } else {
            layoutClass = `cards-${this.gridLayout}`;
        }

        this.element.className = `cards-component ${layoutClass}`;
    }

    triggerChange() {
        const selectedValues = Array.from(this.selectedCards).map(index => {
            return {
                index: index,
                value: this.cards[index].value || index,
                title: this.cards[index].title,
                card: this.cards[index]
            };
        });

        this.onChange(selectedValues, this.selectedCards);
    }

    validate() {
        if (this.required && this.selectedCards.size === 0) {
            return false;
        }
        return true;
    }

    showValidationError(message = 'Please select at least one option') {
        if (typeof window.showError === 'function') {
            window.showError(message);
        } else {
            console.error('Alert system not available:', message);
        }
    }

    getSelection() {
        return Array.from(this.selectedCards).map(index => ({
            index: index,
            value: this.cards[index].value || index,
            title: this.cards[index].title,
            card: this.cards[index]
        }));
    }

    setSelection(values) {
        this.clearSelection();

        values.forEach(value => {

            const cardIndex = this.cards.findIndex((card, index) =>
                (card.value || index) === value || index === value
            );

            if (cardIndex !== -1) {
                this.selectCard(cardIndex);
            }
        });

        this.updateVisualState();
        this.triggerChange();
    }

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

    destroy() {
        if (this.element && this.element.parentNode) {
            this.element.parentNode.removeChild(this.element);
        }
        this.selectedCards.clear();
        this.cardElements = [];
        this.element = null;
    }
}

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

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