/* ui.jsx — shared primitives. Exports to window. Loaded first. */
const { useState, useEffect, useRef, useContext, createContext, useMemo, useCallback } = React;

/* design-system components (from the loaded bundle) */
const DS = window.OLIVEARCHDesignSystem_cfb58f || {};
const { Badge } = DS;

/* ---- language context ---------------------------------------------------- */
const LangContext = createContext("en");
const useLang = () => useContext(LangContext);
/* localized-text helper bound to current lang */
const useT = () => { const l = useLang(); return (v) => window.t(v, l); };

/* ---- icon set (Lucide-style, 1.6px stroke, currentColor) ----------------- */
const ICONS = {
  "arrow-right": <path d="M5 12h14M13 6l6 6-6 6" />,
  "arrow-up-right": <path d="M7 17L17 7M8 7h9v9" />,
  plus: <path d="M12 5v14M5 12h14" />,
  menu: <path d="M4 7h16M4 12h16M4 17h16" />,
  x: <path d="M6 6l12 12M18 6L6 18" />,
  phone: <path d="M4 4h4l2 5-2.5 1.5a11 11 0 006 6L15 14l5 2v4a2 2 0 01-2 2A16 16 0 012 6a2 2 0 012-2z" />,
  mail: <><rect x="3" y="5" width="18" height="14" rx="2" /><path d="M3 7l9 6 9-6" /></>,
  "map-pin": <><path d="M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0116 0z" /><circle cx="12" cy="10" r="3" /></>,
  globe: <><circle cx="12" cy="12" r="9" /><path d="M3 12h18M12 3c2.5 2.5 4 5.5 4 9s-1.5 6.5-4 9c-2.5-2.5-4-5.5-4-9s1.5-6.5 4-9z" /></>,
  filter: <path d="M3 5h18l-7 8v5l-4 2v-7L3 5z" />,
  grid: <><rect x="3" y="3" width="7" height="7" rx="1" /><rect x="14" y="3" width="7" height="7" rx="1" /><rect x="3" y="14" width="7" height="7" rx="1" /><rect x="14" y="14" width="7" height="7" rx="1" /></>,
  ring: <><ellipse cx="12" cy="12" rx="9" ry="5" /><ellipse cx="12" cy="12" rx="3.4" ry="9" /></>,
  "chevron-down": <path d="M6 9l6 6 6-6" />,
  "chevron-left": <><path d="M15 6l-6 6 6 6" /></>,
  images: <><rect x="7" y="3" width="14" height="14" rx="2" /><path d="M3 7v12a2 2 0 002 2h12" /><path d="M11 11l2.5 2.5L17 10l4 5" /></>,
  "chevron-right": <path d="M9 6l6 6-6 6" />,
  target: <><circle cx="12" cy="12" r="8" /><circle cx="12" cy="12" r="3.6" /><path d="M12 2v3M12 19v3M2 12h3M19 12h3" /></>,
  shield: <path d="M12 3l7 3v5c0 5-3.5 8-7 10-3.5-2-7-5-7-10V6l7-3z" />,
  "shield-check": <><path d="M12 3l7 3v5c0 5-3.5 8-7 10-3.5-2-7-5-7-10V6l7-3z" /><path d="M9 12l2 2 4-4" /></>,
  users: <><circle cx="9" cy="8" r="3.2" /><path d="M3 20c0-3.3 2.7-6 6-6s6 2.7 6 6M16 5.5a3 3 0 010 5.8M21 20c0-2.5-1.5-4.6-3.6-5.5" /></>,
  clock: <><circle cx="12" cy="12" r="9" /><path d="M12 7v5l3.5 2" /></>,
  compass: <><circle cx="12" cy="12" r="9" /><path d="M15.5 8.5l-2 5-5 2 2-5 5-2z" /></>,
  medal: <><circle cx="12" cy="9" r="5" /><path d="M9 13.5L7 22l5-2.5L17 22l-2-8.5" /><path d="M12 6.5l.8 1.6 1.7.2-1.3 1.2.3 1.7-1.5-.8-1.5.8.3-1.7-1.3-1.2 1.7-.2z" /></>,
  "trending-up": <path d="M3 17l6-6 4 4 8-8M15 7h6v6" />,
  layers: <path d="M12 3l9 5-9 5-9-5 9-5zM3 13l9 5 9-5M3 17l9 5 9-5" />,
  cpu: <><rect x="7" y="7" width="10" height="10" rx="1.5" /><path d="M10 3v3M14 3v3M10 18v3M14 18v3M3 10h3M3 14h3M18 10h3M18 14h3" /></>,
  "hard-hat": <path d="M3 17a9 9 0 0118 0M6 17V11a6 6 0 013-5M15 6a6 6 0 013 5v6M11 5h2v3h-2zM2.5 17h19" />,
  ruler: <path d="M3 15L15 3l6 6L9 21l-6-6zM7 11l2 2M11 7l2 2M15 11l-2 2" />,
  building: <><rect x="5" y="3" width="14" height="18" rx="1" /><path d="M9 7h1M14 7h1M9 11h1M14 11h1M9 15h1M14 15h1M10 21v-3h4v3" /></>,
  hospital: <><rect x="4" y="3" width="16" height="18" rx="1" /><path d="M12 7v5M9.5 9.5h5M9 21v-4h6v4" /></>,
  trees: <path d="M10 10a4 4 0 10-4 4M6 14v6M18 10a3 3 0 10-2 5M17 15v5" />,
  sofa: <path d="M4 12V9a2 2 0 012-2h12a2 2 0 012 2v3M3 12a2 2 0 012 2v3h14v-3a2 2 0 012-2M5 17v2M19 17v2" />,
  flame: <path d="M12 3s5 4 5 9a5 5 0 01-10 0c0-2 1-3 1-3s.5 1.5 2 1.5C11 8 12 3 12 3z" />,
  leaf: <path d="M4 20c0-9 7-16 16-16 0 9-7 16-16 16zM4 20c3-4 6-6 10-8" />,
  quote: <path d="M8 7c-2 1-3 3-3 5v5h5v-5H6c0-2 .8-3.4 2.5-4.2L8 7zM17 7c-2 1-3 3-3 5v5h5v-5h-4c0-2 .8-3.4 2.5-4.2L17 7z" />,
  check: <path d="M5 12l4.5 4.5L19 7" />,
  "badge-check": <><path d="M12 2l2.4 1.8 3-.2 1 2.8 2.6 1.4-.8 2.9.8 2.9-2.6 1.4-1 2.8-3-.2L12 22l-2.4-1.8-3 .2-1-2.8-2.6-1.4.8-2.9-.8-2.9 2.6-1.4 1-2.8 3 .2L12 2z" /><path d="M9 12l2 2 4-4" /></>,
  drafting: <><circle cx="12" cy="7" r="3" /><path d="M12 10v5l-6 6M12 15l6 6" /></>,
  sparkle: <path d="M12 3l1.6 5.4L19 10l-5.4 1.6L12 17l-1.6-5.4L5 10l5.4-1.6L12 3z" />,
  "chevrons-right": <path d="M6 6l6 6-6 6M13 6l6 6-6 6" />,
  handshake: <path d="M8 12l3-3 3 3 3-3M3 10l4-4 5 5M21 10l-4-4-3 3M8 12l-2 2a1.5 1.5 0 002 2l1-1M13 17l2 2a1.5 1.5 0 002-2l-1-1" />,
  award: <><circle cx="12" cy="9" r="5" /><path d="M8.5 13L7 21l5-2.5L17 21l-1.5-8" /></>,
};
function Icon({ name, size = 20, stroke = 1.6, style, className }) {
  return (
    <svg className={className} width={size} height={size} viewBox="0 0 24 24" fill="none"
      stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
      style={style} aria-hidden="true">{ICONS[name] || null}</svg>
  );
}

