/* ============================================================================
   SHARED UI PRIMITIVES + HOOKS
   ============================================================================ */
const { useState, useRef: useRefU, useEffect: useEffectU, useCallback } = React;

function prefersReduced() {
  return window.matchMedia("(prefers-reduced-motion: reduce)").matches;
}

/* Reveal-on-scroll: adds .is-in when element enters viewport. */
function useReveal(options = {}) {
  const ref = useRefU(null);
  const [shown, setShown] = useState(false);
  useEffectU(() => {
    const el = ref.current;
    if (!el) return;
    if (prefersReduced()) { setShown(true); return; }
    const io = new IntersectionObserver(
      (entries) => entries.forEach((e) => { if (e.isIntersecting) { setShown(true); io.disconnect(); } }),
      { threshold: options.threshold ?? 0.2, rootMargin: options.rootMargin ?? "0px 0px -8% 0px" }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return [ref, shown];
}

/* Reveal wrapper: fades/rises children in when scrolled into view. */
function Reveal({ children, delay = 0, as = "div", className = "", style = {}, id }) {
  const [ref, shown] = useReveal();
  return React.createElement(
    as,
    {
      ref,
      id,
      className: `reveal ${shown ? "is-in" : ""} ${className}`,
      style: { ...style, transitionDelay: `${delay}ms` },
    },
    children
  );
}

/* Number that counts up when it enters view, then tweens on value changes. */
function CountUp({ value, duration = 1100, prefix = "", suffix = "", decimals = 0, className = "", live = false }) {
  const [ref, shown] = useReveal({ threshold: 0.5 });
  const [display, setDisplay] = useState(live ? value : 0);
  const fromRef = useRefU(0);
  const startedRef = useRefU(false);

  useEffectU(() => {
    if (!shown && !live) return;
    if (prefersReduced() || document.documentElement.classList.contains("no-anim")) { setDisplay(value); return; }
    const from = live ? fromRef.current : (startedRef.current ? fromRef.current : 0);
    startedRef.current = true;
    const start = performance.now();
    let raf;
    const dur = live ? 650 : duration;
    function step(t) {
      const k = Math.min(1, (t - start) / dur);
      const e = 1 - Math.pow(1 - k, 3);
      const v = from + (value - from) * e;
      setDisplay(v);
      if (k < 1) raf = requestAnimationFrame(step);
      else fromRef.current = value;
    }
    raf = requestAnimationFrame(step);
    const safety = setTimeout(() => { setDisplay(value); fromRef.current = value; }, dur + 160);
    return () => { cancelAnimationFrame(raf); clearTimeout(safety); };
  }, [value, shown]);

  const txt = Number(display).toLocaleString("en-US", { minimumFractionDigits: decimals, maximumFractionDigits: decimals });
  return React.createElement("span", { ref, className }, prefix + txt + suffix);
}

/* TS lockup — real brand assets.
   variant: "wordmark" = full TS Talya Smart image (entry/footer)
            "lockup"   = TS tile + "Talya Smart" text (detail-page nav)
            "icon"     = TS tile only */
function Logo({ size = 32, variant, withWordmark = true, onClick }) {
  const mode = variant || (withWordmark ? "wordmark" : "icon");

  if (mode === "wordmark") {
    return React.createElement(
      "button",
      { className: "ts-lockup wordmark", onClick, "aria-label": "Talya Smart — restart diagnosis", type: "button" },
      React.createElement("img", {
        className: "ts-wordmark-img", src: "assets/ts-wordmark-white.png",
        alt: "TS Talya Smart", style: { height: size * 0.86 },
      })
    );
  }

  const tile = React.createElement(
    "span",
    { className: "ts-mark", style: { width: size, height: size } },
    React.createElement("img", { className: "ts-mark-img", src: "assets/ts-mark-white.png", alt: "TS" })
  );

  if (mode === "icon") {
    return React.createElement(
      "button",
      { className: "ts-lockup", onClick, "aria-label": "Talya Smart — restart diagnosis", type: "button" },
      tile
    );
  }

  // lockup
  return React.createElement(
    "button",
    { className: "ts-lockup lockup", onClick, "aria-label": "Talya Smart — restart diagnosis", type: "button" },
    tile,
    React.createElement("span", { className: "ts-lockup-text" }, "Talya Smart")
  );
}

/* Animated "OS" / pill chip. */
function Chip({ children, accent, className = "" }) {
  return React.createElement(
    "span",
    { className: `chip ${className}`, style: accent ? { "--chip": accent } : {} },
    children
  );
}

Object.assign(window, { prefersReduced, useReveal, Reveal, CountUp, Logo, Chip });
