/* ============================================================
   Wonderwild — shared core primitives (exported to window)
   Faithful to the Wonderwild Design System tokens.
   Loaded on every page before ww-chrome.jsx / ww-sections.jsx.
   ============================================================ */

/* Google Analytics 4 */
(function() {
  var s = document.createElement('script');
  s.async = true;
  s.src = 'https://www.googletagmanager.com/gtag/js?id=G-4KQN4J0PYG';
  document.head.appendChild(s);
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  window.gtag = gtag;
  gtag('js', new Date());
  gtag('config', 'G-4KQN4J0PYG');
})();


const WW = {
  IMG: "https://wewonderwild.com/wp-content/uploads/2026/01/",
  ICON: "assets/icons/",
  LOGO: "assets/logos/",
};

/* Site map — single source of truth for navigation + footer + page heroes */
const PAGES = {
  home:        { href: "/",                 label: "Home" },
  stays:       { href: "stay",            label: "Bell Tent Stays" },
  staypricing: { href: "stay-pricing",     label: "Bell Tent Pricing" },
  group:       { href: "groups-%26-events", label: "Groups & Events" },
  family:      { href: "family-escape",    label: "Family Weekend Escape" },
  kitchen:     { href: "kitchen-hub",      label: "The Kitchen Hub" },
  swim:        { href: "activities",  label: "Wild Water & Sauna" },
  membership:  { href: "pricing", label: "Pricing & Membership" },
  wellness:    { href: "retreats",label: "Wellness Retreats" },
  retreats:    { href: "retreats#host", label: "Host & Partner" },
  corporate:   { href: "corporate",        label: "Corporate Wellbeing" },
  events:      { href: "groups-%26-events", label: "Groups & Events" },
  whatson:     { href: "whats-on",         label: "What's On" },
  thingstodo:  { href: "things-to-do",     label: "Things to Do" },
  about:       { href: "about",            label: "Our Story" },
  stories:     { href: "editorial",         label: "Stories" },
  faqs:        { href: "faqs",             label: "FAQs" },
  contact:     { href: "contact",          label: "Contact & Location" },
};

/* Header nav structure (Rosewood-style split menu). Items may be a dropdown
   ({label, items:[pageKeys]}) or a direct link ({label, href}). */
const NAV = {
  left: [
    { label: "Stay", items: ["stays", "staypricing", "family", "kitchen"] },
    { label: "Water & Sauna", items: ["swim"] },
    { label: "Gather", items: ["wellness", "retreats", "corporate", "group", "events"] },
  ],
  right: [
    { label: "Pricing", href: "pricing" },
    { label: "What's On", href: "whats-on" },
    { label: "Explore", items: ["thingstodo", "about", "faqs", "contact"] },
  ],
};

/* ---------- Image with branded woodcut fallback tile ---------- */
function Img({ src, icon = "lotus", alt = "", style, ratio, className }) {
  const [failed, setFailed] = React.useState(false);
  const wrap = { position: "relative", overflow: "hidden", background: "var(--green-700)", ...(ratio ? { aspectRatio: ratio } : {}), ...style };
  return (
    <div className={className} style={wrap}>
      <div style={{ position: "absolute", inset: 0, background: "linear-gradient(155deg, var(--green-500) 0%, var(--green-700) 55%, var(--green-900) 100%)", display: "flex", alignItems: "center", justifyContent: "center" }}>
        <img src={WW.ICON + icon + "-cream.png"} alt="" width="84" height="84" style={{ opacity: 0.42 }} />
      </div>
      {!failed && (
        <img src={src} alt={alt} referrerPolicy="no-referrer" loading="lazy" onError={() => setFailed(true)}
          style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }} />
      )}
    </div>
  );
}

