// Spatial UI — smooth cursor-driven tilt with rAF smoothing (no jank)
const { useState, useEffect, useRef } = React;

function SpatialDemo() {
  const wrapRef = useRef(null);
  const auraRef = useRef(null);
  const envRef = useRef(null);
  const stackRef = useRef(null);
  // mouse target + smoothed state
  const target = useRef({ x: 0.5, y: 0.5 });
  const smooth = useRef({ x: 0.5, y: 0.5 });
  const [hudPos, setHudPos] = useState({ x: 50, y: 50 });

  const [dwelling, setDwelling] = useState(0);
  const [pinched, setPinched] = useState(false);
  const [archived, setArchived] = useState(new Set());
  const [envMesh, setEnvMesh] = useState(false);

  const cards = [
    { id: 'msg', kind: 'Messages', from: 'Sarah J.', body: 'Still on for the park meeting? Bringing the prototype.', time: '2m', tint: 'periwinkle' },
    { id: 'cal', kind: 'Calendar', from: 'Studio Review', body: 'In 14 minutes · Glass Room · 5 joining via spatial link.', time: '14m', tint: 'warm' },
    { id: 'sys', kind: 'System', from: 'Engine', body: 'LiDAR calibration complete. Environment mesh refreshed.', time: 'now', tint: 'mono' },
  ];

  useEffect(() => {
    const el = wrapRef.current;
    if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      target.current.x = Math.max(0, Math.min(1, (e.clientX - r.left) / r.width));
      target.current.y = Math.max(0, Math.min(1, (e.clientY - r.top) / r.height));
    };
    const onLeave = () => { target.current.x = 0.5; target.current.y = 0.5; };
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);

    let raf;
    let lastHudUpdate = 0;
    const tick = (t) => {
      // exponential smoothing
      smooth.current.x += (target.current.x - smooth.current.x) * 0.12;
      smooth.current.y += (target.current.y - smooth.current.y) * 0.12;
      const x = smooth.current.x, y = smooth.current.y;

      // aura follow
      if (auraRef.current) {
        auraRef.current.style.transform = `translate(${x * 100}%, ${y * 100}%) translate(-50%, -50%)`;
      }
      // environment parallax (inverse)
      if (envRef.current) {
        envRef.current.style.transform = `translate3d(${(x - 0.5) * -24}px, ${(y - 0.5) * -16}px, 0)`;
      }
      // stack tilt — applied here, no per-card inline transform per frame from React
      if (stackRef.current) {
        const rx = (0.5 - y) * 10;
        const ry = (x - 0.5) * 14;
        stackRef.current.style.transform = `translate(-50%,-50%) rotateX(${rx}deg) rotateY(${ry}deg)`;
      }
      // HUD text — throttle to 8fps
      if (t - lastHudUpdate > 120) {
        setHudPos({ x: Math.round(x * 100), y: Math.round(y * 100) });
        lastHudUpdate = t;
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => {
      el.removeEventListener('mousemove', onMove);
      el.removeEventListener('mouseleave', onLeave);
      cancelAnimationFrame(raf);
    };
  }, []);

  const visibleCards = cards.filter(c => !archived.has(c.id));
  const focusedCard = cards[dwelling] && !archived.has(cards[dwelling].id)
    ? cards[dwelling]
    : visibleCards[0];

  return (
    <div className="spatial-stage" ref={wrapRef}>
      <div className="env-room" ref={envRef}>
        <div className="env-grid" />
        <div className="env-horizon" />
        <div className="env-floor" />
      </div>
      {envMesh && <div className="env-mesh" />}
      <div className="aura" ref={auraRef} />

      <div className="stack" style={{ perspective: '1800px' }} ref={stackRef}>
        {cards.map((c, i) => {
          if (archived.has(c.id)) return null;
          const focused = i === dwelling && !archived.has(c.id);
          const focusedIdx = cards.findIndex((cc, ii) => ii === dwelling && !archived.has(cc.id));
          const rel = i - (focusedIdx === -1 ? 0 : focusedIdx);
          const tabX = rel === 0 ? 0 : (rel < 0 ? -420 : 420) + rel * 40;
          const tabY = Math.abs(rel) * 6;
          const tabZ = focused ? 0 : -160 - Math.abs(rel) * 40;
          const scale = focused ? 1 : 0.78;

          return (
            <div
              key={c.id}
              className={`glass-card tint-${c.tint} ${focused ? 'focused' : 'is-tab'} ${pinched && focused ? 'pinched' : ''}`}
              style={{
                transform: `translate3d(${tabX}px, ${tabY}px, ${tabZ}px) scale(${scale})`,
                zIndex: focused ? 10 : 5 - Math.abs(rel),
                opacity: focused ? 1 : 0.95,
                transition: 'transform .6s cubic-bezier(.2,.6,.2,1), opacity .4s',
              }}
              onMouseEnter={() => setDwelling(i)}
            >
              <div className="gc-head">
                <span>{c.kind}</span>
                <span>{c.time}</span>
              </div>
              {focused ? (
                <>
                  <div className="gc-body">
                    <div className="gc-from">{c.from}</div>
                    <p>{c.body}</p>
                  </div>
                  <div className="gc-actions">
                    <button
                      className="gc-btn"
                      onClick={(e) => { e.stopPropagation(); setArchived(prev => { const n = new Set(prev); n.add(c.id); return n; }); }}
                    >Archive</button>
                    <button className="gc-btn ghost" onClick={e => e.stopPropagation()}>Reply</button>
                  </div>
                  <div className="focus-ring" />
                </>
              ) : (
                <div className="gc-tab-body">
                  <div className="gc-from small">{c.from}</div>
                </div>
              )}
            </div>
          );
        })}
      </div>

      <div className="gesture-hud">
        <div className="ghud-row"><span className="ghud-k">Gaze</span><span className="ghud-v">x{String(hudPos.x).padStart(2,'0')} · y{String(hudPos.y).padStart(2,'0')}</span></div>
        <div className="ghud-row"><span className="ghud-k">Focus</span><span className="ghud-v">{focusedCard?.kind || '—'}</span></div>
        <div className="ghud-row"><span className="ghud-k">Link</span><span className="ghud-v"><span className="dot-live" />7.2 ms</span></div>
      </div>

      <div className="controls">
        <button
          className={`ctrl ${pinched ? 'on' : ''}`}
          onMouseDown={() => setPinched(true)}
          onMouseUp={() => setPinched(false)}
          onMouseLeave={() => setPinched(false)}
        >Hold · Pinch</button>
        <button className={`ctrl ${envMesh ? 'on' : ''}`} onClick={() => setEnvMesh(m => !m)}>LiDAR Mesh</button>
        <button className="ctrl" onClick={() => setArchived(new Set())}>Reset</button>
      </div>

      <div className="hint">
        Move cursor — UI anchors to space.<br/>
        Hover a side tab to shift focus.
      </div>
    </div>
  );
}

Object.assign(window, { SpatialDemo });
