// scene-frame.jsx
// Minimal headless wrapper for an Attesta scene — strips out the Stage's
// playback bar / dark chrome and only ticks the clock while `active` is true.
// Each scene was authored against a 1280x720 canvas; we scale to fit the
// container's width and preserve 16:9 via CSS aspect-ratio.

function SceneFrame({ Scene, duration = 10, active = true }) {
  const W = 1280, H = 720;
  const containerRef = React.useRef(null);
  const [time, setTime] = React.useState(0);
  const [scale, setScale] = React.useState(1);

  // Fit width — height follows from aspect-ratio CSS on the container.
  React.useLayoutEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const measure = () => {
      const w = el.clientWidth || 1;
      setScale(w / W);
    };
    measure();
    const ro = new ResizeObserver(measure);
    ro.observe(el);
    return () => ro.disconnect();
  }, []);

  // Loop the clock while active. Reset to 0 when re-activated so each step's
  // animation starts from the beginning when the user scrolls onto it.
  React.useEffect(() => {
    if (!active) return;
    setTime(0);
    let raf = 0;
    let last = null;
    const step = (ts) => {
      if (last == null) last = ts;
      const dt = (ts - last) / 1000;
      last = ts;
      setTime((t) => {
        let n = t + dt;
        if (n >= duration) n = n % duration;
        return n;
      });
      raf = requestAnimationFrame(step);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [active, duration]);

  const ctx = React.useMemo(
    () => ({ time, duration, playing: active, setTime: () => {}, setPlaying: () => {} }),
    [time, duration, active]
  );

  return (
    <div
      ref={containerRef}
      style={{
        width: '100%',
        aspectRatio: '16 / 9',
        position: 'relative',
        overflow: 'hidden',
        background: '#ffffff',
        borderRadius: 12,
        border: '1px solid hsl(240 6% 90%)',
        boxShadow: '0 1px 0 hsl(240 6% 95%), 0 30px 60px -30px rgba(11,29,58,0.18)',
      }}
    >
      <div
        style={{
          width: W,
          height: H,
          position: 'absolute',
          left: 0,
          top: 0,
          transform: `scale(${scale})`,
          transformOrigin: 'top left',
          willChange: 'transform',
        }}
      >
        <TimelineContext.Provider value={ctx}>
          <Scene />
        </TimelineContext.Provider>
      </div>
    </div>
  );
}

// Mount the six scene frames into the slots inside each step panel.
function HowItWorksAnimations() {
  const SCENES = [
    { id: 0, Scene: window.Scene1, duration: 14.0 },
    { id: 1, Scene: window.Scene2, duration: 11.5 },
    { id: 2, Scene: window.Scene3, duration: 7.0  },
    { id: 3, Scene: window.Scene4, duration: 13.0 },
    { id: 4, Scene: window.Scene5, duration: 8.0  },
    { id: 5, Scene: window.Scene6, duration: 8.5  },
  ];

  // Track which panel is currently active by watching the DOM for the
  // `.is-active` class the scroll-pin script toggles.
  const [activeIdx, setActiveIdx] = React.useState(0);
  React.useEffect(() => {
    const section = document.querySelector('.how-section');
    if (!section) return;
    const panels = Array.from(section.querySelectorAll('.step-panel'));
    let raf = 0;
    const observer = new MutationObserver(() => {
      // Coalesce
      if (raf) return;
      raf = requestAnimationFrame(() => {
        raf = 0;
        const idx = panels.findIndex((p) => p.classList.contains('is-active'));
        if (idx >= 0) setActiveIdx(idx);
      });
    });
    panels.forEach((p) =>
      observer.observe(p, { attributes: true, attributeFilter: ['class'] })
    );
    return () => observer.disconnect();
  }, []);

  return (
    <>
      {SCENES.map(({ id, Scene, duration }) => {
        const slot = document.getElementById(`scene-slot-${id}`);
        if (!slot || !Scene) return null;
        return ReactDOM.createPortal(
          <SceneFrame Scene={Scene} duration={duration} active={activeIdx === id} />,
          slot
        );
      })}
    </>
  );
}

window.HowItWorksAnimations = HowItWorksAnimations;
