// Shared hooks + helpers used by every section.

const useReveal = (threshold = 0.15) => {
  const ref = React.useRef(null);
  const [shown, setShown] = React.useState(false);
  React.useEffect(() => {
    if (!ref.current) return;
    const io = new IntersectionObserver(
      ([e]) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } },
      { threshold }
    );
    io.observe(ref.current);
    return () => io.disconnect();
  }, [threshold]);
  return [ref, shown];
};

// Animated number counter (eases to target once visible)
const Counter = ({ to, suffix = '', prefix = '', decimals = 0, duration = 1400, trigger = true }) => {
  const [val, setVal] = React.useState(0);
  React.useEffect(() => {
    if (!trigger) return;
    let raf, start;
    const tick = (t) => {
      if (!start) start = t;
      const p = Math.min(1, (t - start) / duration);
      const eased = 1 - Math.pow(1 - p, 3);
      setVal(to * eased);
      if (p < 1) raf = requestAnimationFrame(tick);
    };
    raf = requestAnimationFrame(tick);
    return () => cancelAnimationFrame(raf);
  }, [to, duration, trigger]);
  return <>{prefix}{val.toFixed(decimals)}{suffix}</>;
};

// useTick — runs a counter at given interval, returns int
const useTick = (interval = 100) => {
  const [t, setT] = React.useState(0);
  React.useEffect(() => {
    const id = setInterval(() => setT(x => x + 1), interval);
    return () => clearInterval(id);
  }, [interval]);
  return t;
};

// Useful: clock that ticks every second
const useClock = () => {
  const [t, setT] = React.useState(() => new Date());
  React.useEffect(() => {
    const id = setInterval(() => setT(new Date()), 1000);
    return () => clearInterval(id);
  }, []);
  return t;
};

// Mouse parallax — returns x/y normalized to -1..1 of the ref
const useMouseParallax = () => {
  const ref = React.useRef(null);
  const [m, setM] = React.useState({ x: 0, y: 0 });
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const x = ((e.clientX - r.left) / r.width) * 2 - 1;
      const y = ((e.clientY - r.top) / r.height) * 2 - 1;
      setM({ x, y });
    };
    const onLeave = () => setM({ x: 0, y: 0 });
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    return () => {
      el.removeEventListener('mousemove', onMove);
      el.removeEventListener('mouseleave', onLeave);
    };
  }, []);
  return [ref, m];
};

// Scroll-y normalized to viewport (for nav progress / parallax)
const useScrollProgress = () => {
  const [p, setP] = React.useState(0);
  React.useEffect(() => {
    const onScroll = () => {
      const max = document.body.scrollHeight - window.innerHeight;
      setP(max > 0 ? window.scrollY / max : 0);
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return p;
};

// useResponsive — detect mobile viewport
const useResponsive = () => {
  const [isMobile, setIsMobile] = React.useState(typeof window !== 'undefined' && window.innerWidth < 768);
  
  React.useEffect(() => {
    const handleResize = () => setIsMobile(window.innerWidth < 768);
    window.addEventListener('resize', handleResize);
    return () => window.removeEventListener('resize', handleResize);
  }, []);
  
  return isMobile;
};

// Reveal wrapper — fades + translates up when in view
const Reveal = ({ children, delay = 0, y = 16, as: Tag = 'div', style }) => {
  const [ref, shown] = useReveal(0.12);
  return (
    <Tag ref={ref} style={{
      ...style,
      opacity: shown ? 1 : 0,
      transform: shown ? 'translateY(0)' : `translateY(${y}px)`,
      transition: `opacity 600ms cubic-bezier(0.2,0,0,1) ${delay}ms, transform 600ms cubic-bezier(0.2,0,0,1) ${delay}ms`,
      willChange: 'opacity, transform',
    }}>{children}</Tag>
  );
};

Object.assign(window, { useReveal, Counter, useTick, useClock, useMouseParallax, useScrollProgress, Reveal, useResponsive });
