// Scroll reveal — tags elements with `.in-view` when they enter the viewport.
// Usage: <Reveal><section>...</section></Reveal>
// Also auto-decorates elements matching selectors below at mount.

function useInView(ref, { threshold = 0.15, rootMargin = '0px 0px -10% 0px', once = true } = {}) {
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (typeof IntersectionObserver === 'undefined') { el.classList.add('in-view'); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach(e => {
        if (e.isIntersecting) {
          e.target.classList.add('in-view');
          if (once) io.unobserve(e.target);
        } else if (!once) {
          e.target.classList.remove('in-view');
        }
      });
    }, { threshold, rootMargin });
    io.observe(el);
    return () => io.disconnect();
  }, []);
}

function Reveal({ as = 'div', variant = 'reveal', className = '', children, ...rest }) {
  const ref = React.useRef(null);
  useInView(ref);
  const Tag = as;
  const cls = [variant, className].filter(Boolean).join(' ');
  return <Tag ref={ref} className={cls} {...rest}>{children}</Tag>;
}

// Auto-wire: once DOM is populated by React, scan the whole site and attach observers
// to every section + grid, so we don't need to retrofit every component file.
function autoWireScrollReveal() {
  if (typeof IntersectionObserver === 'undefined') return;
  const io = new IntersectionObserver((entries) => {
    entries.forEach(e => {
      if (e.isIntersecting) {
        e.target.classList.add('in-view');
        io.unobserve(e.target);
      }
    });
  }, { threshold: 0.12, rootMargin: '0px 0px -8% 0px' });

  // tag section roots
  document.querySelectorAll('.section, .wwd, .hero-d, .zw-footer').forEach(el => {
    if (!el.classList.contains('hero-d')) { // hero is visible from load
      el.classList.add('reveal');
    }
    io.observe(el);
  });
  // tag grids for stagger
  document.querySelectorAll('.services, .wwd-grid, .pf-grid, .tm-grid, .flow-grid, .blog-grid').forEach(el => {
    el.classList.add('reveal-stagger');
    io.observe(el);
  });
  // section heads slide in from left
  document.querySelectorAll('.section-head, .wwd-head').forEach(el => {
    el.classList.add('reveal-left');
    io.observe(el);
  });
}

// Run after React renders
if (typeof window !== 'undefined') {
  // defer to after React mount — re-run if DOM changes (React can mount late)
  let wired = false;
  const tryWire = () => {
    const hasSections = document.querySelector('.section');
    if (!hasSections) return;
    autoWireScrollReveal();
    wired = true;
  };
  // Attempt wiring repeatedly until sections appear
  const tryLoop = setInterval(() => {
    if (wired) { clearInterval(tryLoop); return; }
    tryWire();
  }, 80);
  setTimeout(() => clearInterval(tryLoop), 4000);

  // Also hook to scroll for tiny parallax drift (very subtle)
  let raf = 0;
  window.addEventListener('scroll', () => {
    if (raf) return;
    raf = requestAnimationFrame(() => {
      const y = window.scrollY;
      document.querySelectorAll('.drift').forEach(el => {
        const speed = parseFloat(el.dataset.driftSpeed || '0.1');
        el.style.transform = `translate3d(0, ${y * speed * -1}px, 0)`;
      });
      raf = 0;
    });
  }, { passive: true });
}

window.Reveal = Reveal;
window.autoWireScrollReveal = autoWireScrollReveal;
