// ACT 2 — Scroll-synced 360° rotation with orbiting callouts

const FRAME_NUMBERS = [1,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100,105,110,115,120];
const FRAME_SRCS = FRAME_NUMBERS.map(n => `images/belgha-360/frame-${String(n).padStart(3,'0')}.webp`);

function Act360({ lang, tweaks }) {
  const content = window.CONTENT[lang].rot;
  const sectionRef = useRef(null);
  const rawP = useStickyProgress(sectionRef);
  const [p, setP] = useState(0);
  const isRTL = lang === 'ar';
  const { isPhone, isTablet } = useResponsive();

  useEffect(() => {
    FRAME_SRCS.forEach(src => {
      const img = new Image();
      img.src = src;
      if (img.decode) img.decode().catch(() => {});
    });
  }, []);

  useEffect(() => {
    let raf;
    const tick = () => {
      setP(current => {
        const next = current + (rawP - current) * 0.14;
        return Math.abs(next - current) < 0.0005 ? current : next;
      });
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [rawP]);

  const intro = clamp(p / 0.16, 0, 1);
  // Start from the exact same first frame used at the end of the hero.
  const rot = clamp(p / 0.82, 0, 1);
  // End: 0.85-1 fade out/zoom
  const out = clamp((p - 0.85) / 0.15, 0, 1);

  const frameIdx = Math.min(FRAME_SRCS.length - 1, Math.floor(rot * FRAME_SRCS.length));
  const degrees = Math.round(rot * 360);

  const stageScale = lerp(1, 1.15, out);
  const stageOpacity = 1 - out * 0.5;

  // Callouts fade in at certain points
  const calloutStart = 0.2;
  const calloutPhases = [0.25, 0.42, 0.6, 0.75];

  return (
    <section ref={sectionRef} className="act" style={{ height: isPhone ? '420vh' : '500vh' }}>
      <div style={{
        position: 'sticky', top: 0, height: isPhone ? '100svh' : '100vh', overflow: 'hidden',
        background: '#020203',
        display: 'flex', alignItems: 'center', justifyContent: 'center'
      }}>
        {/* Ambient spotlight */}
        <div style={{
          position: 'absolute', inset: 0,
          background: 'radial-gradient(circle at 50% 55%, rgba(255,255,255,0.035), transparent 55%)',
          pointerEvents: 'none'
        }} />

        {/* Grid lines */}
        <svg style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', opacity: 0.08 * intro }}>
          <defs>
            <pattern id="grid" width="80" height="80" patternUnits="userSpaceOnUse">
              <path d="M 80 0 L 0 0 0 80" fill="none" stroke="#fafaf7" strokeWidth="0.5"/>
            </pattern>
          </defs>
          <rect width="100%" height="100%" fill="url(#grid)" />
        </svg>

        {/* Section header */}
        <div style={{
          position: 'absolute', top: isPhone ? 'calc(72px + env(safe-area-inset-top))' : '10vh', left: 0, right: 0,
          textAlign: 'center', zIndex: 2,
          opacity: clamp((p - 0.08) / 0.16, 0, 1) * (1 - out),
          padding: isPhone ? '0 22px' : 0
        }}>
          <div className="mono" style={{ color: 'var(--fg-dim)', marginBottom: 18 }}>{content.eyebrow}</div>
          <h2 style={{
            fontFamily: isRTL ? 'var(--font-ar)' : 'var(--font-serif)',
            fontWeight: 300,
            fontSize: isPhone ? 'clamp(31px, 9vw, 40px)' : 'clamp(36px, 5vw, 68px)',
            lineHeight: isPhone ? 1.08 : 1,
            letterSpacing: '-0.02em'
          }}>
            {content.h} <span style={{ fontStyle: 'italic' }}>{content.hIt}</span>
          </h2>
        </div>

        {/* 360 stage */}
        <div style={{
          position: 'relative',
          width: isPhone ? 'min(92vw, 360px)' : isTablet ? 'min(72vw, 620px)' : 'min(70vw, 780px)',
          height: isPhone ? 'min(68vw, 270px)' : isTablet ? 'min(58vw, 520px)' : 'min(70vw, 780px)',
          transform: `scale(${stageScale})`,
          opacity: stageOpacity,
          zIndex: 1
        }}>
          <div style={{
            position: 'relative', width: '100%', height: '100%',
            filter: 'brightness(1.1) contrast(1.08) saturate(1.02) drop-shadow(0 30px 50px rgba(0,0,0,0.58))'
          }}>
            {FRAME_SRCS.map((src, i) => (
              <img
                key={i}
                src={src}
                loading="eager"
                decoding="async"
                style={{
                  position: 'absolute', inset: 0,
                  width: '100%', height: '100%',
                  objectFit: 'contain',
                  opacity: i === frameIdx ? 1 : 0
                }}
              />
            ))}
          </div>
          {/* Floor shadow */}
          <div style={{
            position: 'absolute',
            bottom: '8%', left: '18%', right: '18%',
            height: 12,
            background: 'radial-gradient(ellipse at center, rgba(0,0,0,0.9), transparent 70%)',
            filter: 'blur(10px)'
          }} />

          {/* Orbiting callouts */}
          {tweaks.showCallouts && content.callouts.map((c, i) => {
            const on = rot >= calloutPhases[i];
            const off = i < content.callouts.length - 1 && rot >= calloutPhases[i + 1] + (isPhone ? 0 : 0.05);
            const visible = on && !off;
            return (
              <div key={i} style={{
                position: 'absolute',
                left: isPhone
                  ? c.x < 50 ? 'max(22px, env(safe-area-inset-left))' : 'auto'
                  : `${c.x}%`,
                right: isPhone
                  ? c.x >= 50 ? 'max(22px, env(safe-area-inset-right))' : 'auto'
                  : 'auto',
                top: isPhone
                  ? `clamp(calc(152px + env(safe-area-inset-top)), ${c.y}svh, calc(100svh - 164px - env(safe-area-inset-bottom)))`
                  : `${c.y}%`,
                bottom: 'auto',
                opacity: visible ? 1 : 0,
                transform: visible ? 'translateX(0)' : `translateX(${isPhone ? 0 : -10}px) translateY(${isPhone ? 14 : 0}px)`,
                transition: 'opacity 0.6s, transform 0.6s',
                display: 'flex',
                alignItems: 'center',
                gap: isPhone ? 8 : 12,
                maxWidth: isPhone ? 'min(42vw, 170px)' : 'none',
                filter: isPhone ? 'drop-shadow(0 8px 16px rgba(0,0,0,0.52))' : 'none',
                pointerEvents: 'none'
              }}>
                <div style={{ width: isPhone ? 5 : 6, height: isPhone ? 5 : 6, flex: '0 0 auto', background: 'var(--fg)', borderRadius: '50%', boxShadow: '0 0 16px rgba(255,255,255,0.6)' }} />
                <div style={{ width: isPhone ? 24 : c.x < 50 ? 0 : 60, flex: '0 0 auto', height: 1, background: 'var(--fg-dim)', order: !isPhone && c.x < 50 ? -1 : 0 }} />
                {!isPhone && c.x < 50 && <div style={{ width: 60, height: 1, background: 'var(--fg-dim)' }} />}
                <div style={{ textAlign: c.x < 50 ? 'right' : 'left', order: !isPhone && c.x < 50 ? -2 : 0, minWidth: 0 }}>
                  <div className="mono" style={{ color: 'var(--fg)', fontSize: isPhone ? 9 : 11, lineHeight: isPhone ? 1.28 : 'normal', fontWeight: 500, whiteSpace: isPhone ? 'normal' : 'nowrap' }}>{c.title}</div>
                  <div className="mono" style={{ color: 'var(--fg-dim)', fontSize: isPhone ? 9 : 10, lineHeight: isPhone ? 1.28 : 'normal', marginTop: 4, whiteSpace: isPhone ? 'normal' : 'nowrap' }}>{c.body}</div>
                </div>
              </div>
            );
          })}
        </div>

        {/* Rotation meter removed */}
      </div>
    </section>
  );
}

window.Act360 = Act360;
