/* ============================================================
   Shared UI primitives + icons  →  window globals
   ============================================================ */
const { useState, useEffect, useRef, useContext, createContext, useReducer } = React;

/* ---------- Icons (simple line set) ---------- */
const I = {
  bag: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M6 8h12l-1 12H7L6 8Z" strokeLinejoin="round"/><path d="M9 8V6a3 3 0 0 1 6 0v2"/></svg>,
  search: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><circle cx="11" cy="11" r="7"/><path d="m20 20-3.2-3.2"/></svg>,
  user: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><circle cx="12" cy="8" r="4"/><path d="M4 20c0-4 4-6 8-6s8 2 8 6"/></svg>,
  heart: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M12 20s-7-4.4-7-9.5A4 4 0 0 1 12 7a4 4 0 0 1 7 3.5C19 15.6 12 20 12 20Z" strokeLinejoin="round"/></svg>,
  menu: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M4 7h16M4 12h16M4 17h16"/></svg>,
  close: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M6 6l12 12M18 6 6 18"/></svg>,
  plus: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M12 5v14M5 12h14"/></svg>,
  minus: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M5 12h14"/></svg>,
  star: (p) => <svg viewBox="0 0 24 24" fill="currentColor" {...p}><path d="m12 3 2.6 5.6 6.1.7-4.5 4.2 1.2 6L12 16.9 6.6 19.5l1.2-6L3.3 9.3l6.1-.7L12 3Z"/></svg>,
  arrow: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M5 12h14M13 6l6 6-6 6" strokeLinejoin="round" strokeLinecap="round"/></svg>,
  check: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" {...p}><path d="m5 13 4 4 10-11" strokeLinejoin="round" strokeLinecap="round"/></svg>,
  truck: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M3 6h11v9H3zM14 9h4l3 3v3h-7z"/><circle cx="7" cy="18" r="1.8"/><circle cx="17" cy="18" r="1.8"/></svg>,
  shield: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M12 3l8 3v6c0 5-3.5 8-8 9-4.5-1-8-4-8-9V6l8-3Z" strokeLinejoin="round"/></svg>,
  gift: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><path d="M4 11h16v9H4zM4 8h16v3H4zM12 8v12M12 8c-1-3-5-3-5-1s4 1 5 1Zm0 0c1-3 5-3 5-1s-4 1-5 1Z" strokeLinejoin="round"/></svg>,
  globe: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><circle cx="12" cy="12" r="9"/><path d="M3 12h18M12 3c3 3 3 15 0 18M12 3c-3 3-3 15 0 18"/></svg>,
  ig: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><rect x="3" y="3" width="18" height="18" rx="5"/><circle cx="12" cy="12" r="4"/><circle cx="17" cy="7" r="1" fill="currentColor" stroke="none"/></svg>,
  pin: (p) => <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" {...p}><circle cx="12" cy="12" r="9"/><path d="M12 7c-1.7 0-3 1.3-3 3 0 1.4 1 2 1 3s-.6 2.5-.6 2.5M12 7c1.7 0 3 1.3 3 3 0 2-2.3 2.3-3 4"/></svg>,
  tiktok: (p) => <svg viewBox="0 0 24 24" fill="currentColor" stroke="none" {...p}><path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 0 1-2.88 2.5 2.89 2.89 0 0 1-2.89-2.89 2.89 2.89 0 0 1 2.89-2.89c.28 0 .54.04.79.1V9.01a6.33 6.33 0 0 0-.79-.05 6.34 6.34 0 0 0-6.34 6.34 6.34 6.34 0 0 0 6.34 6.34 6.34 6.34 0 0 0 6.33-6.34V8.69a8.18 8.18 0 0 0 4.78 1.52V6.77a4.85 4.85 0 0 1-1.01-.08Z"/></svg>,
};

/* ---------- Placeholder / Real image ---------- */
function Ph({ label, variant = '', style, className = '', src, children }) {
  const [err, setErr] = useState(false);
  const showImg = src && !err;
  return (
    <div className={`ph ${variant} ${className}`} data-label={showImg ? '' : label} style={style}>
      {showImg && (
        <img
          src={src}
          alt={label || ''}
          style={{ position: 'absolute', inset: 0, width: '100%', height: '100%', objectFit: 'cover', display: 'block' }}
          loading="lazy"
          decoding="async"
          onError={() => setErr(true)}
        />
      )}
      {children}
    </div>
  );
}

/* ---------- Star rating ---------- */
function Stars({ value = 5, size = 13 }) {
  return (
    <span style={{ display: 'inline-flex', gap: 2, color: 'var(--gold)' }} aria-label={`${value} stars`}>
      {[0,1,2,3,4].map(i => <I.star key={i} width={size} height={size} style={{ opacity: i < Math.round(value) ? 1 : .25 }} />)}
    </span>
  );
}

/* ---------- Scroll reveal ---------- */
function Reveal({ children, as = 'div', delay = 0, className = '', ...rest }) {
  const ref = useRef(null);
  const [shown, setShown] = useState(false);
  useEffect(() => {
    const el = ref.current; if (!el || shown) return;
    const io = new IntersectionObserver(([e]) => {
      if (e.isIntersecting) { setShown(true); io.disconnect(); }
    }, { threshold: 0.1 });
    io.observe(el);
    // Safety: ensure visible even if observer never fires
    const t = setTimeout(() => setShown(true), 1200);
    return () => { io.disconnect(); clearTimeout(t); };
  }, []);
  const Tag = as;
  return <Tag ref={ref} className={`reveal ${shown ? 'in' : ''} ${className}`} data-d={delay || undefined} {...rest}>{children}</Tag>;
}

Object.assign(window, { I, Ph, Stars, Reveal, useState, useEffect, useRef, useContext, createContext, useReducer });
