// FX.jsx — cursor, grain, reveals, scroll progress, tweaks
function FX() {
  const cursorRef = React.useRef(null);
  const grainRef = React.useRef(null);
  const progressRef = React.useRef(null);
  const [tweaks, setTweaks] = React.useState({ cursor: true, intensity: 7, accent: 'mint', tweaksOpen: false });

  // Cursor
  React.useEffect(() => {
    if (!tweaks.cursor) return;
    const c = cursorRef.current; if (!c) return;
    let x = 0, y = 0, tx = 0, ty = 0;
    const move = (e) => { tx = e.clientX; ty = e.clientY; };
    window.addEventListener('mousemove', move);
    let raf;
    const tick = () => {
      x += (tx - x) * 0.25;
      y += (ty - y) * 0.25;
      c.style.left = x + 'px';
      c.style.top = y + 'px';
      raf = requestAnimationFrame(tick);
    };
    tick();

    const onOver = (e) => {
      const t = e.target.closest('[data-cursor], a, button, .cap-card, .process__step');
      if (t) {
        const label = t.getAttribute('data-cursor');
        c.classList.add('cursor--hover');
        if (label === 'book' || label === 'view' || label === 'drag') {
          c.classList.add('cursor--label');
          c.textContent = { book: 'Book', view: 'View', drag: 'Drag' }[label];
        } else {
          c.classList.remove('cursor--label');
          c.textContent = '';
        }
      } else {
        c.classList.remove('cursor--hover', 'cursor--label');
        c.textContent = '';
      }
    };
    document.addEventListener('mouseover', onOver);
    return () => {
      window.removeEventListener('mousemove', move);
      document.removeEventListener('mouseover', onOver);
      cancelAnimationFrame(raf);
    };
  }, [tweaks.cursor]);

  // Grain
  React.useEffect(() => {
    const c = grainRef.current; if (!c) return;
    const resize = () => { c.width = window.innerWidth; c.height = window.innerHeight; draw(); };
    const draw = () => {
      const ctx = c.getContext('2d');
      const img = ctx.createImageData(c.width, c.height);
      for (let i = 0; i < img.data.length; i += 4) {
        const v = Math.random() * 255;
        img.data[i] = img.data[i + 1] = img.data[i + 2] = v;
        img.data[i + 3] = 40;
      }
      ctx.putImageData(img, 0, 0);
    };
    resize();
    window.addEventListener('resize', resize);
    return () => window.removeEventListener('resize', resize);
  }, []);

  // Scroll progress + reveals
  React.useEffect(() => {
    const onScroll = () => {
      const bar = progressRef.current;
      if (bar) {
        const sh = document.documentElement.scrollHeight - window.innerHeight;
        bar.style.width = sh > 0 ? `${(window.scrollY / sh) * 100}%` : '0';
      }
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    onScroll();

    const io = new IntersectionObserver((entries) => {
      entries.forEach(en => { if (en.isIntersecting) en.target.classList.add('in'); });
    }, { threshold: 0.15 });
    document.querySelectorAll('.reveal').forEach(el => io.observe(el));

    return () => { window.removeEventListener('scroll', onScroll); io.disconnect(); };
  }, []);

  // Edit mode integration
  React.useEffect(() => {
    const onMsg = (e) => {
      if (!e.data) return;
      if (e.data.type === '__activate_edit_mode') setTweaks(t => ({ ...t, tweaksOpen: true }));
      if (e.data.type === '__deactivate_edit_mode') setTweaks(t => ({ ...t, tweaksOpen: false }));
    };
    window.addEventListener('message', onMsg);
    try { window.parent.postMessage({ type: '__edit_mode_available' }, '*'); } catch(e) {}
    return () => window.removeEventListener('message', onMsg);
  }, []);

  // Apply tweaks
  React.useEffect(() => {
    const root = document.documentElement;
    const accentMap = {
      mint: '#86C8A1', mintDeep: '#5DA57C',
      amber: '#E8B56A', amberDeep: '#C8984C',
      coral: '#E89C86', coralDeep: '#C87C66',
    };
    if (tweaks.accent === 'amber') {
      root.style.setProperty('--nuun-mint', accentMap.amber);
      root.style.setProperty('--nuun-mint-deep', accentMap.amberDeep);
    } else if (tweaks.accent === 'coral') {
      root.style.setProperty('--nuun-mint', accentMap.coral);
      root.style.setProperty('--nuun-mint-deep', accentMap.coralDeep);
    } else {
      root.style.setProperty('--nuun-mint', accentMap.mint);
      root.style.setProperty('--nuun-mint-deep', accentMap.mintDeep);
    }
    document.body.style.cursor = tweaks.cursor ? 'none' : 'auto';
    const c = cursorRef.current;
    if (c) c.style.display = tweaks.cursor ? 'block' : 'none';
  }, [tweaks]);

  const setKey = (k, v) => setTweaks(t => ({ ...t, [k]: v }));

  return (
    <>
      <canvas ref={grainRef} className="grain" aria-hidden />
      <div ref={cursorRef} className="cursor" aria-hidden />
      <div ref={progressRef} className="scroll-progress" />
      <div className={`tweaks ${tweaks.tweaksOpen ? 'open' : ''}`}>
        <h4>Tweaks</h4>
        <div className="tweaks__row">
          <label>Custom cursor</label>
          <div className={`tweaks__toggle ${tweaks.cursor ? 'on' : ''}`}
               onClick={() => setKey('cursor', !tweaks.cursor)} />
        </div>
        <div className="tweaks__row">
          <label>Accent</label>
          <select value={tweaks.accent} onChange={e => setKey('accent', e.target.value)}>
            <option value="mint">Mint</option>
            <option value="amber">Amber</option>
            <option value="coral">Coral</option>
          </select>
        </div>
      </div>
    </>
  );
}
window.FX = FX;
