// The Witness — thoughts and feelings as weather passing through.
// The sky never moves. Hover/touch to disperse the weather.
const { useState: useState5, useEffect: useEffect5, useRef: useRef5 } = React;

const witnessStyles = {
  wrap: {
    position: 'relative',
    aspectRatio: '16 / 9',
    background: 'linear-gradient(180deg, rgba(38,39,39,0.0) 0%, rgba(207,191,149,0.05) 100%), rgba(236,223,186,0.4)',
    borderRadius: 12,
    border: '1px solid var(--border-paper)',
    overflow: 'hidden',
    cursor: 'crosshair',
  },
  hud: {
    position: 'absolute',
    fontFamily: 'var(--font-ui)', fontSize: 9, letterSpacing: '0.32em',
    textTransform: 'uppercase', color: 'var(--ember)',
  },
  legend: {
    display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 24,
    marginTop: 18, padding: '20px 24px',
    background: 'rgba(38,39,39,0.04)',
    borderRadius: 12,
    fontFamily: 'var(--font-prose)', fontSize: 13, lineHeight: 1.6,
    color: 'var(--ink-soft)',
  },
};

// The "weather" — short phrases that float across, fade in and out
const WEATHER_PHRASES = [
  'a recent regret',
  'something they said',
  'who you are',
  'who you were',
  'the wound',
  'the story',
  'i should have',
  'i shouldn\'t have',
  'i am the one who',
  'i am not the one who',
  'the past',
  'the future',
  'a worry',
  'a craving',
  'a contraction',
  'a comparison',
  'an identity',
  'an opinion',
  'a memory of a memory',
];

