// Kid Link — shared UI primitives (vanilla JSX, no JSX-runtime imports).
// Loaded via <script type="text/babel" src="components.jsx"></script>.
// All design tokens live in /colors_and_type.css and are referenced by var().

const { useState, useEffect, useRef, createContext, useContext } = React;

// ------------------ Scroll reveal ------------------
// Attach the returned ref to an element with the `kl-reveal` class; it fades
// + rises into place the first time it scrolls into view. No-op (instantly
// visible) when the user prefers reduced motion.
function useReveal() {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;
    if (reduce || typeof IntersectionObserver === "undefined") {
      el.classList.add("is-visible");
      return;
    }
    const io = new IntersectionObserver((entries, obs) => {
      entries.forEach((e) => {
        if (e.isIntersecting) {
          e.target.classList.add("is-visible");
          obs.unobserve(e.target);
        }
      });
    }, { threshold: 0.1, rootMargin: "0px 0px -6% 0px" });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  return ref;
}

// ------------------ Routing context (mock SPA) ------------------
const ROUTES = ["home", "parents", "clinicians", "educators", "organisations", "team", "events", "fees", "policies"];
function initialRoute() {
  try {
    // Clean-path URLs are canonical (/parents, /team, …) — served as pre-rendered
    // static pages for SEO; the app takes over after load.
    const seg = window.location.pathname.split("/").filter(Boolean)[0] || "";
    if (ROUTES.includes(seg)) return seg;
    // Legacy links: /ui_kits/website/index.html?route=X still works.
    const r = new URLSearchParams(window.location.search).get("route");
    if (r && ROUTES.includes(r)) return r;
  } catch (e) {}
  return "home";
}
// The SPA shell can also be loaded directly (e.g. local preview at
// /ui_kits/website/index.html) — in that case keep URL updates relative to it.
function routeUrl(next) {
  const onShell = window.location.pathname.indexOf("/ui_kits/") === 0;
  if (onShell) return next === "home" ? window.location.pathname : window.location.pathname + "?route=" + next;
  return next === "home" ? "/" : "/" + next;
}
const RouteContext = createContext({ route: "home", go: () => {} });
function RouteProvider({ children }) {
  const [route, setRoute] = useState(initialRoute);
  const go = (next) => {
    setRoute(next);
    // Keep the URL in sync so links are shareable and refresh stays put.
    try {
      window.history.replaceState(null, "", routeUrl(next));
    } catch (e) {}
    // In-app route changes use replaceState, which analytics doesn't see,
    // so report them as custom events.
    if (window.klTrack) window.klTrack("page_view", { route: next });
    window.scrollTo({ top: 0, behavior: "instant" });
  };
  return <RouteContext.Provider value={{ route, go }}>{children}</RouteContext.Provider>;
}
function useRoute() { return useContext(RouteContext); }

// Smooth-scroll to the Contact section on the current page (header offset handled
// by `.kl-section { scroll-margin-top }` in CSS). Used by every "Enquire Now" CTA.
// Pass a string to pre-fill the message box (e.g. "I'd like to join the waitlist…")
// so topic-specific CTAs land the visitor on a form that's already started.
function scrollToContact(prefill) {
  const el = document.getElementById("contact");
  if (el) el.scrollIntoView({ behavior: "smooth", block: "start" });
  if (typeof prefill === "string" && prefill) {
    setTimeout(() => {
      const msg = document.getElementById("contact-message");
      if (msg && !msg.value) msg.value = prefill;
    }, 350);
  }
}

// Report clicks on any link that leaves the site (Splose, Eventbrite,
// Kid Link Education, socials…) so we can see where funnels hand off.
document.addEventListener("click", (e) => {
  const a = e.target && e.target.closest && e.target.closest("a[href]");
  if (!a) return;
  const href = a.getAttribute("href") || "";
  if (!/^https?:/i.test(href)) return;
  try {
    const u = new URL(href);
    if (u.host !== window.location.host && window.klTrack) {
      window.klTrack("outbound_click", { url: u.origin + u.pathname });
    }
  } catch (err) {}
}, true);

