// Primitives.jsx, JVFood marketplace shared UI atoms
// All primitives map 1:1 to the spec cards in /preview.

const { useState, useEffect } = React;

// -------------------------- VIEWPORT HOOK --------------------------
// Single-source-of-truth viewport store. One global resize listener,
// every subscribed component re-renders in lockstep. Avoids the
// per-component listener drift that made resize-without-refresh look
// half-applied.
//
// Breakpoints (mirror colors_and_type.css):
//   sm < 640, md 640–1023, lg 1024–1279, xl ≥ 1280
const __viewportStore = (() => {
 const compute = () => {
  const w = typeof window !== "undefined" ? window.innerWidth : 1280;
  return {
   width: w,
   isMobile: w < 640,
   isTabletDown: w < 1024,
   isTablet: w >= 640 && w < 1024,
   isDesktop: w >= 1024,
   isWide: w >= 1280,
  };
 };
 let current = compute();
 const listeners = new Set();
 if (typeof window !== "undefined") {
  const onResize = () => {
   current = compute();
   listeners.forEach(fn => fn());
  };
  window.addEventListener("resize", onResize, { passive: true });
  window.addEventListener("orientationchange", onResize, { passive: true });
 }
 return {
  get: () => current,
  subscribe: (fn) => { listeners.add(fn); return () => listeners.delete(fn); },
 };
})();

const useViewport = () => {
 const [, force] = useState(0);
 useEffect(() => __viewportStore.subscribe(() => force(n => n + 1)), []);
 return __viewportStore.get();
};

// -------------------------- ICONS (inline Lucide-style at stroke 1.75) --------------------------
const Icon = ({ name, size = 18, color = "currentColor" }) => {
 const paths = {
 "search": <><circle cx="11" cy="11" r="7"/><path d="m20 20-3.5-3.5"/></>,
 "shield-check": <><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z"/><path d="m9 12 2 2 4-4"/></>,
 "check": <path d="M5 12.5 10 17 19 7"/>,
 "x": <><path d="M6 6l12 12"/><path d="M18 6 6 18"/></>,
 "chevron-down": <path d="m6 9 6 6 6-6"/>,
 "chevron-right": <path d="m9 6 6 6-6 6"/>,
 "arrow-right": <><path d="M5 12h14"/><path d="m13 6 6 6-6 6"/></>,
 "filter": <path d="M3 5h18l-7 9v6l-4-2v-4z"/>,
 "globe": <><circle cx="12" cy="12" r="9"/><path d="M3 12h18"/><path d="M12 3a14 14 0 0 1 0 18M12 3a14 14 0 0 0 0 18"/></>,
 "factory": <><path d="M3 21V10l6 4V10l6 4V7l6 3v11Z"/><path d="M3 21h18"/></>,
 "package": <><path d="m3 8 9-5 9 5v8l-9 5-9-5Z"/><path d="M3 8l9 5 9-5"/><path d="M12 13v9"/></>,
 "file-check": <><path d="M14 3H6a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V9Z"/><path d="M14 3v6h6"/><path d="m9 15 2 2 4-4"/></>,
 "anchor": <><circle cx="12" cy="5" r="2"/><path d="M12 7v15"/><path d="M5 12h14"/><path d="M19 15a7 7 0 0 1-14 0"/></>,
 "menu": <><path d="M3 6h18"/><path d="M3 12h18"/><path d="M3 18h18"/></>,
 "external": <><path d="M7 7h10v10"/><path d="M7 17 17 7"/></>,
 };
 return (
 <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke={color} strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" style={{flexShrink:0}}>
 {paths[name]}
 </svg>
 );
};

// -------------------------- BUTTON --------------------------
const Button = ({ variant = "primary", size = "md", leading, trailing, children, ...rest }) => {
 const sizes = {
 sm: { padding: "6px 12px", fontSize: 13 },
 md: { padding: "10px 16px", fontSize: 14 },
 lg: { padding: "14px 22px", fontSize: 15 },
 };
 const variants = {
 primary: { background: "var(--jv-accent-600)", color: "#fff", border: "1px solid var(--jv-accent-600)" },
 secondary: { background: "#fff", color: "var(--jv-navy-800)", border: "1px solid var(--color-border-strong)" },
 ghost: { background: "transparent", color: "var(--jv-navy-800)", border: "1px solid transparent" },
 inverse: { background: "#fff", color: "var(--jv-navy-800)", border: "1px solid #fff" },
 link: { background: "transparent", color: "var(--jv-navy-800)", border: "0", borderBottom: "1px solid var(--color-border)", borderRadius: 0, padding: "4px 0" },
 };
 const [hover, setHover] = useState(false);
 const [press, setPress] = useState(false);
 const hoverStyles = {
 primary: { background: press ? "var(--jv-accent-800)" : "var(--jv-accent-700)" },
 secondary: { background: "var(--jv-ink-50)", borderColor: "var(--jv-ink-400)" },
 ghost: { background: "var(--jv-ink-50)" },
 inverse: { background: "var(--jv-navy-50)" },
 link: { borderBottomColor: "var(--jv-navy-800)" },
 };
 return (
 <button
 {...rest}
 onMouseEnter={() => setHover(true)}
 onMouseLeave={() => { setHover(false); setPress(false); }}
 onMouseDown={() => setPress(true)}
 onMouseUp={() => setPress(false)}
 style={{
 fontFamily: "var(--font-sans)",
 fontWeight: 500,
 lineHeight: 1,
 borderRadius: 6,
 cursor: "pointer",
 display: "inline-flex",
 alignItems: "center",
 gap: 8,
 transition: "background 120ms var(--ease-standard), border-color 120ms var(--ease-standard)",
 ...sizes[size],
 ...variants[variant],
 ...(hover ? hoverStyles[variant] : {}),
 }}
 >
 {leading && <Icon name={leading} size={size === "sm" ? 14 : 16}/>}
 {children}
 {trailing && <Icon name={trailing} size={size === "sm" ? 14 : 16}/>}
 </button>
 );
};