function Witness() {
  const wrapRef = useRef5(null);
  const [clouds, setClouds] = useState5([]);
  const mouseRef = useRef5({ x: -1000, y: -1000, active: false });
  const cloudIdRef = useRef5(0);
  const dimRef = useRef5({ w: 800, h: 450 });

  // resize listener
  useEffect5(() => {
    const update = () => {
      if (!wrapRef.current) return;
      const r = wrapRef.current.getBoundingClientRect();
      dimRef.current = { w: r.width, h: r.height };
    };
    update();
    window.addEventListener('resize', update);
    return () => window.removeEventListener('resize', update);
  }, []);

  // spawn loop
  useEffect5(() => {
    const spawn = (initial = false) => {
      const { w, h } = dimRef.current;
      if (!w) return; // skip if not measured yet
      const fromLeft = Math.random() > 0.5;
      const id = cloudIdRef.current++;
      const text = WEATHER_PHRASES[Math.floor(Math.random() * WEATHER_PHRASES.length)];
      const y = 60 + Math.random() * (h - 160);
      const speed = 0.15 + Math.random() * 0.2;
      const size = 0.7 + Math.random() * 0.7;
      // Initial clouds are positioned across the frame; subsequent ones drift in from edges
      const startX = initial
        ? 40 + Math.random() * (w - 80)
        : (fromLeft ? -200 : w + 200);
      setClouds(cs => [...cs, {
        id, text, y, size,
        x: startX,
        vx: fromLeft ? speed : -speed,
        opacity: initial ? 0.7 : 0,
        targetOp: 0.55 + Math.random() * 0.3,
        alive: true,
        dispersed: false,
      }]);
    };
    // populate immediately so the frame isn't empty
    const seed = () => {
      if (!dimRef.current.w) { requestAnimationFrame(seed); return; }
      for (let i = 0; i < 5; i++) spawn(true);
    };
    seed();
    const interval = setInterval(() => spawn(false), 2000);
    return () => clearInterval(interval);
  }, []);

  // animation loop
  useEffect5(() => {
    let raf;
    const tick = () => {
      const { w, h } = dimRef.current;
      const mx = mouseRef.current.x;
      const my = mouseRef.current.y;
      const active = mouseRef.current.active;

      setClouds(cs => cs.map(c => {
        if (!c.alive) return c;
        let { x, y, vx, opacity, targetOp, dispersed } = c;
        // proximity to mouse
        if (active) {
          const dx = x - mx; const dy = y - my;
          const dist = Math.sqrt(dx*dx + dy*dy);
          if (dist < 110) {
            targetOp = 0;
            dispersed = true;
            // a gentle push away
            const push = (110 - dist) / 110;
            vx += (dx / (dist + 1)) * 0.3 * push;
            y += (dy / (dist + 1)) * 1.0 * push;
          }
        }
        x += vx;
        opacity += (targetOp - opacity) * 0.04;
        // remove if off screen or fully dispersed and faded
        let alive = c.alive;
        if (x < -300 || x > w + 300) alive = false;
        if (dispersed && opacity < 0.02) alive = false;
        return { ...c, x, y, vx, opacity, targetOp, dispersed, alive };
      }).filter(c => c.alive));

      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);

  const handleMove = (e) => {
    const r = wrapRef.current.getBoundingClientRect();
    mouseRef.current.x = (e.touches ? e.touches[0].clientX : e.clientX) - r.left;
    mouseRef.current.y = (e.touches ? e.touches[0].clientY : e.clientY) - r.top;
    mouseRef.current.active = true;
  };
  const handleLeave = () => { mouseRef.current.active = false; mouseRef.current.x = -1000; };

  return (
    <div style={{ marginTop: 0 }}>
      <div ref={wrapRef}
        style={witnessStyles.wrap}
        onMouseMove={handleMove}
        onMouseLeave={handleLeave}
        onTouchMove={handleMove}
        onTouchEnd={handleLeave}>

        {/* sun / awareness center */}
        <div style={{
          position: 'absolute', left: '50%', top: '50%',
          transform: 'translate(-50%, -50%)',
          width: 220, height: 220,
          background: 'radial-gradient(circle, rgba(207,191,149,0.55) 0%, rgba(207,191,149,0.18) 30%, rgba(207,191,149,0.05) 60%, transparent 80%)',
          borderRadius: '50%',
          animation: 'luma-breath 8s cubic-bezier(0.4,0,0.2,1) infinite',
          pointerEvents: 'none',
        }}></div>
        <div style={{
          position: 'absolute', left: '50%', top: '50%',
          transform: 'translate(-50%, -50%)',
          width: 80, height: 80,
          background: 'radial-gradient(circle, rgba(207,191,149,0.9) 0%, rgba(207,191,149,0.3) 60%, transparent 80%)',
          borderRadius: '50%',
          pointerEvents: 'none',
          animation: 'luma-breath 8s cubic-bezier(0.4,0,0.2,1) infinite',
        }}></div>

        {/* center label */}
        <div style={{
          position: 'absolute', left: '50%', top: '50%',
          transform: 'translate(-50%, -50%)',
          fontFamily: 'var(--font-display)', fontSize: 24,
          color: 'var(--ember)', fontWeight: 500, fontStyle: 'italic',
          letterSpacing: '-0.01em', pointerEvents: 'none',
          textShadow: '0 0 24px rgba(246,240,226,0.8)',
        }}>
          what notices
        </div>

        {/* clouds (weather) */}
        {clouds.map(c => (
          <div key={c.id} style={{
            position: 'absolute',
            left: c.x, top: c.y,
            transform: `translate(-50%, -50%) scale(${c.size})`,
            opacity: c.opacity,
            fontFamily: 'var(--font-prose)',
            fontStyle: 'italic',
            fontSize: 18,
            color: 'var(--ink-soft)',
            whiteSpace: 'nowrap',
            pointerEvents: 'none',
            textShadow: '0 0 18px rgba(246,240,226,0.6)',
            transition: 'opacity 600ms cubic-bezier(0.4,0,0.2,1)',
          }}>
            {c.text}
          </div>
        ))}

        {/* horizon shading at top/bottom */}
        <div style={{
          position: 'absolute', inset: 0,
          background: 'radial-gradient(ellipse at 50% 50%, transparent 30%, rgba(38,39,39,0.06) 100%)',
          pointerEvents: 'none',
        }}></div>

        {/* corner labels */}
        <div style={{ ...witnessStyles.hud, top: 14, left: 16 }}>
          the witness
        </div>
        <div style={{ ...witnessStyles.hud, bottom: 14, left: 16 }}>
          move across the weather to disperse it
        </div>
        <div style={{ ...witnessStyles.hud, top: 14, right: 16, color: 'var(--ink-soft)' }}>
          the sky never moves
        </div>
      </div>

      <div style={witnessStyles.legend} data-mobile-stack>
        <div>
          <div style={{
            fontFamily: 'var(--font-ui)', fontSize: 10, letterSpacing: '0.32em',
            textTransform: 'uppercase', color: 'var(--muted)', marginBottom: 6,
          }}>The weather</div>
          <div>Thoughts. Feelings. Memories. Stories about who you are. Each one rises, drifts, passes. None of it stays. None of it is you.</div>
        </div>
        <div>
          <div style={{
            fontFamily: 'var(--font-ui)', fontSize: 10, letterSpacing: '0.32em',
            textTransform: 'uppercase', color: 'var(--ember)', marginBottom: 6,
          }}>The sky</div>
          <div>What was present before the word "i" arrived. Unchanged by any of it. Reading these words right now.</div>
        </div>
      </div>
    </div>
  );
}

window.Witness = Witness;