// ------------------ Section wrapper ------------------
function Section({ scheme = "scheme-2", children, className = "", style = {}, id }) {
  const revealRef = useReveal();
  return (
    <section
      id={id}
      className={`${scheme} kl-section ${className}`}
      style={{ padding: "var(--kl-section-py) var(--kl-section-px)", ...style }}
    >
      <div ref={revealRef} className="kl-reveal" style={{ maxWidth: "var(--kl-container)", marginInline: "auto" }}>
        {children}
      </div>
    </section>
  );
}

// ------------------ Button ------------------
function Button({ variant = "primary", size = "default", children, onClick, iconRight, iconLeft, ...rest }) {
  const cls = ["kl-btn", `kl-btn--${variant}`, size === "sm" ? "kl-btn--sm" : ""].join(" ");
  return (
    <button className={cls} onClick={onClick} {...rest}>
      {iconLeft}
      {children}
      {iconRight}
    </button>
  );
}

// ------------------ ChevronRight (matches relume-icons.ChevronRight) ------------------
function ChevronRight({ size = 18 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="9 6 15 12 9 18" />
    </svg>
  );
}
function ChevronDown({ size = 18 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <polyline points="6 9 12 15 18 9" />
    </svg>
  );
}

// ------------------ Material Symbols icon ------------------
// Uses CDN — matches the codebase's pattern in layout-364.jsx.
function MIcon({ name, size = 48, color }) {
  const src = `https://cdn.jsdelivr.net/npm/@material-symbols/svg-500@latest/rounded/${name}.svg`;
  // When a colour is requested, mask the (black) SVG so `background` shows through;
  // otherwise render the mark directly as an <img>.
  if (color) {
    return (
      <span
        aria-hidden="true"
        style={{
          display: "inline-block", width: size, height: size,
          background: color,
          WebkitMaskImage: `url(${src})`, maskImage: `url(${src})`,
          WebkitMaskSize: "contain", maskSize: "contain",
          WebkitMaskRepeat: "no-repeat", maskRepeat: "no-repeat",
          WebkitMaskPosition: "center", maskPosition: "center",
        }}
      />
    );
  }
  return <img src={src} width={size} height={size} alt="" />;
}

// ------------------ Eyebrow + Section header ------------------
function Eyebrow({ children, onPhoto = false }) {
  const cls = onPhoto ? "kl-eyebrow kl-eyebrow--on-photo" : "kl-eyebrow";
  return <p className={cls}>{children}</p>;
}
function SectionHeader({ eyebrow, title, lede, align = "center", mb = 80, innerMax }) {
  const max = align === "center" ? { maxWidth: "var(--kl-container)", marginInline: "auto", textAlign: "center" } : {};
  const defInner = align === "center" ? "32rem" : "42rem";
  const inner = align === "center" ? { maxWidth: innerMax || defInner, margin: "0 auto" } : { maxWidth: innerMax || defInner };
  return (
    <div style={{ marginBottom: mb, ...max }}>
      <div style={inner}>
        {eyebrow && <Eyebrow>{eyebrow}</Eyebrow>}
        <h2 style={{ marginBottom: 20, fontSize: "var(--kl-text-h2)" }}>{title}</h2>
        {lede && <p style={{ fontSize: "var(--kl-text-medium)", lineHeight: 1.6, color: "var(--kl-fg-2)" }}>{lede}</p>}
      </div>
    </div>
  );
}

// ------------------ Card (sharp corners) ------------------
function Card({ children, style = {}, ...rest }) {
  return (
    <div
      className="kl-card"
      style={{
        background: "var(--kl-card-bg)",
        border: "var(--kl-card-border)",
        borderRadius: "var(--kl-radius-card)",
        boxShadow: "var(--kl-card-shadow)",
        overflow: "hidden",   // clip child media to the rounded corners
        ...style,
      }}
      {...rest}
    >
      {children}
    </div>
  );
}

// ------------------ Container ------------------
function Container({ children, style = {} }) {
  return <div style={{ maxWidth: "var(--kl-container)", marginInline: "auto", ...style }}>{children}</div>;
}

// Expose to other Babel scripts (each script gets its own scope unless we attach to window).
Object.assign(window, {
  RouteProvider, useRoute, RouteContext,
  Section, Button, ChevronRight, ChevronDown,
  MIcon, Eyebrow, SectionHeader, Card, Container,
  scrollToContact,
});
