// Reusable UI primitives — Field, Select, Slider, Section, Card, Pill, IconButton
const { useState, useEffect, useRef, useMemo } = React;

// ---------- Format helpers ----------
function fmtMoney(n, symbol = "$", locale = "en-US", digits = 2) {
  if (!isFinite(n)) return "—";
  const abs = Math.abs(n);
  const s = abs.toLocaleString(locale, { minimumFractionDigits: digits, maximumFractionDigits: digits });
  return (n < 0 ? "−" : "") + symbol + s;
}
function fmtPct(n, digits = 1) {
  if (!isFinite(n)) return "—";
  return (n * 100).toFixed(digits) + "%";
}
function fmtNum(n, digits = 0) {
  if (!isFinite(n)) return "—";
  return n.toLocaleString("en-US", { minimumFractionDigits: digits, maximumFractionDigits: digits });
}

// ---------- Card ----------
function Card({ title, right, children, padded = true, className = "" }) {
  return (
    <div className={"card " + className}>
      {(title || right) && (
        <div className="card-head">
          <div className="card-title">{title}</div>
          <div className="card-right">{right}</div>
        </div>
      )}
      <div className={padded ? "card-body" : "card-body bare"}>{children}</div>
    </div>
  );
}

// ---------- Collapsible left-pane section ----------
function Section({ title, kicker, icon, defaultOpen = true, badge, children }) {
  const [open, setOpen] = useState(defaultOpen);
  return (
    <div className={"section " + (open ? "open" : "closed")}>
      <button className="section-head" onClick={() => setOpen(o => !o)}>
        <span className="section-icon">{icon}</span>
        <span className="section-title">{title}</span>
        {kicker && <span className="section-kicker">{kicker}</span>}
        {badge && <span className="section-badge">{badge}</span>}
        <span className="section-chev" aria-hidden="true">{open ? "▾" : "▸"}</span>
      </button>
      {open && <div className="section-body">{children}</div>}
    </div>
  );
}

// ---------- Field row ----------
function Field({ label, sublabel, hint, suffix, prefix, children, full, auto }) {
  return (
    <label className={"field " + (full ? "full " : "") + (auto ? "auto " : "")}>
      <div className="field-label">
        <span>{label}</span>
        {auto && <span className="field-auto-pill">auto</span>}
      </div>
      {sublabel && <div className="field-sublabel">{sublabel}</div>}
      <div className="field-input-wrap">
        {prefix && <span className="field-prefix">{prefix}</span>}
        {children}
        {suffix && <span className="field-suffix">{suffix}</span>}
      </div>
      {hint && <div className="field-hint">{hint}</div>}
    </label>
  );
}

// ---------- Number input ----------
function NumberInput({ value, onChange, step = 1, min, max, placeholder }) {
  return (
    <input
      type="number"
      className="num-input"
      value={value === "" || value === null || value === undefined ? "" : value}
      step={step}
      min={min}
      max={max}
      placeholder={placeholder}
      onChange={e => {
        const v = e.target.value;
        onChange(v === "" ? "" : parseFloat(v));
      }}
    />
  );
}

// ---------- Text input ----------
function TextInput({ value, onChange, placeholder, mono }) {
  return (
    <input
      type="text"
      className={"text-input " + (mono ? "mono" : "")}
      value={value || ""}
      placeholder={placeholder}
      onChange={e => onChange(e.target.value)}
    />
  );
}

