// Shared hooks for shiwake LP
const { useEffect, useRef, useState } = React;

// IntersectionObserver-based reveal trigger
function useReveal(threshold = 0.15) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting) {
            setShown(true);
            io.unobserve(e.target);
          }
        });
      },
      { threshold, rootMargin: "0px 0px -60px 0px" }
    );
    io.observe(el);
    return () => io.disconnect();
  }, [threshold]);
  return [ref, shown];
}

// Reveal wrapper component
function Reveal({ children, delay = 0, as: As = "div", className = "", style = {}, ...rest }) {
  const [ref, shown] = useReveal();
  return (
    <As
      ref={ref}
      className={`reveal ${shown ? "in" : ""} ${className}`}
      style={{ "--d": `${delay}ms`, ...style }}
      {...rest}
    >
      {children}
    </As>
  );
}

// Count up when in view
function useCountUp(target, duration = 1600) {
  const ref = useRef(null);
  const [val, setVal] = useState(0);
  const started = useRef(false);
  useEffect(() => {
    if (!ref.current) return;
    const el = ref.current;
    const io = new IntersectionObserver(
      (entries) => {
        entries.forEach((e) => {
          if (e.isIntersecting && !started.current) {
            started.current = true;
            const t0 = performance.now();
            const tick = (t) => {
              const p = Math.min(1, (t - t0) / duration);
              const eased = 1 - Math.pow(1 - p, 3);
              setVal(target * eased);
              if (p < 1) requestAnimationFrame(tick);
              else setVal(target);
            };
            requestAnimationFrame(tick);
            io.unobserve(e.target);
          }
        });
      },
      { threshold: 0.4 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, [target, duration]);
  return [ref, val];
}

// Stripe placeholder
function StripePh({ corner, label, style, className = "" }) {
  return (
    <div className={`stripe-ph ${className}`} style={style}>
      {corner && <div className="ph-corner">{corner}</div>}
      {label && <div className="ph-label">{label}</div>}
    </div>
  );
}

Object.assign(window, { useReveal, Reveal, useCountUp, StripePh });