/* ---- reveal on scroll ---------------------------------------------------- */
function Reveal({ children, as = "div", delay, className = "", style, ...rest }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    if (!("IntersectionObserver" in window)) { el.classList.add("is-in"); return; }
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { el.classList.add("is-in"); io.disconnect(); }
    }, { threshold: 0.14, rootMargin: "0px 0px -6% 0px" });
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const Tag = as;
  return <Tag ref={ref} className={("reveal " + className).trim()} data-d={delay} style={style} {...rest}>{children}</Tag>;
}

/* ---- overline + section header ------------------------------------------- */
function Overline({ children, style }) {
  return <span className="overline" style={style}>{children}</span>;
}

/* ---- masked line-by-line headline reveal (signature load motion) --------- */
function Headline({ text, as = "h1", className = "", style, startDelay = 140, lineDelay = 95, onScroll = false }) {
  const ref = useRef(null);
  const lines = String(text).split("\n");
  useEffect(() => {
    const el = ref.current; if (!el) return;
    if (window.matchMedia("(prefers-reduced-motion:reduce)").matches) { el.classList.add("in"); return; }
    if (onScroll && "IntersectionObserver" in window) {
      const io = new IntersectionObserver(([e]) => { if (e.isIntersecting) { el.classList.add("in"); io.disconnect(); } }, { threshold: 0.2, rootMargin: "0px 0px -8% 0px" });
      io.observe(el);
      return () => io.disconnect();
    }
    const t = setTimeout(() => el.classList.add("in"), startDelay);
    return () => clearTimeout(t);
  }, [text]);
  const Tag = as;
  return (
    <Tag ref={ref} className={("headline " + className).trim()} style={style}>
      {lines.map((ln, i) => (
        <span className="hl-ln" key={i}><span className="hl-i" style={{ transitionDelay: (i * lineDelay) + "ms" }}>{ln || "\u00a0"}</span></span>
      ))}
    </Tag>
  );
}
function SectionHead({ overline, title, lead, align = "left", maxWidth }) {
  return (
    <div className="shead" style={{ textAlign: align, marginInline: align === "center" ? "auto" : undefined, maxWidth }}>
      <Reveal><Overline>{overline}</Overline></Reveal>
      <Headline as="h2" text={title} className="display" onScroll style={{ marginTop: 22 }} />
      {lead && <Reveal delay="2"><p className="lead">{lead}</p></Reveal>}
    </div>
  );
}