// ---------- Select ----------
function Select({ value, onChange, options, groupBy }) {
  // options: [{value, label}]
  if (groupBy) {
    const groups = {};
    options.forEach(o => {
      const g = o.group || "Other";
      groups[g] = groups[g] || [];
      groups[g].push(o);
    });
    return (
      <select className="select" value={value} onChange={e => onChange(e.target.value)}>
        {Object.entries(groups).map(([g, items]) => (
          <optgroup key={g} label={g}>
            {items.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
          </optgroup>
        ))}
      </select>
    );
  }
  return (
    <select className="select" value={value} onChange={e => onChange(e.target.value)}>
      {options.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
    </select>
  );
}

// ---------- Slider with live value (optionally editable) ----------
function Slider({ value, onChange, min = 0, max = 100, step = 1, suffix = "", editable = false }) {
  return (
    <div className="slider-row">
      <input
        type="range"
        className="slider"
        min={min} max={max} step={step}
        value={value}
        onChange={e => onChange(parseFloat(e.target.value))}
      />
      {editable ? (
        <div className="slider-readout slider-readout-edit">
          <input
            type="number"
            className="slider-num"
            value={value === "" || value === null || value === undefined ? "" : value}
            min={min}
            max={max}
            step={step}
            onChange={e => {
              const v = e.target.value;
              onChange(v === "" ? 0 : Math.max(min, Math.min(max, parseFloat(v))));
            }}
          />
          {suffix && <span className="slider-suffix">{suffix.trim()}</span>}
        </div>
      ) : (
        <div className="slider-readout">{value}{suffix}</div>
      )}
    </div>
  );
}

// ---------- Toggle ----------
function Toggle({ checked, onChange, label }) {
  return (
    <button className={"toggle " + (checked ? "on" : "")} onClick={() => onChange(!checked)}>
      <span className="toggle-track"><span className="toggle-knob" /></span>
      {label && <span className="toggle-label">{label}</span>}
    </button>
  );
}

// ---------- Pill ----------
function Pill({ children, tone = "neutral", icon }) {
  return (
    <span className={"pill pill-" + tone}>
      {icon && <span className="pill-icon">{icon}</span>}
      {children}
    </span>
  );
}

// ---------- Product image placeholder ----------
function ProductGlyph({ kind = "bottle", size = 56 }) {
  // Minimal line-art placeholders
  const stroke = "#0F1B2D";
  const accent = "#FF9900";
  const sw = 1.6;
  const glyphs = {
    bottle: (
      <g fill="none" stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
        <rect x="18" y="14" width="20" height="34" rx="3" />
        <rect x="22" y="9" width="12" height="5" rx="1" />
        <path d="M22 22h12" stroke={accent} />
      </g>
    ),
    earbuds: (
      <g fill="none" stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
        <rect x="10" y="22" width="14" height="22" rx="6" />
        <rect x="32" y="22" width="14" height="22" rx="6" />
        <circle cx="17" cy="29" r="1.5" fill={accent} stroke="none" />
        <circle cx="39" cy="29" r="1.5" fill={accent} stroke="none" />
      </g>
    ),
    lamp: (
      <g fill="none" stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
        <path d="M16 16l24 6" />
        <path d="M14 12l8 10" stroke={accent} />
        <path d="M28 18v28" />
        <rect x="22" y="46" width="14" height="3" rx="1" />
      </g>
    ),
    yoga: (
      <g fill="none" stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
        <rect x="8" y="20" width="40" height="20" rx="3" />
        <path d="M14 26c4-4 12-4 16 0s12 4 16 0" stroke={accent} />
      </g>
    ),
    serum: (
      <g fill="none" stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
        <rect x="22" y="20" width="14" height="26" rx="2" />
        <rect x="25" y="14" width="8" height="6" rx="1" />
        <path d="M25 28h8" stroke={accent} />
      </g>
    ),
    tool: (
      <g fill="none" stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
        <path d="M12 44l20-20" />
        <path d="M28 16l12 12-4 4-12-12z" stroke={accent} />
        <circle cx="34" cy="22" r="2" />
      </g>
    ),
    box: (
      <g fill="none" stroke={stroke} strokeWidth={sw} strokeLinecap="round" strokeLinejoin="round">
        <path d="M10 20l18-8 18 8v20l-18 8-18-8V20z" />
        <path d="M10 20l18 8 18-8" />
        <path d="M28 28v20" />
        <path d="M19 16l18 8" stroke={accent} />
      </g>
    ),
  };
  return (
    <svg className="product-glyph" width={size} height={size} viewBox="0 0 56 56">
      {glyphs[kind] || glyphs.box}
    </svg>
  );
}

// Export
window.UI = { Card, Section, Field, NumberInput, TextInput, Select, Slider, Toggle, Pill, ProductGlyph, fmtMoney, fmtPct, fmtNum };
