/* ============================================================
   RACK & BOX — UI primitives + icons  (exports to window)
   ============================================================ */
const { useState, useEffect, useRef, useContext, createContext } = React;

/* Shared app context (currency, cart actions, navigation) */
const RBCtx = createContext({ currency: "NGN" });

/* ---------- Icons ---------- */
const I = {
  arrow: "M5 12h14M13 6l6 6-6 6",
  arrowR: "M5 12h14M13 6l6 6-6 6",
  cart: "M3 5h2l2.5 11.5a1 1 0 0 0 1 .8h8.6a1 1 0 0 0 1-.78L21 8H6",
  search: "M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM21 21l-4.3-4.3",
  user: "M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8zM4 21a8 8 0 0 1 16 0",
  heart: "M12 20s-7-4.6-9.3-9.1C1 7.7 2.6 4.5 5.8 4.5c2 0 3.3 1.2 4.2 2.5.9-1.3 2.2-2.5 4.2-2.5 3.2 0 4.8 3.2 3.1 6.4C19 15.4 12 20 12 20z",
  close: "M6 6l12 12M18 6L6 18",
  menu: "M3 6h18M3 12h18M3 18h18",
  plus: "M12 5v14M5 12h14",
  minus: "M5 12h14",
  check: "M5 12l4.5 4.5L19 7",
  chevron: "M9 6l6 6-6 6",
  chevronD: "M6 9l6 6 6-6",
  globe: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18zM3 12h18M12 3c2.5 2.5 3.8 5.7 3.8 9s-1.3 6.5-3.8 9c-2.5-2.5-3.8-5.7-3.8-9S9.5 5.5 12 3z",
  truck: "M3 6h11v9H3zM14 9h4l3 3v3h-7zM7.5 18.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3zM17.5 18.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3z",
  ruler: "M3 8h18v8H3zM7 8v3M11 8v4M15 8v3M19 8v4",
  swap: "M7 10l-3 3 3 3M4 13h12M17 14l3-3-3-3M20 11H8",
  return: "M9 7L4 12l5 5M4 12h11a5 5 0 0 1 0 10",
  star: "M12 3l2.6 5.6 6 .8-4.4 4.1 1.1 6L12 16.8 6.7 19.5l1.1-6L3.4 9.4l6-.8z",
  spark: "M12 3v6M12 15v6M3 12h6M15 12h6",
  scissors: "M6 6a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM6 13a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM8 9l12 8M8 15l12-8",
  ig: "M4 8a4 4 0 0 1 4-4h8a4 4 0 0 1 4 4v8a4 4 0 0 1-4 4H8a4 4 0 0 1-4-4zM12 15.5a3.5 3.5 0 1 0 0-7 3.5 3.5 0 0 0 0 7zM17.5 6.5h.01",
  whatsapp: "M12 3a9 9 0 0 0-7.7 13.6L3 21l4.5-1.2A9 9 0 1 0 12 3zM8.5 8.5c.2-.5.4-.5.6-.5h.5c.2 0 .4 0 .6.5l.7 1.6c.1.2 0 .4-.1.5l-.4.5c-.1.1-.2.3 0 .6.3.5.8 1.1 1.5 1.5.3.2.5.1.6 0l.5-.5c.1-.2.3-.2.5-.1l1.5.7c.2.1.3.3.3.5 0 .8-.6 1.4-1.3 1.5-.6.1-1.3.1-3.2-.9-1.8-1-3-2.8-3.1-3-.1-.2-.8-1.1-.8-2 0-1 .5-1.4.7-1.6z",
  x: "M4 4l16 16M20 4L4 20",
  play: "M8 5v14l11-7z",
  shield: "M12 3l8 3v6c0 4.5-3 7.8-8 9-5-1.2-8-4.5-8-9V6z",
  leaf: "M5 19c0-8 6-13 14-13 0 8-5 14-13 14-0.3 0-1 0-1 0zM7 17C12 12 12 9 12 9",
  pin: "M12 21s7-6 7-11a7 7 0 1 0-14 0c0 5 7 11 7 11zM12 12.5a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5z",
  phone: "M5 4h4l2 5-2.5 1.5a11 11 0 0 0 5 5L15 13l5 2v4a2 2 0 0 1-2 2A16 16 0 0 1 3 6a2 2 0 0 1 2-2z",
  mail: "M3 6h18v12H3zM3 7l9 6 9-6",
};
function Icon({ name, size = 20, stroke = 1.6, fill = "none", style, className }) {
  const filled = name === "star-f";
  const d = I[filled ? "star" : name] || "";
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill={filled ? "currentColor" : fill}
      stroke={filled ? "none" : "currentColor"} strokeWidth={stroke} strokeLinecap="round"
      strokeLinejoin="round" style={style} className={className} aria-hidden="true">
      <path d={d} />
    </svg>
  );
}

