// Act IVa — THE OBJECT (reveal)
// The Lenglen dress lands center-stage. This act is pure object: a big
// garment plate with six hotspots, a single editorial line, a museum-plate
// caption. The argument that follows (why it mattered) lives in IVb — this
// stop is the reveal, and the presenter should linger on it.

const { useState, useEffect, useRef, useMemo, useLayoutEffect } = window;

const HOTSPOTS_4A = [
  { id: 1, x: 52, y: 12, label: 'Headband',     body: 'The signature Lenglen silk — orange or amaranth.' },
  { id: 2, x: 64, y: 22, label: 'Bare arms',    body: 'Unthinkable in 1920 women\u2019s sport; the scandal that made the cover.' },
  { id: 3, x: 38, y: 40, label: 'Drop waist',   body: 'The 1920s silhouette, adapted to the courtside.' },
  { id: 4, x: 70, y: 52, label: 'Knife pleats', body: 'Hand-set pleats — ~72 radial folds, silk-jersey, designed to travel with the serve.' },
  { id: 5, x: 46, y: 70, label: 'Hemline',      body: 'Knee-length — a decade earlier this was prosecutable.' },
  { id: 6, x: 56, y: 86, label: 'Shoe',         body: 'Canvas and rubber — the first recognizable athletic shoe.' },
];

function Hotspot4a({ h, active, onHover }) {
  return (
    <button
      aria-label={h.label}
      onMouseEnter={() => onHover(h.id)}
      onMouseLeave={() => onHover(null)}
      onFocus={() => onHover(h.id)}
      onBlur={() => onHover(null)}
      style={{
        position: 'absolute',
        left: `${h.x}%`, top: `${h.y}%`,
        transform: 'translate(-50%, -50%)',
        width: 30, height: 30,
        border: 'none', background: 'transparent',
        cursor: 'pointer', padding: 0,
      }}
    >
      <span style={{
        position: 'absolute', inset: 0, borderRadius: '50%',
        background: active ? 'var(--gold)' : 'rgba(143,166,143,0.9)',
        boxShadow: active ? '0 0 28px rgba(201,168,76,0.7)' : '0 0 16px rgba(143,166,143,0.4)',
        transform: active ? 'scale(1.2)' : 'scale(1)',
        transition: 'all 0.35s ease',
      }} />
      <span style={{
        position: 'absolute', inset: 8, borderRadius: '50%',
        background: 'var(--petrol-deep)',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontFamily: 'var(--font-display)', fontSize: 10,
        color: active ? 'var(--gold)' : 'var(--sage)', fontWeight: 700,
      }}>{h.id}</span>
      <span style={{
        position: 'absolute', inset: -5, borderRadius: '50%',
        border: '1px solid rgba(143,166,143,0.35)',
        animation: 'hpulse4a 2.6s ease-out infinite',
        opacity: active ? 0 : 1,
      }} />
      <style>{`@keyframes hpulse4a { 0%{transform:scale(1);opacity:.6} 100%{transform:scale(1.85);opacity:0} }`}</style>
    </button>
  );
}

function HotspotCaption4a({ h, visible }) {
  if (!h) return null;
  return (
    <div
      style={{
        position: 'absolute',
        left: h.x > 50 ? 'auto' : `${h.x}%`,
        right: h.x > 50 ? `${100 - h.x}%` : 'auto',
        top: `${h.y}%`,
        transform: `translate(${h.x > 50 ? '-30px' : '30px'}, -50%)`,
        maxWidth: 300,
        padding: '16px 20px',
        background: 'rgba(7,50,66,0.94)',
        border: '1px solid rgba(201,168,76,0.45)',
        backdropFilter: 'blur(6px)',
        opacity: visible ? 1 : 0,
        transition: 'opacity 0.25s ease',
        pointerEvents: 'none',
        zIndex: 20,
      }}
    >
      <div className="label-text" style={{ color: 'var(--gold)', marginBottom: 6 }}>
        № 0{h.id} · {h.label}
      </div>
      <div className="font-editorial" style={{ fontSize: 13.5, lineHeight: 1.55, color: 'var(--parchment)', fontStyle: 'italic' }}>
        {h.body}
      </div>
    </div>
  );
}

