// lib.jsx — shared hooks
const { useEffect, useRef, useState, useCallback, useMemo, useLayoutEffect } = React;

function useCustomCursor() {
  useEffect(() => {
    const dot = document.getElementById('cursorDot');
    const ring = document.getElementById('cursorRing');
    if (!dot || !ring) return;
    let mx = window.innerWidth / 2, my = window.innerHeight / 2;
    let rx = mx, ry = my;
    let raf;
    const onMove = (e) => {
      mx = e.clientX; my = e.clientY;
      dot.style.transform = `translate3d(${mx - 4}px, ${my - 4}px, 0)`;
    };
    const tick = () => {
      rx += (mx - rx) * 0.2;
      ry += (my - ry) * 0.2;
      ring.style.transform = `translate3d(${rx - 18}px, ${ry - 18}px, 0)`;
      raf = requestAnimationFrame(tick);
    };
    const onOver = (e) => {
      const t = e.target;
      if (!t || !t.closest) return;
      if (t.closest('a, button, [data-hover], .clickable')) {
        ring.classList.add('hover');
      }
    };
    const onOut = (e) => {
      const t = e.target;
      if (!t || !t.closest) return;
      if (t.closest('a, button, [data-hover], .clickable')) {
        ring.classList.remove('hover');
      }
    };
    document.addEventListener('mousemove', onMove);
    document.addEventListener('mouseover', onOver);
    document.addEventListener('mouseout', onOut);
    raf = requestAnimationFrame(tick);
    return () => {
      document.removeEventListener('mousemove', onMove);
      document.removeEventListener('mouseover', onOver);
      document.removeEventListener('mouseout', onOut);
      cancelAnimationFrame(raf);
    };
  }, []);
}

function useReveal() {
  useEffect(() => {
    const els = document.querySelectorAll('.reveal, .reveal-word');
    const obs = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) e.target.classList.add('in');
      });
    }, { threshold: 0.12, rootMargin: '0px 0px -6% 0px' });
    els.forEach((el) => obs.observe(el));
    return () => obs.disconnect();
  });
}

function SplitText({ children, as = 'span', delay = 0, className = '', style = {} }) {
  const Tag = as;
  const words = String(children).split(/(\s+)/);
  return (
    <Tag className={className} style={style}>
      {words.map((w, i) =>
        /\s+/.test(w) ? (
          <span key={i}>{w}</span>
        ) : (
          <span key={i} className="reveal-word" style={{ '--i': delay + i * 0.5 }}>
            <span>{w}</span>
          </span>
        )
      )}
    </Tag>
  );
}

function useScrollY() {
  const [y, setY] = useState(0);
  useEffect(() => {
    let raf;
    const tick = () => { setY(window.scrollY); raf = requestAnimationFrame(tick); };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, []);
  return y;
}

function useMouse() {
  const [m, setM] = useState({ x: 0.5, y: 0.5 });
  useEffect(() => {
    const onMove = (e) => setM({
      x: e.clientX / window.innerWidth,
      y: e.clientY / window.innerHeight,
    });
    window.addEventListener('mousemove', onMove);
    return () => window.removeEventListener('mousemove', onMove);
  }, []);
  return m;
}

function Magnetic({ children, strength = 0.35, className = '', style = {} }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const x = e.clientX - (r.left + r.width / 2);
      const y = e.clientY - (r.top + r.height / 2);
      el.style.transform = `translate3d(${x * strength}px, ${y * strength}px, 0)`;
    };
    const onLeave = () => { el.style.transform = ''; };
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    return () => {
      el.removeEventListener('mousemove', onMove);
      el.removeEventListener('mouseleave', onLeave);
    };
  }, [strength]);
  return (
    <span ref={ref} className={`lift ${className}`} style={style}>{children}</span>
  );
}

function useTiltScroll(ref) {
  const [p, setP] = useState(0);
  useEffect(() => {
    let raf;
    const tick = () => {
      if (ref.current) {
        const r = ref.current.getBoundingClientRect();
        const vh = window.innerHeight;
        const total = r.height + vh;
        const passed = vh - r.top;
        setP(Math.max(0, Math.min(1, passed / total)));
      }
      raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [ref]);
  return p;
}

/* ──────────────────────────────────────────────────────────
   Icon — wrapper para Lucide (carga vía CDN en index.html).
   Renderiza <i data-lucide="name"></i> y dispara lucide.createIcons()
   tras el mount para reemplazar por SVG inline.
   Reemplaza emojis en toda la plataforma.
   ────────────────────────────────────────────────────────── */
function Icon({ name, size = 18, color, strokeWidth = 2, style = {}, ariaLabel }) {
  const ref = useRef(null);
  useEffect(() => {
    if (typeof window === 'undefined' || !window.lucide) return;
    try { window.lucide.createIcons({ icons: window.lucide.icons, attrs: {} }); } catch (e) {}
  }, [name, size, color]);
  return (
    <i ref={ref}
      data-lucide={name}
      role={ariaLabel ? 'img' : 'presentation'}
      aria-label={ariaLabel}
      aria-hidden={ariaLabel ? undefined : 'true'}
      style={{
        display: 'inline-flex', alignItems: 'center', justifyContent: 'center',
        width: size, height: size, color: color || 'currentColor',
        strokeWidth, lineHeight: 0, verticalAlign: 'middle',
        ...style
      }}/>
  );
}

// Refresca todos los íconos Lucide del DOM (incluye data-icon dispersos)
function refreshLucide() {
  if (typeof window === 'undefined' || !window.lucide) return;
  document.querySelectorAll('[data-icon]:not([data-lucide])').forEach(el => {
    el.setAttribute('data-lucide', el.dataset.icon);
    if (el.dataset.size) el.style.width = el.style.height = el.dataset.size + 'px';
    if (el.dataset.color) el.style.color = el.dataset.color;
  });
  try { window.lucide.createIcons(); } catch (e) {}
}

Object.assign(window, {
  useCustomCursor, useReveal, SplitText, useScrollY, useMouse, Magnetic, useTiltScroll,
  Icon, refreshLucide
});
