// Dynamic effects layer — cursor glow, parallax, counters, magnetic hover

const { useEffect: useEffectDyn, useState: useStateDyn, useRef: useRefDyn } = React;

// ────── Cursor spotlight (desktop only) ──────
function CursorGlow() {
  const ref = useRefDyn(null);
  useEffectDyn(() => {
    if (matchMedia('(hover: none)').matches) return;
    const el = ref.current;
    let raf = 0;
    let tx = window.innerWidth / 2, ty = window.innerHeight / 2;
    let x = tx, y = ty;
    const onMove = (e) => { tx = e.clientX; ty = e.clientY; };
    const tick = () => {
      x += (tx - x) * 0.16;
      y += (ty - y) * 0.16;
      if (el) el.style.transform = `translate3d(${x}px, ${y}px, 0)`;
      raf = requestAnimationFrame(tick);
    };
    window.addEventListener('mousemove', onMove);
    raf = requestAnimationFrame(tick);
    return () => { window.removeEventListener('mousemove', onMove); cancelAnimationFrame(raf); };
  }, []);
  return <div ref={ref} className="cursor-glow" aria-hidden="true"></div>;
}

// ────── Scroll progress bar ──────
function ScrollProgress() {
  const ref = useRefDyn(null);
  useEffectDyn(() => {
    const onScroll = () => {
      const max = document.documentElement.scrollHeight - window.innerHeight;
      const p = max > 0 ? window.scrollY / max : 0;
      if (ref.current) ref.current.style.transform = `scaleX(${p})`;
    };
    onScroll();
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => window.removeEventListener('scroll', onScroll);
  }, []);
  return <div className="scroll-progress" ref={ref}></div>;
}

// ────── Animated counter (intersection-triggered) ──────
function Counter({ to, suffix = '', prefix = '', duration = 1400, accent }) {
  const [val, setVal] = useStateDyn(0);
  const ref = useRefDyn(null);
  useEffectDyn(() => {
    if (typeof to !== 'number') { setVal(to); return; }
    const el = ref.current;
    if (!el) return;
    let raf = 0, started = false, start = 0;
    const easeOut = (t) => 1 - Math.pow(1 - t, 3);
    const animate = (ts) => {
      if (!start) start = ts;
      const t = Math.min((ts - start) / duration, 1);
      setVal(Math.round(easeOut(t) * to));
      if (t < 1) raf = requestAnimationFrame(animate);
    };
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting && !started) {
          started = true;
          raf = requestAnimationFrame(animate);
          io.unobserve(e.target);
        }
      });
    }, { threshold: 0.4 });
    io.observe(el);
    return () => { cancelAnimationFrame(raf); io.disconnect(); };
  }, [to, duration]);
  return (
    <span ref={ref}>
      {prefix}<span className={accent ? 'accent' : ''}>{typeof to === 'number' ? val : to}</span>{suffix}
    </span>
  );
}

// ────── Magnetic / tilt wrapper ──────
function useTilt(strength = 8) {
  const ref = useRefDyn(null);
  useEffectDyn(() => {
    const el = ref.current;
    if (!el || matchMedia('(hover: none)').matches) return;
    const onMove = (e) => {
      const r = el.getBoundingClientRect();
      const px = (e.clientX - r.left) / r.width - 0.5;
      const py = (e.clientY - r.top) / r.height - 0.5;
      el.style.transform = `perspective(900px) rotateX(${-py * strength}deg) rotateY(${px * strength}deg)`;
    };
    const onLeave = () => { el.style.transform = ''; };
    el.addEventListener('mousemove', onMove);
    el.addEventListener('mouseleave', onLeave);
    return () => {
      el.removeEventListener('mousemove', onMove);
      el.removeEventListener('mouseleave', onLeave);
    };
  }, [strength]);
  return ref;
}

// ────── Hero parallax ──────
function useHeroParallax(selector) {
  useEffectDyn(() => {
    if (matchMedia('(hover: none)').matches) return;
    const el = document.querySelector(selector);
    if (!el) return;
    let raf = 0;
    const onScroll = () => {
      cancelAnimationFrame(raf);
      raf = requestAnimationFrame(() => {
        const y = window.scrollY;
        el.style.setProperty('--hero-shift', `${Math.min(y * 0.3, 200)}px`);
        el.style.setProperty('--hero-fade', `${Math.max(1 - y / 500, 0)}`);
      });
    };
    window.addEventListener('scroll', onScroll, { passive: true });
    return () => { window.removeEventListener('scroll', onScroll); cancelAnimationFrame(raf); };
  }, [selector]);
}

// ────── Type-on text ──────
function TypeOn({ text, delay = 0, speed = 28, className }) {
  const [shown, setShown] = useStateDyn('');
  const [done, setDone] = useStateDyn(false);
  useEffectDyn(() => {
    let i = 0;
    let t = setTimeout(function tick() {
      if (i <= text.length) {
        setShown(text.slice(0, i));
        i++;
        t = setTimeout(tick, speed);
      } else {
        setDone(true);
      }
    }, delay);
    return () => clearTimeout(t);
  }, [text, delay, speed]);
  return <span className={className}>{shown}{!done && <span className="type-cursor">▌</span>}</span>;
}

Object.assign(window, { CursorGlow, ScrollProgress, Counter, useTilt, useHeroParallax, TypeOn });
