// scenes-constellation.jsx — THE wow moment.
// A sticky section: 4 stars drift onto a celestial map, then connecting lines
// are drawn between them, then each star reveals its product name. Each star is
// gently hoverable; on hover the constellation gains a glow.
//
// Scroll mapping (within the section, 0..1 local):
//   0.00..0.20  : sky settles, frame is drawn
//   0.20..0.45  : 4 stars appear one by one
//   0.45..0.70  : connecting lines draw between them
//   0.70..1.00  : each star expands into a product label (parallel)

const { useRef: useRefC, useEffect: useEffectC, useState: useStateC } = React;

// Star positions in a 1000x1000 canvas (designed for visual harmony)
const STARS = [
  { id: 'core', label: 'Ari · Core',  suf: 'iOS · Day',     x: 280, y: 380, r: 6, tone: 'gold',     tag: '◐ Morning pocket' },
  { id: 'roam', label: 'Ari · Roam',  suf: 'iOS · Night',   x: 720, y: 300, r: 7, tone: 'lavender', tag: '◑ Midnight tab' },
  { id: 'code', label: 'Ari · Code',  suf: 'macOS · Forge', x: 820, y: 640, r: 6, tone: 'gold',     tag: '◆ Desk tool' },
  { id: 'desk', label: 'Ari · Desk',  suf: 'macOS · Agent', x: 320, y: 720, r: 7, tone: 'lavender', tag: '◆ Desk assistant' },
];

// Lines as pairs of star indices — designed to make a coherent figure.
const LINES = [
  [0, 1],
  [1, 2],
  [2, 3],
  [3, 0],
  [0, 2], // diagonal — gives it character
];

function lerp(a, b, t) { return a + (b - a) * t; }
function clamp01(x) { return Math.max(0, Math.min(1, x)); }
function smoothstep(a, b, x) { const t = clamp01((x - a) / (b - a)); return t * t * (3 - 2 * t); }