/* ---------- Button ---------- */
function Button({ children, variant = "primary", size = "md", href = "#", icon, iconAfter, onClick, style, target }) {
  const [h, setH] = React.useState(false);
  const sizes = {
    sm: { padding: "9px 18px", fontSize: "11px", letterSpacing: "0.18em" },
    md: { padding: "14px 26px", fontSize: "12.5px", letterSpacing: "0.16em" },
    lg: { padding: "17px 34px", fontSize: "13px", letterSpacing: "0.16em" },
  };
  const variants = {
    primary: { background: h ? "var(--green-800)" : "var(--green-700)", color: "var(--cream-100)", borderColor: "transparent", transform: h ? "translateY(-1px)" : "none" },
    secondary: { background: h ? "var(--green-700)" : "transparent", color: h ? "var(--cream-100)" : "var(--green-800)", borderColor: "var(--green-700)" },
    clay: { background: h ? "var(--clay-600)" : "var(--clay-500)", color: "var(--cream-100)", borderColor: "transparent", transform: h ? "translateY(-1px)" : "none" },
    "on-ink": { background: h ? "var(--cream-200)" : "var(--cream-100)", color: "var(--green-800)", borderColor: "transparent", transform: h ? "translateY(-1px)" : "none" },
    "on-ink-outline": { background: h ? "rgba(248,241,233,0.14)" : "transparent", color: "var(--cream-100)", borderColor: "rgba(248,241,233,0.6)" },
  };
  const handle = (e) => { if (onClick) { e.preventDefault(); onClick(e); } };
  return (
    <a href={href} target={target} onClick={handle}
      onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        display: "inline-flex", alignItems: "center", justifyContent: "center", gap: "0.6em",
        fontFamily: "var(--font-label)", fontWeight: 700, textTransform: "uppercase", textDecoration: "none",
        lineHeight: 1, border: "1px solid transparent", borderRadius: "var(--radius-sm)", cursor: "pointer",
        transition: "all var(--dur-base) var(--ease-out)", ...sizes[size], ...variants[variant], ...style,
      }}>
      {icon}<span>{children}</span>{iconAfter}
    </a>
  );
}

/* ---------- Eyebrow ---------- */
function Eyebrow({ children, color = "accent", style }) {
  const colors = { accent: "var(--accent)", "on-ink": "var(--clay-300)", muted: "var(--text-muted)", green: "var(--green-500)", cream: "var(--cream-100)" };
  return <div style={{ fontFamily: "var(--font-label)", fontWeight: 700, fontSize: "0.75rem", textTransform: "uppercase", letterSpacing: "var(--track-eyebrow)", color: colors[color], ...style }}>{children}</div>;
}

/* ---------- Tag ---------- */
function Tag({ children, tone = "soft", style }) {
  const tones = {
    soft: { background: "var(--cream-200)", color: "var(--green-800)", border: "1px solid var(--cream-300)" },
    solid: { background: "var(--green-700)", color: "var(--cream-100)", border: "1px solid var(--green-700)" },
    clay: { background: "var(--clay-100)", color: "var(--clay-600)", border: "1px solid var(--clay-300)" },
    "on-ink": { background: "rgba(248,241,233,0.12)", color: "var(--cream-100)", border: "1px solid var(--border-on-ink)" },
  };
  return <span style={{ display: "inline-flex", alignItems: "center", gap: "0.4em", fontFamily: "var(--font-label)", fontWeight: 700, fontSize: "0.6875rem", lineHeight: 1, letterSpacing: "0.12em", textTransform: "uppercase", padding: "7px 13px", borderRadius: "var(--radius-pill)", ...tones[tone], ...style }}>{children}</span>;
}

