// useScrollReveal.jsx — scroll animation hooks, RevealBlock, GlobalAnimStyles

function useScrollReveal(options = {}) {
  const ref = React.useRef(null);
  const [visible, setVisible] = React.useState(false);
  React.useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setVisible(true); return; }
    const obs = new IntersectionObserver(
      ([entry]) => { if (entry.isIntersecting) { setVisible(true); obs.disconnect(); } },
      { threshold: 0.1, rootMargin: "0px 0px -40px 0px", ...options }
    );
    obs.observe(el);
    return () => obs.disconnect();
  }, []);
  return [ref, visible];
}

function useCountUp(target, duration = 1400, active = false) {
  const [count, setCount] = React.useState(0);
  React.useEffect(() => {
    if (!active) return;
    if (window.matchMedia("(prefers-reduced-motion: reduce)").matches) { setCount(target); return; }
    let start = null;
    const raf = (ts) => {
      if (!start) start = ts;
      const p = Math.min((ts - start) / duration, 1);
      const eased = 1 - Math.pow(1 - p, 3);
      setCount(Math.floor(eased * target));
      if (p < 1) requestAnimationFrame(raf);
      else setCount(target);
    };
    requestAnimationFrame(raf);
  }, [target, active]);
  return count;
}

function RevealBlock({ children, delay = 0, style = {} }) {
  const [ref, visible] = useScrollReveal();
  const rm = window.matchMedia("(prefers-reduced-motion: reduce)").matches;
  return (
    <div ref={ref} style={{
      opacity: (visible || rm) ? 1 : 0,
      transform: (visible || rm) ? "translateY(0)" : "translateY(20px)",
      transition: `opacity 0.55s ease ${delay}ms, transform 0.55s ease ${delay}ms`,
      ...style,
    }}>
      {children}
    </div>
  );
}

function GlobalAnimStyles() {
  return (
    <style>{`
      html { scroll-behavior: smooth; }
      ::selection { background: #D4E6EF; color: #1A2330; }

      @keyframes scrollBob {
        0%, 100% { transform: translateY(0); }
        50%       { transform: translateY(7px); }
      }
      @keyframes slideUpIn {
        from { transform: translateY(100%); }
        to   { transform: translateY(0); }
      }
      @keyframes fadeInScale {
        from { opacity: 0; transform: scale(0.96); }
        to   { opacity: 1; transform: scale(1); }
      }
      @keyframes marqueeScroll {
        from { transform: translateX(0); }
        to   { transform: translateX(-50%); }
      }
      @keyframes shimmerSlide {
        0%   { transform: translateX(-120%) skewX(-18deg); opacity: 0.18; }
        80%  { opacity: 0.18; }
        100% { transform: translateX(280%)  skewX(-18deg); opacity: 0; }
      }
      @keyframes spin {
        from { transform: rotate(0deg); }
        to   { transform: rotate(360deg); }
      }
      @keyframes countPulse {
        0%  { opacity: 0.7; }
        50% { opacity: 1; }
        100%{ opacity: 0.7; }
      }

      .lin-partner-chip {
        transition: background 150ms ease, color 150ms ease;
        cursor: default;
      }
      .lin-partner-chip:hover {
        background: #E8F1F5 !important;
        color: #4A7A91 !important;
      }
      .lin-gift-row {
        cursor: pointer;
        transition: background 150ms ease;
      }
      .lin-gift-row:hover { background: #E8F1F5 !important; }
      .lin-gift-row-cta {
        opacity: 0;
        transition: opacity 150ms ease;
        font-size: 12px;
        font-weight: 600;
        color: #6399AF;
        letter-spacing: 0.04em;
        white-space: nowrap;
      }
      .lin-gift-row:hover .lin-gift-row-cta { opacity: 1; }

      .lin-btn-primary:hover { background: #4A7A91 !important; }
      .lin-btn-secondary:hover { background: #E8F1F5 !important; }

      @media (prefers-reduced-motion: reduce) {
        *, *::before, *::after {
          animation-duration: 0.01ms !important;
          transition-duration: 0.01ms !important;
        }
      }
    `}</style>
  );
}

Object.assign(window, { useScrollReveal, useCountUp, RevealBlock, GlobalAnimStyles });