/* ---- number count-up ----------------------------------------------------- */
function CountUp({ value, prefix = "", suffix = "", duration = 1700 }) {
  const [n, setN] = useState(0);
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) {
        const start = performance.now();
        const step = (t) => {
          const p = Math.min(1, (t - start) / duration);
          setN(Math.round(value * (1 - Math.pow(1 - p, 3))));
          if (p < 1) requestAnimationFrame(step);
        };
        requestAnimationFrame(step);
        io.disconnect();
      }
    }, { threshold: 0.5 });
    io.observe(el);
    return () => io.disconnect();
  }, [value]);
  return <span ref={ref}>{prefix}{n.toLocaleString("en-IN")}{suffix}</span>;
}

/* ---- primary CTA button (DS-styled) -------------------------------------- */
function Cta({ children, onClick, variant = "primary", size = "lg", icon = "arrow-right", type }) {
  const [h, setH] = useState(false);
  const styles = {
    primary: { background: h ? "var(--olv-gold-champagne)" : "var(--olv-gold)", color: "var(--olv-black)", border: "1px solid transparent" },
    outline: { background: h ? "rgba(212,175,55,.08)" : "transparent", color: "var(--olv-gold)", border: "1px solid var(--border-gold-strong)" },
    secondary: { background: "var(--surface-card-elevated)", color: h ? "var(--olv-gold-champagne)" : "var(--text-heading)", border: "1px solid var(--border-gold)" },
  };
  const H = { lg: 56, md: 48, sm: 40 }[size];
  return (
    <button type={type || "button"} onClick={onClick} onMouseEnter={() => setH(true)} onMouseLeave={() => setH(false)}
      style={{
        height: H, padding: "0 30px", borderRadius: "var(--radius-button)", fontFamily: "var(--font-body)",
        fontSize: "var(--fs-body)", fontWeight: 500, display: "inline-flex", alignItems: "center", gap: 10,
        cursor: "pointer", letterSpacing: ".01em", whiteSpace: "nowrap",
        transition: "background .4s var(--ease-luxury),color .4s,border-color .4s", ...styles[variant],
      }}>
      {children}{icon && <Icon name={icon} size={18} style={{ transform: h ? "translateX(3px)" : "none", transition: "transform .4s var(--ease-luxury)" }} />}
    </button>
  );
}