// -------------------------- FORM PRIMITIVES --------------------------
const Field = ({ label, help, error, children }) => (
 <label style={{ display: "flex", flexDirection: "column", gap: 6, flex: 1 }}>
 {label && <span style={{ fontSize: 12, fontWeight: 500, color: "var(--color-fg)" }}>{label}</span>}
 {children}
 {error && <span style={{ fontSize: 12, color: "var(--color-accent)" }}>{error}</span>}
 {!error && help && <span style={{ fontSize: 12, color: "var(--color-fg-muted)" }}>{help}</span>}
 </label>
);

const inputBase = {
 fontFamily: "var(--font-sans)",
 fontSize: 14,
 padding: "9px 12px",
 border: "1px solid var(--color-border)",
 borderRadius: 6,
 background: "#fff",
 color: "var(--color-fg)",
 outline: "none",
 width: "100%",
 boxSizing: "border-box",
};

const Input = (props) => {
 const [focus, setFocus] = useState(false);
 return (
 <input
 {...props}
 onFocus={(e) => { setFocus(true); props.onFocus && props.onFocus(e); }}
 onBlur={(e) => { setFocus(false); props.onBlur && props.onBlur(e); }}
 style={{
 ...inputBase,
 ...(props.style || {}),
 ...(focus ? { borderColor: "var(--jv-navy-500)", boxShadow: "0 0 0 3px rgba(11,42,74,0.18)" } : {}),
 }}
 />
 );
};

const Select = ({ children, ...rest }) => (
 <div style={{ position: "relative", width: "100%" }}>
 <select {...rest} style={{ ...inputBase, appearance: "none", paddingRight: 32 }}>{children}</select>
 <div style={{ position: "absolute", right: 10, top: "50%", transform: "translateY(-50%)", pointerEvents: "none", color: "var(--color-fg-muted)" }}>
 <Icon name="chevron-down" size={16}/>
 </div>
 </div>
);

const Textarea = (props) => (
 <textarea {...props} style={{ ...inputBase, minHeight: 96, fontFamily: "var(--font-sans)", resize: "vertical", ...(props.style || {}) }} />
);

// -------------------------- BADGES / CHIPS --------------------------
const StatusPill = ({ tone = "trust", children }) => {
 const tones = {
 trust: { bg: "var(--jv-trust-50)", fg: "var(--jv-trust-700)", bd: "var(--jv-trust-100)" },
 warn: { bg: "var(--jv-warn-50)", fg: "var(--jv-warn-700)", bd: "var(--jv-warn-100)" },
 danger: { bg: "var(--jv-accent-50)", fg: "var(--jv-accent-700)", bd: "var(--jv-accent-100)" },
 neutral:{ bg: "var(--jv-ink-100)", fg: "var(--jv-ink-700)", bd: "var(--color-border)" },
 };
 const t = tones[tone];
 return (
 <span style={{ display: "inline-flex", alignItems: "center", gap: 6, padding: "3px 9px", background: t.bg, color: t.fg, border: `1px solid ${t.bd}`, borderRadius: 999, fontSize: 12, fontWeight: 500, whiteSpace: "nowrap" }}>
 <span style={{ width: 6, height: 6, borderRadius: 999, background: t.fg, opacity: 0.9 }}/>
 {children}
 </span>
 );
};

const CertTag = ({ children }) => (
 <span style={{ display: "inline-flex", padding: "2px 6px", background: "var(--jv-navy-50)", color: "var(--jv-navy-800)", borderRadius: 4, fontSize: 11, fontWeight: 600, letterSpacing: "0.04em", fontFamily: "var(--font-mono)" }}>{children}</span>
);

const PremiumTag = () => (
 <span style={{ display: "inline-flex", padding: "2px 6px", background: "var(--jv-sand-100)", color: "var(--jv-navy-800)", border: "1px solid var(--jv-sand-200)", borderRadius: 4, fontSize: 11, fontWeight: 600, letterSpacing: "0.04em", fontFamily: "var(--font-mono)" }}>PREMIUM</span>
);

const CountryChip = ({ country, label }) => (
 <span style={{ display: "inline-flex", alignItems: "center", gap: 6, fontSize: 12, color: "var(--color-fg-muted)" }}>
 <img src={`assets/flag-${country}.svg`} width="14" height="11" alt={country}/>
 {label || (country === "vn" ? "Vietnam" : "Japan")}
 </span>
);

const Eyebrow = ({ children, style }) => (
 <div style={{ fontSize: 12, letterSpacing: "0.08em", textTransform: "uppercase", fontWeight: 500, color: "var(--color-fg-muted)", ...style }}>{children}</div>
);

const Mono = ({ children, style, weight = 500 }) => (
 <span style={{ fontFamily: "var(--font-mono)", fontWeight: weight, ...style }}>{children}</span>
);

// -------------------------- EXPORT --------------------------
Object.assign(window, { Icon, Button, Field, Input, Select, Textarea, StatusPill, CertTag, PremiumTag, CountryChip, Eyebrow, Mono, useViewport });