/* ---------- Field (underline) ---------- */
function Field({ label, type = "text", placeholder, required, onInk, textarea, rows = 3, value, onChange, options }) {
  const [f, setF] = React.useState(false);
  const labelColor = onInk ? "var(--green-200)" : "var(--text-muted)";
  const textColor = onInk ? "var(--cream-100)" : "var(--text-strong)";
  const lineBase = onInk ? "var(--border-on-ink)" : "var(--border-quiet)";
  const istyle = { width: "100%", boxSizing: "border-box", background: "transparent", border: "none", borderBottom: `1px solid ${f ? "var(--accent)" : lineBase}`, outline: "none", padding: "8px 0", fontFamily: "var(--font-serif)", fontWeight: 300, fontSize: "1.0625rem", color: textColor, transition: "border-color var(--dur-base) var(--ease-out)", resize: "vertical" };
  return (
    <div style={{ display: "flex", flexDirection: "column", gap: "6px" }}>
      {label && <label style={{ fontFamily: "var(--font-label)", fontWeight: 700, fontSize: "0.6875rem", letterSpacing: "var(--track-eyebrow)", textTransform: "uppercase", color: labelColor }}>{label}{required && <span style={{ color: "var(--accent)" }}> *</span>}</label>}
      {textarea
        ? <textarea rows={rows} placeholder={placeholder} value={value} onChange={onChange} onFocus={() => setF(true)} onBlur={() => setF(false)} style={istyle} />
        : options
        ? <select value={value} onChange={onChange} onFocus={() => setF(true)} onBlur={() => setF(false)} style={{ ...istyle, appearance: "none", cursor: "pointer" }}>{options.map((o) => <option key={o} value={o}>{o}</option>)}</select>
        : <input type={type} placeholder={placeholder} value={value} onChange={onChange} onFocus={() => setF(true)} onBlur={() => setF(false)} style={istyle} />}
    </div>
  );
}

