// Scroll-driven exploded view of a product.
// Drops a long "sticky" section; as the user scrolls through it, the image
// swaps through a frame sequence so it looks like the product explodes apart.

function ScrollExplode({ frameCount = 23, framePath = 'assets/wing-explode/frame-', frameExt = '.png', heightVh = 300 }) {
  const sectionRef = React.useRef(null);
  const stageRef = React.useRef(null);
  const [frame, setFrame] = React.useState(1);
  const [progress, setProgress] = React.useState(0);

  // Preload frames
  React.useEffect(() => {
    for (let i = 1; i <= frameCount; i++) {
      const img = new Image();
      img.src = `${framePath}${String(i).padStart(3, '0')}${frameExt}`;
    }
  }, [frameCount, framePath, frameExt]);

  React.useEffect(() => {
    const el = sectionRef.current;
    if (!el) return;
    let raf = 0, alive = true;
    let lastP = -1;

    const compute = () => {
      const rect = el.getBoundingClientRect();
      const vh = window.innerHeight;
      const total = Math.max(1, rect.height - vh);
      const scrolled = -rect.top;
      const p = Math.max(0, Math.min(1, scrolled / total));
      if (Math.abs(p - lastP) > 0.001) {
        lastP = p;
        setProgress(p);
        setFrame(Math.max(1, Math.min(frameCount, Math.round(p * (frameCount - 1)) + 1)));
      }
      const stage = stageRef.current;
      if (stage) {
        if (rect.top > 0) stage.style.transform = 'translateY(0)';
        else if (rect.bottom < vh) stage.style.transform = `translateY(${rect.height - vh}px)`;
        else stage.style.transform = `translateY(${-rect.top}px)`;
      }
    };

    const tick = () => { if (!alive) return; compute(); raf = requestAnimationFrame(tick); };
    compute();
    raf = requestAnimationFrame(tick);
    const interval = setInterval(compute, 100);
    const onScroll = () => compute();
    window.addEventListener('scroll', onScroll, { passive: true, capture: true });
    document.addEventListener('scroll', onScroll, { passive: true, capture: true });
    window.addEventListener('resize', compute);
    return () => {
      alive = false;
      cancelAnimationFrame(raf);
      clearInterval(interval);
      window.removeEventListener('scroll', onScroll, { capture: true });
      document.removeEventListener('scroll', onScroll, { capture: true });
      window.removeEventListener('resize', compute);
    };
  }, [frameCount]);

  const src = `${framePath}${String(frame).padStart(3, '0')}${frameExt}`;

  // Callouts tied to scroll progress
  const callouts = [
    { at: 0.08, end: 0.35, side: 'left', label: 'CARCASA EXTERIOR', detail: 'Policarbonato in-mold, ventilación 14 canales' },
    { at: 0.22, end: 0.55, side: 'right', label: 'LINER MIPS', detail: 'Sistema de protección multi-direccional' },
    { at: 0.45, end: 0.80, side: 'left', label: 'ACOLCHADO RPM+', detail: 'Lavable, antimicrobiano, reemplazable' },
    { at: 0.65, end: 0.98, side: 'right', label: 'CORREA FIDLOCK®', detail: 'Ajuste magnético con una mano' },
  ];

  return (
    <section ref={sectionRef} style={{ position: 'relative', height: `${heightVh}vh`, background: 'var(--bg-sunk)' }}>
      <div ref={stageRef} style={{ position: 'absolute', top: 0, left: 0, right: 0, height: '100vh', overflow: 'hidden', willChange: 'transform' }}>
        {/* Left column: copy */}
        <div style={{ position: 'absolute', inset: 0, display: 'grid', gridTemplateColumns: '1fr 1.2fr 1fr' }}>
          {/* Left panel */}
          <div style={{ padding: '80px 48px', display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}>
            <div>
              <div className="eyebrow eyebrow-accent" style={{ marginBottom: 16 }}>— Anatomía</div>
              <h2 className="font-display" style={{ fontSize: 56, margin: 0, fontWeight: 400, lineHeight: 1.02, letterSpacing: '-0.02em' }}>
                Desarma el <em>Wing.</em>
              </h2>
              <p style={{ marginTop: 20, fontSize: 14, lineHeight: 1.7, color: 'var(--ink-2)', maxWidth: 320 }}>
                Desplázate para ver cómo se construye uno de los cascos aero más vendidos de Rudy Project — pieza por pieza.
              </p>
            </div>
            <div>
              <div className="font-mono" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '0.08em', marginBottom: 8 }}>PROGRESO</div>
              <div style={{ height: 2, background: 'var(--rule)', position: 'relative' }}>
                <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: `${progress * 100}%`, background: 'var(--ink)', transition: 'width 60ms linear' }}/>
              </div>
              <div className="font-mono" style={{ fontSize: 10, color: 'var(--ink-3)', letterSpacing: '0.08em', marginTop: 8, display: 'flex', justifyContent: 'space-between' }}>
                <span>FRAME {String(frame).padStart(3, '0')} / {String(frameCount).padStart(3, '0')}</span>
                <span>{Math.round(progress * 100)}%</span>
              </div>
            </div>
          </div>

          {/* Center stage */}
          <div style={{ position: 'relative', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
            <img
              src={src}
              alt="Exploded view"
              style={{ maxWidth: '100%', maxHeight: '80vh', display: 'block', mixBlendMode: 'multiply' }}
            />
          </div>

          {/* Right panel — callouts */}
          <div style={{ position: 'relative', padding: '80px 48px' }}>
            {callouts.map((c, i) => {
              const active = progress >= c.at && progress <= c.end;
              const fadeIn = Math.min(1, Math.max(0, (progress - c.at) * 12));
              const fadeOut = Math.min(1, Math.max(0, (c.end - progress) * 12));
              const op = active ? Math.min(fadeIn, fadeOut) : 0;
              return (
                <div key={i} style={{
                  position: 'absolute',
                  top: `${20 + i * 18}%`,
                  left: c.side === 'right' ? 48 : 'auto',
                  right: c.side === 'left' ? 48 : 'auto',
                  opacity: op,
                  transform: `translateY(${(1 - op) * 20}px)`,
                  transition: 'opacity 200ms, transform 200ms',
                  maxWidth: 280,
                  pointerEvents: active ? 'auto' : 'none',
                }}>
                  <div className="font-mono" style={{ fontSize: 10, letterSpacing: '0.12em', color: 'var(--it-red-ink)', marginBottom: 6 }}>
                    ◇ 0{i + 1}
                  </div>
                  <div className="font-display" style={{ fontSize: 26, fontStyle: 'italic', lineHeight: 1.1, letterSpacing: '-0.01em' }}>{c.label}</div>
                  <div style={{ marginTop: 8, fontSize: 13, color: 'var(--ink-2)', lineHeight: 1.5 }}>{c.detail}</div>
                  <div style={{ marginTop: 14, height: 1, width: 80, background: 'var(--ink)' }}/>
                </div>
              );
            })}
          </div>
        </div>

        {/* Bottom ticker */}
        <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, padding: '16px 48px', borderTop: '1px solid var(--rule)', display: 'flex', justifyContent: 'space-between', alignItems: 'center', background: 'var(--bg-sunk)' }}>
          <div className="eyebrow">RUDY PROJECT · THE WING · COSMIC BLUE MATTE</div>
          <div className="font-mono" style={{ fontSize: 11, letterSpacing: '0.1em', color: 'var(--ink-3)' }}>
            {progress < 0.05 ? '↓ DESPLÁZATE PARA EXPLORAR' : progress > 0.95 ? '↑ REGRESAR AL INICIO' : 'EN CONSTRUCCIÓN…'}
          </div>
          <div className="font-mono" style={{ fontSize: 11, letterSpacing: '0.1em' }}>$5,490 MXN</div>
        </div>
      </div>
    </section>
  );
}

window.ScrollExplode = ScrollExplode;