function Constellation() {
  const wrapRef = useRefC(null);
  const stickyRef = useRefC(null);
  const [local, setLocal] = useStateC(0);
  const [hovered, setHovered] = useStateC(null);

  useEffectC(() => {
    function onScroll() {
      const el = wrapRef.current;
      if (!el) return;
      const r = el.getBoundingClientRect();
      const h = el.offsetHeight;
      const vh = window.innerHeight;
      // local = how far into the section, 0..1
      // The sticky child fills 100vh of viewport; total scroll over the section is h - vh.
      const total = h - vh;
      const scrolled = -r.top;
      const p = clamp01(scrolled / Math.max(1, total));
      setLocal(p);
    }
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    window.addEventListener('resize', onScroll);
    return () => { window.removeEventListener('scroll', onScroll); window.removeEventListener('resize', onScroll); };
  }, []);

  // Per-star reveal
  const starAlpha = (i) => {
    const s = 0.18 + i * 0.06;
    const e = s + 0.10;
    return smoothstep(s, e, local);
  };
  // Per-line draw
  const lineProgress = (i) => {
    const s = 0.45 + i * 0.05;
    const e = s + 0.08;
    return smoothstep(s, e, local);
  };
  // Per-label reveal
  const labelAlpha = (i) => smoothstep(0.72 + i * 0.04, 0.78 + i * 0.04, local);

  // The intro heading
  const headlineP = smoothstep(0.02, 0.18, local);
  const headlineExit = smoothstep(0.55, 0.85, local);

  // Closing sub-line opacity
  const finaleP = smoothstep(0.85, 1.0, local);

  return (
    <section id="family" ref={wrapRef} style={{ position: 'relative', height: '380vh' }}>
      <div ref={stickyRef} style={{
        position: 'sticky', top: 0, height: '100vh', overflow: 'hidden',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
      }}>
        {/* Eyebrow + headline drift in & out at top of viewport */}
        <div style={{
          position: 'absolute', top: '8vh', left: 0, right: 0,
          display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 18,
          pointerEvents: 'none',
          opacity: headlineP * (1 - headlineExit * 0.85),
          transform: `translateY(${(1 - headlineP) * 20 - headlineExit * 30}px)`,
          transition: 'opacity .4s',
        }}>
          <div style={{
            fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '0.5em', textTransform: 'uppercase',
            color: 'currentColor', opacity: 0.65,
            display: 'flex', alignItems: 'center', gap: 14,
          }}>
            <span>◆</span><span>The Ari family</span><span>·</span><span>A four-star constellation</span><span>◆</span>
          </div>
          <h2 style={{
            fontFamily: 'var(--serif)',
            fontSize: 'clamp(54px, 7.4vw, 120px)',
            lineHeight: 0.95,
            fontWeight: 300,
            letterSpacing: '-0.035em',
            textAlign: 'center',
            margin: 0,
          }}>
            Four small <em style={{ color: 'var(--gold-light)' }}>doorways</em>.<br/>
            One <em>quiet</em> philosophy.
          </h2>
        </div>

        {/* The constellation field */}
        <div style={{
          position: 'relative',
          width: 'min(92vw, 1100px)',
          aspectRatio: '1 / 1',
          maxHeight: '78vh',
        }}>
          <svg viewBox="0 0 1000 1000" preserveAspectRatio="xMidYMid meet" style={{
            position: 'absolute', inset: 0, width: '100%', height: '100%', overflow: 'visible',
          }}>
            <defs>
              <radialGradient id="star-gold" cx="0.5" cy="0.5">
                <stop offset="0" stopColor="#fff6e4" stopOpacity="1"/>
                <stop offset="0.3" stopColor="#e0b15a" stopOpacity="1"/>
                <stop offset="1" stopColor="#a87a2a" stopOpacity="0"/>
              </radialGradient>
              <radialGradient id="star-lav" cx="0.5" cy="0.5">
                <stop offset="0" stopColor="#f5eeff" stopOpacity="1"/>
                <stop offset="0.3" stopColor="#c8b8ff" stopOpacity="1"/>
                <stop offset="1" stopColor="#6b54c4" stopOpacity="0"/>
              </radialGradient>
              <linearGradient id="line-grad" x1="0" y1="0" x2="1" y2="1">
                <stop offset="0" stopColor="#d4a85a"/>
                <stop offset="0.5" stopColor="#ece2ff"/>
                <stop offset="1" stopColor="#c8b8ff"/>
              </linearGradient>
              <filter id="glow"><feGaussianBlur stdDeviation="4"/></filter>
            </defs>

            {/* Faint celestial grid — concentric ellipses */}
            <g opacity={0.18 + headlineP * 0.15} stroke="currentColor" fill="none" strokeWidth="0.4">
              <ellipse cx="500" cy="500" rx="380" ry="380"/>
              <ellipse cx="500" cy="500" rx="280" ry="280" opacity="0.7"/>
              <ellipse cx="500" cy="500" rx="180" ry="180" opacity="0.5"/>
              <line x1="500" y1="120" x2="500" y2="880" opacity="0.4"/>
              <line x1="120" y1="500" x2="880" y2="500" opacity="0.4"/>
            </g>

            {/* Constellation lines */}
            {LINES.map(([a, b], i) => {
              const sA = STARS[a], sB = STARS[b];
              const t = lineProgress(i);
              const x = lerp(sA.x, sB.x, t);
              const y = lerp(sA.y, sB.y, t);
              return (
                <g key={i}>
                  <line x1={sA.x} y1={sA.y} x2={x} y2={y}
                    stroke="url(#line-grad)" strokeWidth="0.9"
                    opacity={Math.min(starAlpha(a), starAlpha(b)) * 0.85}/>
                </g>
              );
            })}

            {/* Stars */}
            {STARS.map((s, i) => {
              const a = starAlpha(i);
              const grad = s.tone === 'gold' ? 'url(#star-gold)' : 'url(#star-lav)';
              const isHover = hovered === s.id;
              const haloR = s.r * (5.5 + (isHover ? 4 : 0));
              return (
                <g key={s.id} style={{ cursor: 'none', transition: 'transform .4s', transformOrigin: `${s.x}px ${s.y}px` }}
                   transform={isHover ? `translate(${s.x},${s.y}) scale(1.18) translate(${-s.x},${-s.y})` : ''}>
                  <circle cx={s.x} cy={s.y} r={haloR} fill={grad} opacity={a * 0.85} filter="url(#glow)"/>
                  <circle cx={s.x} cy={s.y} r={s.r * 1.5} fill="#fff6e4" opacity={a}/>
                  {/* diffraction spikes */}
                  <g stroke="#fff6e4" strokeWidth="0.6" opacity={a * 0.7}>
                    <line x1={s.x - s.r * 7} y1={s.y} x2={s.x + s.r * 7} y2={s.y}/>
                    <line x1={s.x} y1={s.y - s.r * 7} x2={s.x} y2={s.y + s.r * 7}/>
                    <line x1={s.x - s.r * 4} y1={s.y - s.r * 4} x2={s.x + s.r * 4} y2={s.y + s.r * 4} opacity="0.5"/>
                    <line x1={s.x - s.r * 4} y1={s.y + s.r * 4} x2={s.x + s.r * 4} y2={s.y - s.r * 4} opacity="0.5"/>
                  </g>
                </g>
              );
            })}
          </svg>

          {/* Label overlays — placed in HTML for type quality */}
          {STARS.map((s, i) => {
            const la = labelAlpha(i);
            // Anchor: each label sits next to its star (offset depends on position)
            const right = s.x > 500;
            const below = s.y > 500;
            const xPct = (s.x / 1000) * 100;
            const yPct = (s.y / 1000) * 100;
            return (
              <a key={s.id}
                 className="cn-label"
                 href={`#${s.id}`}
                 data-cursor="hover"
                 onMouseEnter={() => setHovered(s.id)}
                 onMouseLeave={() => setHovered(null)}
                 style={{
                   position: 'absolute',
                   left: `${xPct}%`, top: `${yPct}%`,
                   transform: `translate(${right ? '24px' : 'calc(-100% - 24px)'}, ${below ? '8px' : '-100%'}) translateY(${below ? '24px' : '-24px'})`,
                   minWidth: 220,
                   opacity: la,
                   transition: 'opacity .6s',
                   color: 'currentColor',
                 }}>
                <div className="cn-suf" style={{
                  fontFamily: 'var(--mono)', fontSize: 10, letterSpacing: '0.35em',
                  textTransform: 'uppercase', opacity: 0.7,
                  borderTop: '1px solid currentColor', paddingTop: 10, marginBottom: 8,
                  width: 140,
                }}>{s.suf}</div>
                <div className="cn-title" style={{
                  fontFamily: 'var(--serif)', fontSize: 36, fontStyle: 'italic',
                  letterSpacing: '-0.02em', lineHeight: 1, marginBottom: 6,
                }}>{s.label}</div>
                <div className="cn-tag" style={{
                  fontFamily: 'var(--mono)', fontSize: 11, letterSpacing: '0.18em',
                  opacity: 0.6,
                }}>{s.tag}</div>
              </a>
            );
          })}
        </div>

        {/* Closing sub-line */}
        <div style={{
          position: 'absolute', bottom: '6vh', left: 0, right: 0,
          textAlign: 'center', opacity: finaleP * 0.85,
          fontFamily: 'var(--serif)', fontStyle: 'italic',
          fontSize: 'clamp(18px, 1.5vw, 24px)',
        }}>
          Pick the doorway that fits the hour.
        </div>
      </div>
    </section>
  );
}

window.Constellation = Constellation;