/* ---------- Logo ---------- */
function Logo({ variant = "green", size = 38, withText = true, textColor }) {
  const src = WW.LOGO + (variant === "cream" ? "wonderwild-mark-cream.png" : "wonderwild-mark-green.png");
  const tc = textColor || (variant === "cream" ? "var(--cream-100)" : "var(--green-800)");
  return (
    <a href="index" style={{ display: "inline-flex", alignItems: "center", gap: "12px", textDecoration: "none" }}>
      <img src={src} alt="Wonderwild" width={size} height={size} className="ww-logo-img" style={{ objectFit: "contain" }} />
      {withText && <span className="ww-logo-wordmark" style={{ fontFamily: "var(--font-display)", fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.22em", fontSize: "1.05rem", color: tc }}>Wonderwild</span>}
    </a>
  );
}

/* ---------- tiny inline UI glyphs (Lucide-style strokes) ---------- */
function Glyph({ d, size = 20, stroke = "currentColor", sw = 1.5, style }) {
  return <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round" style={style}>{d}</svg>;
}
const Icons = {
  arrowRight: <Glyph d={<><path d="M5 12h14" /><path d="m13 5 7 7-7 7" /></>} />,
  arrowLeft: <Glyph d={<><path d="M19 12H5" /><path d="m11 19-7-7 7-7" /></>} />,
  chevDown: (p) => <Glyph size={14} d={<path d="m6 9 6 6 6-6" />} {...p} />,
  chevRight: (p) => <Glyph size={16} d={<path d="m9 6 6 6-6 6" />} {...p} />,
  plus: (p) => <Glyph d={<><path d="M12 5v14" /><path d="M5 12h14" /></>} {...p} />,
  minus: (p) => <Glyph d={<path d="M5 12h14" />} {...p} />,
  menu: <Glyph d={<><path d="M3 6h18" /><path d="M3 12h18" /><path d="M3 18h18" /></>} />,
  close: <Glyph d={<><path d="M18 6 6 18" /><path d="M6 6l12 12" /></>} />,
  pin: <Glyph size={16} d={<><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z" /><circle cx="12" cy="10" r="3" /></>} />,
  clock: <Glyph size={16} d={<><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3 2" /></>} />,
  train: <Glyph size={16} d={<><rect x="4" y="3" width="16" height="14" rx="2" /><path d="M4 11h16" /><path d="m6 21 2-3M18 21l-2-3" /><circle cx="8.5" cy="14" r="0.6" fill="currentColor" /><circle cx="15.5" cy="14" r="0.6" fill="currentColor" /></>} />,
  car: <Glyph size={16} d={<><path d="M5 13 6.5 8.5A2 2 0 0 1 8.4 7h7.2a2 2 0 0 1 1.9 1.5L19 13" /><path d="M3 13h18v4a1 1 0 0 1-1 1h-1a1 1 0 0 1-1-1v-1H6v1a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1z" /><circle cx="7" cy="15.5" r="0.6" fill="currentColor" /><circle cx="17" cy="15.5" r="0.6" fill="currentColor" /></>} />,
  instagram: <Glyph d={<><rect x="2" y="2" width="20" height="20" rx="5" /><circle cx="12" cy="12" r="4" /><circle cx="17.5" cy="6.5" r="0.6" fill="currentColor" /></>} />,
  facebook: <Glyph d={<path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" />} />,
  check: <Glyph d={<path d="M20 6 9 17l-5-5" />} />,
  leaf: <Glyph size={16} d={<><path d="M11 20A7 7 0 0 1 4 13c0-5 4-9 16-9 0 12-5 16-9 16Z" /><path d="M5 20c4-6 8-8 12-9" /></>} />,
};

function ScrollCarousel({ children, trackStyle }) {
  const scrollRef = React.useRef(null);
  const [canLeft,  setCanLeft]  = React.useState(false);
  const [canRight, setCanRight] = React.useState(false);

  const check = React.useCallback(() => {
    const el = scrollRef.current;
    if (!el) return;
    setCanLeft(el.scrollLeft > 4);
    setCanRight(el.scrollLeft < el.scrollWidth - el.clientWidth - 4);
  }, []);

  React.useEffect(() => {
    const el = scrollRef.current;
    if (!el) return;
    check();
    el.addEventListener('scroll', check, { passive: true });
    const ro = new ResizeObserver(check);
    ro.observe(el);
    return () => { el.removeEventListener('scroll', check); ro.disconnect(); };
  }, [check]);

  const shift = (dir) => {
    const el = scrollRef.current;
    if (el) el.scrollBy({ left: dir * el.clientWidth * 0.78, behavior: 'smooth' });
  };

  const arrowBtn = (dir, active, label) => (
    <button
      aria-label={label}
      onClick={() => active && shift(dir)}
      style={{
        width: "36px", height: "36px", borderRadius: "999px",
        background: "white", border: "1px solid rgba(0,0,0,0.15)",
        boxShadow: "0 1px 4px rgba(0,0,0,0.08)",
        display: "inline-flex", alignItems: "center", justifyContent: "center",
        cursor: active ? "pointer" : "default",
        color: active ? "var(--green-900)" : "rgba(0,0,0,0.25)",
        padding: 0, transition: "box-shadow 0.15s, background 0.15s",
      }}
      onMouseEnter={e => { if (active) { e.currentTarget.style.boxShadow = "0 2px 8px rgba(0,0,0,0.14)"; e.currentTarget.style.background = "var(--cream-100)"; } }}
      onMouseLeave={e => { e.currentTarget.style.boxShadow = "0 1px 4px rgba(0,0,0,0.08)"; e.currentTarget.style.background = "white"; }}
    >
      {dir === -1 ? Icons.arrowLeft : Icons.arrowRight}
    </button>
  );

  const needsScroll = canLeft || canRight;

  return (
    <div>
      {needsScroll && (
        <div style={{ display: "flex", justifyContent: "flex-end", paddingRight: "clamp(20px, 5vw, 80px)", marginBottom: "16px" }}>
          <div style={{ display: "flex", gap: "8px" }}>
            {arrowBtn(-1, canLeft,  "Previous")}
            {arrowBtn( 1, canRight, "Next")}
          </div>
        </div>
      )}
      <div className="ww-exp-scroll" ref={scrollRef}>
        <div className="ww-exp-track" style={trackStyle}>
          {children}
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { WW, PAGES, NAV, Img, Button, Eyebrow, Tag, Field, Logo, Glyph, Icons, ScrollCarousel });