/* ---- link button (underline reveal, reference style) --------------------- */
function LinkBtn({ children, onClick, active, plus = true, style }) {
  return (
    <button className={"linkbtn" + (active ? " is-active" : "")} onClick={onClick} style={style}>
      {children}{plus && <span className="lb-plus"><Icon name="plus" size={14} /></span>}
    </button>
  );
}

/* ---- custom cursor (fine pointers) --------------------------------------- */
function CustomCursor() {
  useEffect(() => {
    const fine = window.matchMedia("(hover:hover) and (pointer:fine)").matches;
    if (!fine) return;
    const dot = document.getElementById("cDot"), ring = document.getElementById("cRing"), torch = document.getElementById("cTorch");
    if (!dot || !ring) return;
    document.body.classList.add("cursor-on");
    let mx = window.innerWidth / 2, my = window.innerHeight / 2, rx = mx, ry = my, tx = mx, ty = my, raf;
    const move = (e) => { mx = e.clientX; my = e.clientY; dot.style.transform = `translate(${mx}px,${my}px) translate(-50%,-50%)`; };
    const loop = () => { rx += (mx - rx) * 0.18; ry += (my - ry) * 0.18; ring.style.transform = `translate(${rx}px,${ry}px) translate(-50%,-50%)`; if (torch) { tx += (mx - tx) * 0.12; ty += (my - ty) * 0.12; torch.style.transform = `translate(${tx}px,${ty}px) translate(-50%,-50%)`; } raf = requestAnimationFrame(loop); };
    const over = (e) => {
      const t = e.target.closest("a,button,[data-cursor='grab'],input,select,textarea,label");
      if (!t) { ring.style.width = "34px"; ring.style.height = "34px"; ring.style.borderColor = "var(--border-gold-strong)"; return; }
      if (t.getAttribute("data-cursor") === "grab") { ring.style.width = "58px"; ring.style.height = "58px"; ring.style.borderColor = "var(--olv-gold)"; }
      else { ring.style.width = "46px"; ring.style.height = "46px"; ring.style.borderColor = "var(--olv-gold)"; }
    };
    window.addEventListener("mousemove", move);
    window.addEventListener("mouseover", over);
    loop();
    return () => { window.removeEventListener("mousemove", move); window.removeEventListener("mouseover", over); cancelAnimationFrame(raf); document.body.classList.remove("cursor-on"); };
  }, []);
  return null;
}

/* ---- scroll to a section id ---------------------------------------------- */
function scrollToId(id) {
  const el = document.getElementById(id);
  if (!el) return;
  const y = el.getBoundingClientRect().top + window.scrollY - 64;
  window.scrollTo({ top: y, behavior: "smooth" });
}

Object.assign(window, { LangContext, useLang, useT, Icon, Reveal, Overline, Headline, SectionHead, CountUp, Cta, LinkBtn, CustomCursor, scrollToId, Badge });
