/**
 * Supernova 2.0 — Star Wars Scroll Animation Engine
 * Elements animate in with epic perspective crawl / warp effects on scroll.
 */

(function () {
  'use strict';

  /* ------------------------------------------------------------------ */
  /* 1. INJECT CSS                                                        */
  /* ------------------------------------------------------------------ */
  const style = document.createElement('style');
  style.textContent = `
    /* ── base hidden state — "skip" elements are excluded ── */
    [data-animate]:not([data-animate="skip"]) {
      opacity: 0;
      transition-property: opacity, transform, filter;
      transition-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
      will-change: opacity, transform;
    }

    /* ── crawl-up  (default): rises from below with perspective tilt ── */
    [data-animate="crawl"],
    [data-animate]:not([data-animate="skip"]) {
      transform: perspective(800px) rotateX(18deg) translateY(60px);
      filter: blur(4px);
      transition-duration: 0.9s;
    }

    /* ── warp-in: zooms in from far away (hyperspace arrival) ── */
    [data-animate="warp"] {
      transform: perspective(600px) scale(0.6) translateZ(-300px);
      filter: blur(8px) brightness(2);
      transition-duration: 1.1s;
    }

    /* ── slide-left  ── */
    [data-animate="slide-left"] {
      transform: perspective(800px) rotateY(-20deg) translateX(-80px);
      filter: blur(3px);
      transition-duration: 0.85s;
    }

    /* ── slide-right ── */
    [data-animate="slide-right"] {
      transform: perspective(800px) rotateY(20deg) translateX(80px);
      filter: blur(3px);
      transition-duration: 0.85s;
    }

    /* ── flare: fades in with a bright flash ── */
    [data-animate="flare"] {
      transform: scale(1.08);
      filter: blur(6px) brightness(3);
      transition-duration: 1s;
    }

    /* ── hyperline: thin horizontal streak then expands ── */
    [data-animate="hyperline"] {
      transform: perspective(800px) scaleX(0.05) rotateX(12deg);
      filter: blur(10px) brightness(4);
      transition-duration: 1s;
    }

    /* ── VISIBLE state (shared by all — skip elements never reach here anyway) ── */
    [data-animate]:not([data-animate="skip"]).sw-visible {
      opacity: 1;
      transform: none;
      filter: none;
    }


    /* ── stagger delay helpers ── */
    [data-delay="100"] { transition-delay: 0.10s; }
    [data-delay="150"] { transition-delay: 0.15s; }
    [data-delay="200"] { transition-delay: 0.20s; }
    [data-delay="250"] { transition-delay: 0.25s; }
    [data-delay="300"] { transition-delay: 0.30s; }
    [data-delay="400"] { transition-delay: 0.40s; }
    [data-delay="500"] { transition-delay: 0.50s; }
    [data-delay="600"] { transition-delay: 0.60s; }
    [data-delay="700"] { transition-delay: 0.70s; }

    /* ── Hyperspace particles overlay ── */
    #sw-hyperspace {
      position: fixed;
      inset: 0;
      pointer-events: none;
      z-index: 9999;
      overflow: hidden;
    }
    .sw-streak {
      position: absolute;
      top: 50%;
      left: 50%;
      width: 2px;
      height: 0;
      background: linear-gradient(to bottom, transparent, rgba(120,220,255,0.9), transparent);
      border-radius: 9999px;
      opacity: 0;
      transform-origin: center top;
      animation: sw-streak-anim linear forwards;
    }
    @keyframes sw-streak-anim {
      0%   { height: 0;    opacity: 0.9; }
      80%  { height: 120px; opacity: 0.8; }
      100% { height: 180px; opacity: 0; }
    }
  `;
  document.head.appendChild(style);

  /* ------------------------------------------------------------------ */
  /* 2. AUTO-ANNOTATE elements that don't already have data-animate      */
  /* ------------------------------------------------------------------ */
  const AUTO_SELECTORS = [
    /* headings */
    'h1:not([data-animate])',
    'h2:not([data-animate])',
    'h3:not([data-animate])',
    /* cards / panels */
    '.glass-panel:not([data-animate])',
    '.glass-card:not([data-animate])',
    '.event-card:not([data-animate])',
    /* grids */
    '.grid > *:not([data-animate])',
    /* list items */
    'ul > li:not([data-animate])',
    /* buttons / links that are prominent */
    'a.shadow-glow:not([data-animate])',
    'button[type="submit"]:not([data-animate])',
    /* stat / info blocks */
    '[class*="border-white/10"]:not([data-animate])',
  ];

  function annotateElements() {
    const effectMap = ['crawl', 'slide-left', 'slide-right', 'warp', 'flare'];

    AUTO_SELECTORS.forEach(sel => {
      document.querySelectorAll(sel).forEach((el, i) => {
        // skip tiny or offscreen-forever elements
        if (el.offsetParent === null && !el.closest('body')) return;
        // skip elements explicitly opted out (hero elements use CSS keyframes instead)
        if (el.getAttribute('data-animate') === 'skip') return;

        // pick animation style based on element type
        let type = 'crawl';
        if (sel.includes('h1') || sel.includes('h2')) type = 'warp';
        else if (i % 5 === 1) type = 'slide-left';
        else if (i % 5 === 2) type = 'slide-right';
        else if (sel.includes('shadow-glow')) type = 'flare';

        el.setAttribute('data-animate', type);

        // stagger siblings inside the same parent
        const siblings = Array.from(el.parentElement?.children || []);
        const idx = siblings.indexOf(el);
        if (idx > 0) {
          const delays = [0, 100, 200, 300, 400, 500];
          el.setAttribute('data-delay', delays[Math.min(idx, delays.length - 1)]);
        }
      });
    });
  }

  /* ------------------------------------------------------------------ */
  /* 3. INTERSECTION OBSERVER — triggers animations on scroll            */
  /* ------------------------------------------------------------------ */
  function setupObserver() {
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add('sw-visible');
          observer.unobserve(entry.target);
        }
      });
    }, {
      threshold: 0.08,
      rootMargin: '0px 0px -40px 0px'
    });

    // Only observe real animated elements — not skip elements
    document.querySelectorAll('[data-animate]:not([data-animate="skip"])').forEach(el => {
      observer.observe(el);
    });
  }

  /* ------------------------------------------------------------------ */
  /* 4. HYPERSPACE STREAK BURST — fires when user scrolls fast           */
  /* ------------------------------------------------------------------ */
  const isMainPage = !!document.getElementById('supernova-hero-heading');
  
  if (isMainPage) {
    let lastScrollY = window.scrollY;
    let streakTimeout = null;

    const hyperspace = document.createElement('div');
    hyperspace.id = 'sw-hyperspace';
    document.body.appendChild(hyperspace);

    function createStreak() {
      const streak = document.createElement('div');
      streak.className = 'sw-streak';

      const angle = Math.random() * 360;
      const dist  = 20 + Math.random() * 42; // % from center
      const x = 50 + dist * Math.cos((angle * Math.PI) / 180);
      const y = 50 + dist * Math.sin((angle * Math.PI) / 180);
      const duration = 0.25 + Math.random() * 0.35;
      const size = 1.5 + Math.random() * 2.5;

      streak.style.cssText = `
        left: ${x}%;
        top: ${y}%;
        width: ${size}px;
        transform: rotate(${angle + 90}deg);
        animation-duration: ${duration}s;
      `;
      hyperspace.appendChild(streak);
      setTimeout(() => streak.remove(), duration * 1000 + 50);
    }

    function onScroll() {
      const dy = Math.abs(window.scrollY - lastScrollY);
      lastScrollY = window.scrollY;

      if (dy > 50) {
        const count = Math.min(Math.floor(dy / 25), 18);
        for (let i = 0; i < count; i++) {
          setTimeout(createStreak, i * 18);
        }
      }

      clearTimeout(streakTimeout);
      streakTimeout = setTimeout(() => {}, 200);
    }

    window.addEventListener('scroll', onScroll, { passive: true });
  }

  /* ------------------------------------------------------------------ */
  /* 5. REINIT — resets all animations and re-observes every element     */
  /* ------------------------------------------------------------------ */
  function reinit() {
    // Strip sw-visible from all animated elements so they animate in again
    // but NOT from skip elements (those use CSS keyframes, not this system)
    document.querySelectorAll('[data-animate]:not([data-animate="skip"])').forEach(el => {
      el.classList.remove('sw-visible');
    });

    // Re-annotate any new elements, then re-run the observer
    annotateElements();
    setupObserver();

    // Immediately reveal elements that are already in the viewport
    document.querySelectorAll('[data-animate]:not([data-animate="skip"])').forEach(el => {
      const rect = el.getBoundingClientRect();
      if (rect.top < window.innerHeight && rect.bottom > 0) {
        setTimeout(() => el.classList.add('sw-visible'), 80);
      }
    });
  }

  /* ------------------------------------------------------------------ */
  /* 6. INIT                                                              */
  /* ------------------------------------------------------------------ */
  function init() {
    annotateElements();
    setupObserver();

    // Make elements already in view visible — but skip hero elements
    // (they use CSS keyframes and handle their own animation)
    document.querySelectorAll('[data-animate]:not([data-animate="skip"])').forEach(el => {
      const rect = el.getBoundingClientRect();
      if (rect.top < window.innerHeight && rect.bottom > 0) {
        // slight delay so the CSS transition is already registered
        setTimeout(() => el.classList.add('sw-visible'), 80);
      }
    });
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
  } else {
    init();
  }

  // ── Re-run animations when page is restored from bfcache (back/forward nav) ──
  // `persisted = true` means the page was pulled from the browser's back/forward cache
  window.addEventListener('pageshow', (e) => {
    if (e.persisted) {
      // Small delay ensures the DOM is fully painted before we reset
      setTimeout(reinit, 50);
    }
  });

  // ── Also handle programmatic same-tab navigation (SPA-style pushState) ──
  // and the case where the user hides/shows the tab and comes back to the home link
  document.addEventListener('visibilitychange', () => {
    if (document.visibilityState === 'visible') {
      // Only reinit if we're on a page that has hero/animated elements
      // and the SUPERNOVA title is not yet visible (was reset)
      const heroTitle = document.getElementById('supernova-hero-heading');
      if (heroTitle && !heroTitle.classList.contains('sw-visible')) {
        setTimeout(reinit, 80);
      }
    }
  });

})();