function ActObjectRevealInner({ index, total, act }) {
  const [ref, visible] = useBeatReveal(0);
  const [activeHotspot, setActiveHotspot] = useState(null);

  // Auto-tour the hotspots once, then rest.
  useEffect(() => {
    if (!visible) { setActiveHotspot(null); return; }
    let i = 0;
    const iv = setInterval(() => {
      i = (i + 1) % (HOTSPOTS_4A.length + 1);
      setActiveHotspot(i === HOTSPOTS_4A.length ? null : HOTSPOTS_4A[i].id);
    }, 1400);
    const stop = setTimeout(() => { clearInterval(iv); setActiveHotspot(null); }, 1400 * (HOTSPOTS_4A.length + 2));
    return () => { clearInterval(iv); clearTimeout(stop); };
  }, [visible]);

  const current = activeHotspot ? HOTSPOTS_4A.find(h => h.id === activeHotspot) : null;

  return (
    <ActFrame act={act} index={index} total={total} bg="var(--petrol-deep)">
      <ActSeam roman={act.roman} />

      <div ref={ref} style={{ paddingTop: 30, display: 'flex', flexDirection: 'column', minHeight: 'calc(100vh - 160px)' }}>
        {/* Accession header */}
        <div style={{
          display: 'flex', justifyContent: 'space-between', alignItems: 'flex-end', marginBottom: 24,
          opacity: visible ? 1 : 0, transform: visible ? 'translateY(0)' : 'translateY(10px)',
          transition: 'all 1.0s cubic-bezier(0.16,1,0.3,1)',
        }}>
          <div>
            <span className="label-text" style={{ color: 'var(--sage)' }}>
              Object № 012 · Jean Patou for Suzanne Lenglen · France · 1921
            </span>
            <h2 className="font-display" style={{
              fontSize: 'clamp(52px, 6vw, 92px)',
              lineHeight: 0.98, letterSpacing: '-0.02em',
              color: 'var(--parchment)', margin: '14px 0 0', textTransform: 'uppercase',
            }}>
              The frock that <span style={{ color: 'var(--gold)', fontStyle: 'italic' }}>ended the corset</span>.
            </h2>
          </div>
          <div style={{ textAlign: 'right' }}>
            <QRCard
              url="https://vintaverse-eight.vercel.app"
              kicker="Scan · Enter VintaVerse"
              label="vintaverse-eight.vercel.app"
              size={104}
            />
          </div>
        </div>

        {/* Big garment stage — takes the rest of the viewport */}
        <div style={{
          position: 'relative',
          flex: 1,
          minHeight: 560,
          background:
            'radial-gradient(ellipse 60% 70% at 50% 45%, rgba(201,168,76,0.16), transparent 68%),' +
            'linear-gradient(180deg, rgba(7,50,66,0.9), rgba(7,50,66,0.98))',
          border: '1px solid rgba(143,166,143,0.15)',
          overflow: 'hidden',
          opacity: visible ? 1 : 0,
          transform: visible ? 'scale(1)' : 'scale(0.985)',
          transition: 'all 1.6s cubic-bezier(0.16,1,0.3,1) 0.2s',
        }}>
          {/* Spotlight */}
          <div aria-hidden style={{
            position: 'absolute', inset: 0,
            background: 'radial-gradient(ellipse 42% 62% at 50% 48%, rgba(255,255,255,0.14), transparent 62%)',
            pointerEvents: 'none',
          }} />
          {/* Frame */}
          <div style={{ position: 'absolute', inset: 26, border: '1px solid rgba(143,166,143,0.14)', pointerEvents: 'none' }} />

          {/* The garment */}
          <img src="assets/lenglen-1920s.png" alt="Suzanne Lenglen tennis dress, 1921"
            style={{
              position: 'absolute', inset: 0,
              width: '100%', height: '100%', objectFit: 'contain',
              padding: '52px 24px',
              filter: 'drop-shadow(0 50px 70px rgba(0,0,0,0.6))',
            }}
          />

          {/* Hotspots */}
          {HOTSPOTS_4A.map((h) => (
            <Hotspot4a key={h.id} h={h}
              active={activeHotspot === h.id}
              onHover={setActiveHotspot}
            />
          ))}
          <HotspotCaption4a h={current} visible={!!current} />

          {/* One-line wall-label floating top-left of stage */}
          <div style={{
            position: 'absolute', top: 40, left: 48, maxWidth: 360,
            borderLeft: '2px solid var(--gold)',
            padding: '8px 0 8px 18px',
          }}>
            <div className="label-text" style={{ color: 'var(--gold)' }}>Wall label · excerpt</div>
            <div className="font-editorial" style={{ fontSize: 16.5, lineHeight: 1.55, color: 'var(--parchment)', marginTop: 8, fontStyle: 'italic' }}>
              “Sleeveless, knee-length, silk jersey — and the crowd at Wimbledon decided what a woman could wear to compete.”
            </div>
          </div>

          {/* Museum plate corner */}
          <div style={{
            position: 'absolute', bottom: 32, left: 48,
            display: 'flex', alignItems: 'center', gap: 12,
          }}>
            <span style={{ width: 10, height: 10, background: 'var(--gold)', display: 'inline-block' }} />
            <span className="label-text" style={{ color: 'var(--parchment-dim)', letterSpacing: '0.3em' }}>
              PATOU · 1921 · SILK JERSEY · KNIFE PLEATS
            </span>
          </div>

          {/* Wimbledon source attribution — bottom-right of the stage. The
              dress that ran the All England Club's whites rule into the 21st
              century deserves to point at the Centre Court's own archive. */}
          <a
            href="https://www.wimbledon.com"
            target="_blank"
            rel="noopener noreferrer"
            style={{
              position: 'absolute', bottom: 32, right: 48,
              display: 'flex', alignItems: 'center', gap: 8,
              textDecoration: 'none',
              color: 'var(--parchment-dim)',
              transition: 'color 0.3s ease',
            }}
            onMouseEnter={(e) => { e.currentTarget.style.color = 'var(--gold)'; }}
            onMouseLeave={(e) => { e.currentTarget.style.color = 'var(--parchment-dim)'; }}
          >
            <span className="label-text" style={{ letterSpacing: '0.3em' }}>
              Source · WIMBLEDON.COM
            </span>
            <span style={{ fontFamily: 'var(--font-display)', fontSize: 12 }}>↗</span>
          </a>

        </div>
      </div>
    </ActFrame>
  );
}

function ActObjectReveal({ index, total, act }) {
  return (
    <ScrollBeats beats={1} bg="var(--petrol-deep)">
      <ActObjectRevealInner index={index} total={total} act={act} />
    </ScrollBeats>
  );
}

window.ActObjectReveal = ActObjectReveal;
