/**
 * VH Flickr Mosaic - JavaScript
 * Beautiful photo mosaic with fade animations
 */

(function() {
    'use strict';

    class VHFlickrMosaic {
        constructor(container) {
            this.container = container;
            this.mosaicEl = container.querySelector('.vh-mosaic-container');
            this.photos = [];
            this.displayedPhotos = [];
            this.rows = parseInt(container.dataset.rows) || vhMosaicConfig.rows || 2;
            this.photoSize = parseInt(container.dataset.size) || vhMosaicConfig.photoSize || 150;
            this.animationSpeed = parseFloat(container.dataset.speed) || vhMosaicConfig.animationSpeed || 5;
            this.apiUrl = vhMosaicConfig.apiUrl;
            this.animationInterval = null;
            this.isVisible = false;

            this.init();
        }

        async init() {
            // Set up intersection observer for lazy loading
            this.setupVisibilityObserver();

            // Load photos
            await this.loadPhotos();

            // Initial render
            this.render();

            // Start animation when visible
            if (this.isVisible) {
                this.startAnimation();
            }
        }

        setupVisibilityObserver() {
            const observer = new IntersectionObserver((entries) => {
                entries.forEach(entry => {
                    this.isVisible = entry.isIntersecting;
                    if (this.isVisible && this.photos.length > 0) {
                        this.startAnimation();
                    } else {
                        this.stopAnimation();
                    }
                });
            }, { threshold: 0.1 });

            observer.observe(this.container);
        }

        async loadPhotos() {
            if (!this.apiUrl) {
                console.error('VH Flickr Mosaic: API URL not configured');
                return;
            }

            try {
                const response = await fetch(this.apiUrl);
                const data = await response.json();

                if (data.success && data.photos) {
                    this.photos = data.photos;
                } else {
                    console.error('VH Flickr Mosaic: Failed to load photos', data.error);
                }
            } catch (error) {
                console.error('VH Flickr Mosaic: API error', error);
            }
        }

        calculateGrid() {
            const containerWidth = this.mosaicEl.offsetWidth || window.innerWidth;
            const cols = Math.floor(containerWidth / (this.photoSize + 8)); // 8px gap
            return {
                cols: Math.max(cols, 3),
                total: Math.max(cols, 3) * this.rows
            };
        }

        render() {
            if (this.photos.length === 0) {
                this.mosaicEl.innerHTML = '';
                return;
            }

            const { cols, total } = this.calculateGrid();

            // Set grid columns
            this.mosaicEl.style.gridTemplateColumns = `repeat(${cols}, ${this.photoSize}px)`;

            // Select random photos for display
            this.displayedPhotos = this.getRandomPhotos(total);

            // Create HTML
            this.mosaicEl.innerHTML = this.displayedPhotos.map((photo, index) => `
                <div class="vh-mosaic-item" data-index="${index}" style="width:${this.photoSize}px;height:${this.photoSize}px;">
                    <a href="${photo.page_url || '#'}" target="_blank" rel="noopener noreferrer">
                        <img src="${photo.medium || photo.thumb}" alt="${this.escapeHtml(photo.title || '')}" loading="lazy">
                        ${photo.title ? `<span class="vh-photo-title">${this.escapeHtml(photo.title)}</span>` : ''}
                    </a>
                </div>
            `).join('');
        }

        getRandomPhotos(count) {
            const shuffled = [...this.photos].sort(() => Math.random() - 0.5);
            return shuffled.slice(0, Math.min(count, shuffled.length));
        }

        startAnimation() {
            if (this.animationInterval) return;
            if (this.photos.length <= this.displayedPhotos.length) return;

            this.animationInterval = setInterval(() => {
                this.swapRandomPhoto();
            }, this.animationSpeed * 1000);
        }

        stopAnimation() {
            if (this.animationInterval) {
                clearInterval(this.animationInterval);
                this.animationInterval = null;
            }
        }

        swapRandomPhoto() {
            if (!this.isVisible || this.photos.length === 0) return;

            const items = this.mosaicEl.querySelectorAll('.vh-mosaic-item');
            if (items.length === 0) return;

            // Pick random item to swap
            const randomIndex = Math.floor(Math.random() * items.length);
            const item = items[randomIndex];

            // Find a photo not currently displayed
            const currentIds = this.displayedPhotos.map(p => p.id);
            const availablePhotos = this.photos.filter(p => !currentIds.includes(p.id));

            if (availablePhotos.length === 0) return;

            const newPhoto = availablePhotos[Math.floor(Math.random() * availablePhotos.length)];

            // Animate the swap
            this.animatePhotoSwap(item, newPhoto, randomIndex);
        }

        animatePhotoSwap(item, newPhoto, index) {
            const oldImg = item.querySelector('img');
            const link = item.querySelector('a');

            if (!oldImg || !link) return;

            // Create new image
            const newImg = document.createElement('img');
            newImg.src = newPhoto.medium || newPhoto.thumb;
            newImg.alt = newPhoto.title || '';
            newImg.className = 'vh-fading-in';
            newImg.loading = 'lazy';

            // Start fade out of old image
            oldImg.classList.add('vh-fading-out');

            // Add new image
            link.appendChild(newImg);

            // Update link href
            link.href = newPhoto.page_url || '#';

            // Update title
            let titleEl = item.querySelector('.vh-photo-title');
            if (newPhoto.title) {
                if (titleEl) {
                    titleEl.textContent = newPhoto.title;
                } else {
                    titleEl = document.createElement('span');
                    titleEl.className = 'vh-photo-title';
                    titleEl.textContent = newPhoto.title;
                    link.appendChild(titleEl);
                }
            } else if (titleEl) {
                titleEl.remove();
            }

            // After animation, clean up
            setTimeout(() => {
                oldImg.remove();
                newImg.classList.remove('vh-fading-in');
            }, 800);

            // Update displayed photos array
            this.displayedPhotos[index] = newPhoto;
        }

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

    // Initialize all mosaics on page
    function initMosaics() {
        document.querySelectorAll('.vh-flickr-mosaic').forEach(container => {
            new VHFlickrMosaic(container);
        });
    }

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

    // Handle window resize
    let resizeTimeout;
    window.addEventListener('resize', () => {
        clearTimeout(resizeTimeout);
        resizeTimeout = setTimeout(() => {
            document.querySelectorAll('.vh-flickr-mosaic').forEach(container => {
                const mosaic = container._vhMosaic;
                if (mosaic) {
                    mosaic.render();
                }
            });
        }, 250);
    });

})();
