/* util.jsx — shared atoms & hooks. Exports to window. */
const { useState, useEffect, useRef, useCallback } = React;

/* IntersectionObserver reveal — adds .in once when in view.
   Visible end-state is the base style (see .reveal in CSS), so reduced-motion
   and no-JS show content immediately. */
function Reveal({ children, delay, as, className, ...rest }) {
  const ref = useRef(null);
  const [seen, setSeen] = useState(false);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (!("IntersectionObserver" in window)) { setSeen(true); return; }
    const io = new IntersectionObserver((entries) => {
      entries.forEach((e) => {
        if (e.isIntersecting) { setSeen(true); io.unobserve(e.target); }
      });
    }, { threshold: 0.14, rootMargin: "0px 0px -8% 0px" });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const Tag = as || "div";
  return (
    <Tag
      ref={ref}
      className={"reveal" + (seen ? " in" : "") + (className ? " " + className : "")}
      data-d={delay || undefined}
      {...rest}
    >
      {children}
    </Tag>
  );
}

function Stars({ n, total, className }) {
  const full = Math.round(n || total || 5);
  const max = total || 5;
  return (
    <span className={"stars" + (className ? " " + className : "")} aria-label={full + " of " + max}>
      {Array.from({ length: max }).map((_, i) => (
        <i key={i} style={{ color: i < full ? "var(--brass)" : "var(--line)" }}>&#9733;</i>
      ))}
    </span>
  );
}

function SectionHead({ eyebrow, title, sub, children }) {
  return (
    <div className="section-head">
      {eyebrow ? <Reveal as="p" className="eyebrow">{eyebrow}</Reveal> : null}
      {title ? <Reveal as="h2" delay="1">{title}</Reveal> : null}
      {sub ? <Reveal as="p" delay="2" className="sub">{sub}</Reveal> : null}
      {children}
    </div>
  );
}

/* smooth scroll to an id, accounting for the fixed header */
function scrollToId(id) {
  const el = document.getElementById(id);
  if (!el) return;
  const y = el.getBoundingClientRect().top + window.pageYOffset - 64;
  window.scrollTo({ top: y, behavior: "smooth" });
}

Object.assign(window, { Reveal, Stars, SectionHead, scrollToId });
