/**
 * ALGA ARENA — Cinematic Image Motion System
 * id="cinematic-image-motion"
 * AAA game-launcher feel: layered parallax, depth reveals, living hero scene
 * Technique stack: GSAP, ScrollTrigger, requestAnimationFrame, CSS custom props
 */

'use strict';

document.addEventListener('DOMContentLoaded', () => {
    const isReduced = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
    const isTouch   = window.matchMedia('(hover: none)').matches;
    const isMobile  = window.innerWidth < 768;
    const hasGSAP   = typeof gsap !== 'undefined';

    // ─────────────────────────────────────────────────────────────
    // HERO ELEMENT REFS
    // ─────────────────────────────────────────────────────────────
    const heroContainer = document.querySelector('.hero-banner-container');
    const heroBg        = heroContainer?.querySelector('.hero-bg-img');
    const heroFog       = heroContainer?.querySelector('.hero-fog');
    const heroParticles = heroContainer?.querySelector('.hero-particle-field');
    const heroLensFlare = heroContainer?.querySelector('.hero-lens-flare');
    const heroSafeCol   = heroContainer?.querySelector('.hero-safe-col');

    // ══════════════════════════════════════════════════════════════
    // 1. HERO ENTRANCE — camera depth push + text stagger
    // ══════════════════════════════════════════════════════════════
    if (hasGSAP && !isReduced) {
        // Start hero bg at deeper zoom and drift in
        gsap.set(heroBg, { scale: 1.12, opacity: 0 });
        gsap.to(heroBg, {
            scale: 1.06,
            opacity: 1,
            duration: 2.2,
            ease: 'power3.out',
            onComplete: () => {
                // Re-attach the CSS camera drift animation after entrance
                if (heroBg) heroBg.style.animation = 'heroCameraDrift 22s ease-in-out infinite';
            }
        });

        // Overlay fades to reveal scene
        const heroOverlay = heroContainer?.querySelector('.hero-overlay');
        if (heroOverlay) {
            gsap.fromTo(heroOverlay,
                { opacity: 0 },
                { opacity: 1, duration: 1.8, ease: 'power2.out' }
            );
        }

        // Text stagger — masked reveal (clip from bottom)
        gsap.set('.hero-stagger', { opacity: 0, y: 32, clipPath: 'inset(0 0 100% 0)' });
        gsap.to('.hero-stagger', {
            opacity: 1,
            y: 0,
            clipPath: 'inset(0 0 0% 0)',
            duration: 0.8,
            stagger: 0.14,
            ease: 'power3.out',
            delay: 0.7
        });

        // Stats strip stagger — enter from depth
        gsap.set('.hero-stats-strip .stat-item', { opacity: 0, y: 18 });
        gsap.to('.hero-stats-strip .stat-item', {
            opacity: 1,
            y: 0,
            duration: 0.65,
            stagger: 0.09,
            ease: 'power2.out',
            delay: 1.4,
            onComplete: triggerCounters
        });

        // Particle field fade-in with delay
        if (heroParticles) {
            gsap.from(heroParticles, { opacity: 0, duration: 2.5, delay: 1.8, ease: 'power1.out' });
        }

        // Lens flare appears after scene is established
        if (heroLensFlare) {
            gsap.from(heroLensFlare, { opacity: 0, scale: 0.4, duration: 1.5, delay: 2.0, ease: 'power2.out' });
        }

        // Energy rings fade in
        const energyPulse = heroContainer?.querySelector('.hero-energy-pulse');
        if (energyPulse) {
            gsap.from(energyPulse, { opacity: 0, duration: 2.0, delay: 1.5, ease: 'power1.out' });
        }

    } else {
        // Reduced motion fallback — instant show
        if (heroBg) {
            heroBg.style.transform = 'scale(1.03)';
            heroBg.style.opacity   = '1';
        }
        triggerCounters();
    }

    // ══════════════════════════════════════════════════════════════
    // 2. HERO MOUSE PARALLAX — requestAnimationFrame driven
    //    Background moves opposite to cursor (camera pan feel)
    //    Fog, particles, flare move slightly toward cursor
    // ══════════════════════════════════════════════════════════════
    if (!isReduced && !isTouch && heroContainer && heroBg) {
        // Target values (lerp targets)
        let tBgX = 0, tBgY = 0;
        let tFgX = 0, tFgY = 0;
        // Current interpolated values
        let cBgX = 0, cBgY = 0;
        let cFgX = 0, cFgY = 0;

        let rafID = null;
        const LERP = 0.06; // smoothing factor

        const lerp = (a, b, t) => a + (b - a) * t;

        const onMouseMove = (e) => {
            const rect   = heroContainer.getBoundingClientRect();
            const xRel   = (e.clientX - rect.left)  / rect.width  - 0.5; // -0.5 → 0.5
            const yRel   = (e.clientY - rect.top)   / rect.height - 0.5;

            // Background: moves opposite to create depth parallax (max ±18px / ±10px)
            tBgX = xRel * -18;
            tBgY = yRel * -10;

            // Foreground elements: move slightly toward cursor (max ±10px / ±6px)
            tFgX = xRel * 10;
            tFgY = yRel * 6;

            // Update lens flare position (light follows mouse gently)
            if (heroLensFlare) {
                const flareTargetLeft = 52 + xRel * 8; // % offset
                const flareTargetTop  = 18 + yRel * 6;
                heroLensFlare.style.left = `${flareTargetLeft}%`;
                heroLensFlare.style.top  = `${flareTargetTop}%`;
            }

            heroContainer.classList.add('parallax-active'); // pauses CSS camera drift
            if (!rafID) rafID = requestAnimationFrame(parallaxLoop);
        };

        const onMouseLeave = () => {
            tBgX = 0; tBgY = 0;
            tFgX = 0; tFgY = 0;
            heroContainer.classList.remove('parallax-active');
        };

        const parallaxLoop = () => {
            // Smooth lerp toward targets
            cBgX = lerp(cBgX, tBgX, LERP);
            cBgY = lerp(cBgY, tBgY, LERP);
            cFgX = lerp(cFgX, tFgX, LERP);
            cFgY = lerp(cFgY, tFgY, LERP);

            // Apply to background (camera moves opposite)
            heroBg.style.transform = `scale(1.06) translate(${cBgX}px, ${cBgY}px)`;

            // Apply to fog layer
            if (heroFog) {
                heroFog.style.transform = `translate(${cFgX * 0.4}px, ${cFgY * 0.4}px)`;
            }

            // Apply to particles
            if (heroParticles) {
                heroParticles.style.transform = `translate(${cFgX * 0.7}px, ${cFgY * 0.5}px)`;
            }

            // Continue loop if still moving
            const stillMoving =
                Math.abs(cBgX - tBgX) > 0.01 ||
                Math.abs(cBgY - tBgY) > 0.01 ||
                Math.abs(cFgX - tFgX) > 0.01 ||
                Math.abs(cFgY - tFgY) > 0.01;

            rafID = stillMoving ? requestAnimationFrame(parallaxLoop) : null;
        };

        heroContainer.addEventListener('mousemove', onMouseMove, { passive: true });
        heroContainer.addEventListener('mouseleave', onMouseLeave);
    }


    // ══════════════════════════════════════════════════════════════
    // 3. CARD IMAGE PARALLAX — mouse moves image inside card bounds
    // ══════════════════════════════════════════════════════════════
    if (!isTouch && !isMobile) {
        document.querySelectorAll('.quick-card').forEach(card => {
            const bg = card.querySelector('.quick-card__bg');
            if (!bg) return;

            let tX = 0, tY = 0, cX = 0, cY = 0, rafCard = null;

            const lerpCard = (a, b, t) => a + (b - a) * t;

            card.addEventListener('mousemove', (e) => {
                const rect = card.getBoundingClientRect();
                const xRel = (e.clientX - rect.left) / rect.width  - 0.5;
                const yRel = (e.clientY - rect.top)  / rect.height - 0.5;

                // Small parallax on the background image (max ±8px)
                tX = xRel * -8;
                tY = yRel * -6;

                // Update light highlight position
                card.style.setProperty('--x', `${e.clientX - rect.left}px`);
                card.style.setProperty('--y', `${e.clientY - rect.top}px`);

                if (!rafCard) rafCard = requestAnimationFrame(cardLoop);
            }, { passive: true });

            card.addEventListener('mouseleave', () => {
                tX = 0; tY = 0;
            });

            const cardLoop = () => {
                cX = lerpCard(cX, tX, 0.08);
                cY = lerpCard(cY, tY, 0.08);

                // --px / --py drive the hover transform in CSS
                card.style.setProperty('--px', `${cX}px`);
                card.style.setProperty('--py', `${cY}px`);

                const stillMoving = Math.abs(cX - tX) > 0.01 || Math.abs(cY - tY) > 0.01;
                rafCard = stillMoving ? requestAnimationFrame(cardLoop) : null;
            };
        });
    }


    // ══════════════════════════════════════════════════════════════
    // 4. STATS COUNTER REVEAL
    // ══════════════════════════════════════════════════════════════
    function triggerCounters() {
        document.querySelectorAll('.stat-number').forEach(stat => {
            const target = parseInt(stat.getAttribute('data-target'), 10) || 0;

            if (isReduced || !hasGSAP) {
                stat.textContent = target.toLocaleString();
                return;
            }

            const obj = { val: 0 };
            gsap.to(obj, {
                val: target,
                duration: 2.0,
                ease: 'power2.out',
                onUpdate: () => { stat.textContent = Math.floor(obj.val).toLocaleString(); }
            });
        });
    }


    // ══════════════════════════════════════════════════════════════
    // 5. SCROLL REVEALS — GSAP + ScrollTrigger depth entrance
    //    Cards: scale(0.92) + blur(4px) → scale(1) + blur(0)
    //    Panels: translateY + blur → normal
    // ══════════════════════════════════════════════════════════════
    if (hasGSAP && !isReduced) {
        gsap.registerPlugin(ScrollTrigger);

        // ── Quick-action cards — depth Z reveal with stagger
        const cards = document.querySelectorAll('.quick-card');
        if (cards.length) {
            gsap.set(cards, {
                opacity: 0,
                scale: 0.92,
                y: 20,
                filter: 'blur(6px)'
            });

            ScrollTrigger.create({
                trigger: cards[0].closest('.row') || cards[0],
                start: 'top 88%',
                onEnter: () => {
                    gsap.to(cards, {
                        opacity: 1,
                        scale: 1,
                        y: 0,
                        filter: 'blur(0px)',
                        duration: 0.75,
                        stagger: 0.1,
                        ease: 'power3.out',
                        onComplete: () => {
                            // Mark revealed so CSS transitions take over
                            cards.forEach(c => c.classList.add('revealed'));
                        }
                    });
                },
                once: true
            });
        }

        // ── Lower panels (activity, tournaments, leaderboard)
        const panels = document.querySelectorAll('.card-arena');
        if (panels.length) {
            gsap.set(panels, { opacity: 0, y: 22, filter: 'blur(8px)' });

            panels.forEach((panel, i) => {
                ScrollTrigger.create({
                    trigger: panel,
                    start: 'top 92%',
                    onEnter: () => {
                        gsap.to(panel, {
                            opacity: 1,
                            y: 0,
                            filter: 'blur(0px)',
                            duration: 0.7,
                            delay: i * 0.06,
                            ease: 'power3.out'
                        });
                    },
                    once: true
                });
            });
        }

        // ── Hero stats strip panel — blur reveal
        const statsStrip = document.querySelector('.hero-stats-strip');
        if (statsStrip) {
            // Already handled by entrance, but add shimmer after load
            setTimeout(() => {
                gsap.from(statsStrip, {
                    backdropFilter: 'blur(0px)',
                    duration: 1.2,
                    ease: 'power2.out'
                });
            }, 1500);
        }
    }


    // ══════════════════════════════════════════════════════════════
    // 6. VISIBILITY API — pause hero animations when tab hidden
    //    Respects CPU/GPU when user switches tabs
    // ══════════════════════════════════════════════════════════════
    document.addEventListener('visibilitychange', () => {
        const heroBgEl   = document.querySelector('.hero-bg-img');
        const fogEl      = document.querySelector('.hero-fog');
        const particles  = document.querySelectorAll('.crowd-light, .field-particle, .energy-ring');
        const cardLive   = document.querySelectorAll('.live-dot');

        const state = document.hidden ? 'paused' : 'running';

        [heroBgEl, fogEl].forEach(el => {
            if (el) el.style.animationPlayState = state;
        });

        particles.forEach(el => { el.style.animationPlayState = state; });
        cardLive.forEach(el  => { el.style.animationPlayState = state; });

        if (hasGSAP) {
            document.hidden ? gsap.globalTimeline.pause() : gsap.globalTimeline.resume();
        }
    });


    // ══════════════════════════════════════════════════════════════
    // 7. CARD SWEEP — re-trigger animation on each hover entry
    //    (CSS animation only triggers once without JS reset)
    // ══════════════════════════════════════════════════════════════
    if (!isTouch) {
        document.querySelectorAll('.quick-card').forEach(card => {
            const sweep = card.querySelector('.quick-card__sweep');
            if (!sweep) return;

            card.addEventListener('mouseenter', () => {
                // Reset animation by removing and re-adding the pseudo element trigger
                sweep.style.setProperty('--sweep-running', '1');
                // Force reflow then remove so CSS animation re-fires
                const before = sweep.querySelector(':scope::before');
                sweep.classList.remove('sweep-active');
                void sweep.offsetWidth; // reflow
                sweep.classList.add('sweep-active');
            });

            card.addEventListener('mouseleave', () => {
                sweep.classList.remove('sweep-active');
            });
        });
    }
});