/* ---------- Eyebrow ---------- */
function Eyebrow({ children, line, muted, style }) {
  return (
    <span className={"eyebrow" + (muted ? " muted" : "") + (line ? " kicker-line" : "")} style={style}>
      {children}
    </span>
  );
}

/* ---------- Button ---------- */
function Btn({ children, onClick, variant, size, block, arrow = true, className = "", type, href }) {
  const cls = ["btn", variant === "ghost" ? "ghost" : "", size ? size : "", block ? "block" : "", className].join(" ").trim();
  const inner = (
    <>
      <span>{children}</span>
      {arrow && <Icon name="arrow" size={16} className="btn-arrow" />}
    </>
  );
  if (href) return <a className={cls} href={href} onClick={onClick}>{inner}</a>;
  return <button type={type || "button"} className={cls} onClick={onClick}>{inner}</button>;
}

/* ---------- Photo (real image or gradient placeholder) ---------- */
function Ph({ label, ratio = "portrait", className = "", style, children }) {
  const src = label ? ((window.RB_IMGS || {})[label] || null) : null;
  const [failed, setFailed] = useState(false);
  useEffect(() => { setFailed(false); }, [src]);
  const show = src && !failed;
  return (
    <div className={"ph " + ratio + (show ? " has-img" : "") + " " + className} style={style}>
      {show && (
        <img
          src={src}
          alt={label || ""}
          onError={() => setFailed(true)}
          style={{ position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover", display: "block" }}
        />
      )}
      {!show && label && <span className="ph-label">{label}</span>}
      {children}
    </div>
  );
}

/* ---------- Price ---------- */
function Price({ ngn, old, className = "", style }) {
  const { currency } = useContext(RBCtx);
  return (
    <span className={className} style={style}>
      {RB.format(ngn, currency)}
      {old && <span className="was" style={{ marginLeft: 10 }}>{RB.format(old, currency)}</span>}
    </span>
  );
}

/* ---------- Stars ---------- */
function Stars({ value = 5, size = 14 }) {
  return (
    <span className="row" style={{ gap: 2, color: "var(--accent)" }}>
      {[1, 2, 3, 4, 5].map((i) => (
        <Icon key={i} name="star-f" size={size} style={{ opacity: i <= value ? 1 : 0.25 }} />
      ))}
    </span>
  );
}

/* ---------- Reveal on scroll ---------- */
function Reveal({ children, delay, as = "div", className = "", style }) {
  const ref = useRef(null);
  useEffect(() => {
    const el = ref.current;
    if (!el) return;
    const io = new IntersectionObserver(
      (ents) => ents.forEach((e) => { if (e.isIntersecting) { el.classList.add("in"); io.unobserve(el); } }),
      { threshold: 0.12 }
    );
    io.observe(el);
    return () => io.disconnect();
  }, []);
  const Tag = as;
  return (
    <Tag ref={ref} className={"reveal " + (delay ? "d" + delay + " " : "") + className} style={style}>
      {children}
    </Tag>
  );
}

/* ---------- Logo mark (icon-only monogram) ---------- */
function Logo({ size = 22, onClick, mono }) {
  const d = size * 1.86;
  return (
    <button className="rb-logo" onClick={onClick} aria-label="Winns Couture" style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", lineHeight: 1 }}>
      <svg width={d} height={d} viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
        <circle cx="24" cy="24" r="22.5" stroke="currentColor" strokeWidth="1" opacity="0.55" />
        <circle cx="24" cy="24" r="19" stroke="var(--accent)" strokeWidth="0.75" opacity="0.7" />
        <text x="24" y="30.5" textAnchor="middle" fontFamily="var(--font-display)" fontSize="20" fontStyle="italic" fontWeight="600" fill="currentColor">W</text>
      </svg>
    </button>
  );
}

/* ---------- Marquee ---------- */
function Marquee({ items, sep = "✦" }) {
  const run = [...items, ...items, ...items];
  return (
    <div className="marquee">
      <div className="marquee-track">
        {run.map((t, i) => (
          <span key={i} className="marquee-item">{t}<span className="marquee-sep">{sep}</span></span>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { RBCtx, Icon, Eyebrow, Btn, Ph, Price, Stars, Reveal, Logo, Marquee });
