// Shared UI primitives + icons + helpers. Exports to window for other babel scripts.
const { useState, useEffect, useRef } = React;

/* ---------- Lucide-style icons ---------- */
const ICONS = {
  plus: "M5 12h14M12 5v14",
  check: "M20 6 9 17l-5-5",
  search: "M21 21l-4.3-4.3M11 19a8 8 0 1 0 0-16 8 8 0 0 0 0 16Z",
  x: "M18 6 6 18M6 6l12 12",
  chevDown: "m6 9 6 6 6-6",
  chevRight: "m9 18 6-6-6-6",
  chevLeft: "m15 18-6-6 6-6",
  phone: "M13.8 10.2a8.5 8.5 0 0 0 3.7 3.7l1.2-1.2a1 1 0 0 1 1-.24 11 11 0 0 0 3.5.56 1 1 0 0 1 1 1V18a1 1 0 0 1-1 1A16 16 0 0 1 3 5a1 1 0 0 1 1-1h3.2a1 1 0 0 1 1 1 11 11 0 0 0 .56 3.5 1 1 0 0 1-.24 1Z",
  mail: "M4 5h16a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V6a1 1 0 0 1 1-1Zm0 1.5 8 5.5 8-5.5",
  mapPin: "M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z|M12 12a2.5 2.5 0 1 0 0-5 2.5 2.5 0 0 0 0 5Z",
  user: "M12 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8ZM5 21a7 7 0 0 1 14 0",
  calendar: "M7 3v3M17 3v3M4 8h16M5 6h14a1 1 0 0 1 1 1v12a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1Z",
  clock: "M12 21a9 9 0 1 0 0-18 9 9 0 0 0 0 18ZM12 7v5l3 2",
  dollar: "M12 2v20M17 5.5C17 4 14.8 3 12 3S7 4 7 6s2.2 3 5 3.5 5 1.5 5 3.5-2.2 3-5 3-5-1-5-2.5",
  message: "M21 12a8 8 0 0 1-11.5 7.2L3 21l1.8-6.5A8 8 0 1 1 21 12Z",
  filter: "M3 5h18l-7 8v5l-4 2v-7L3 5Z",
  logout: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9",
  list: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01",
  filePlus: "M14 3v4a1 1 0 0 0 1 1h4M14 3H6a1 1 0 0 0-1 1v16a1 1 0 0 0 1 1h12a1 1 0 0 0 1-1V8l-5-5ZM12 11v6M9 14h6",
  alert: "M12 9v4M12 17h.01M10.3 3.9 1.8 18a2 2 0 0 0 1.7 3h17a2 2 0 0 0 1.7-3L13.7 3.9a2 2 0 0 0-3.4 0Z",
  shield: "M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10Z",
  inbox: "M22 12h-6l-2 3h-4l-2-3H2M5 5h14a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2Z",
  arrowRight: "M5 12h14M13 6l6 6-6 6",
  sparkle: "M12 3l1.8 5.2L19 10l-5.2 1.8L12 17l-1.8-5.2L5 10l5.2-1.8L12 3Z",
  lock: "M6 10V8a6 6 0 1 1 12 0v2M5 10h14a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1v-9a1 1 0 0 1 1-1Z",
  eye: "M2 12s4-7 10-7 10 7 10 7-4 7-10 7-10-7-10-7Z|M12 15a3 3 0 1 0 0-6 3 3 0 0 0 0 6Z",
  building: "M3 21h18M5 21V5a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v16M13 9h4a1 1 0 0 1 1 1v11M8 8h2M8 12h2M8 16h2",
  refresh: "M21 12a9 9 0 1 1-3-6.7L21 8M21 3v5h-5"
};
function Icon({ name, size = 18, stroke = 2, className = "", style = {} }) {
  const d = ICONS[name] || "";
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none"
    stroke="currentColor" strokeWidth={stroke} strokeLinecap="round" strokeLinejoin="round"
    className={className} style={style} aria-hidden="true">
      {d.split("|").map((p, i) => <path key={i} d={p} />)}
    </svg>);

}

/* ---------- helpers ---------- */
const MONTHS = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
function fmtDate(iso) {
  if (!iso) return "Nil";
  const d = new Date(iso);
  return `${MONTHS[d.getMonth()]} ${d.getDate()}, ${d.getFullYear()}`;
}
function fmtDateTime(iso) {
  if (!iso) return "Nil";
  const d = new Date(iso);
  let h = d.getHours(),ap = h >= 12 ? "PM" : "AM";
  h = h % 12 || 12;
  const m = String(d.getMinutes()).padStart(2, "0");
  return `${MONTHS[d.getMonth()]} ${d.getDate()}, ${h}:${m} ${ap}`;
}
function relTime(iso) {
  if (!iso) return "";
  const now = new Date();
  const d = new Date(iso);
  const mins = Math.round((now - d) / 60000);
  if (mins < 1) return "just now";
  if (mins < 60) return `${mins}m ago`;
  const hrs = Math.round(mins / 60);
  if (hrs < 24) return `${hrs}h ago`;
  const days = Math.round(hrs / 24);
  if (days < 30) return `${days}d ago`;
  return fmtDate(iso);
}
function formatPhone(v) {
  const d = (v || "").replace(/\D/g, "").slice(0, 10);
  if (!d) return "";
  if (d.length < 4) return "(" + d;
  if (d.length < 7) return "(" + d.slice(0, 3) + ") " + d.slice(3);
  return "(" + d.slice(0, 3) + ") " + d.slice(3, 6) + "-" + d.slice(6);
}

/* ---------- CustomSelect (styled dropdown / combobox) ---------- */
function CustomSelect({ value, onChange, options, placeholder = "Select", error, searchable = false }) {
  const [open, setOpen] = useState(false);
  const [q, setQ] = useState("");
  const ref = useRef(null);
  useEffect(() => {
    function h(e) {if (ref.current && !ref.current.contains(e.target)) setOpen(false);}
    function k(e) {if (e.key === "Escape") setOpen(false);}
    document.addEventListener("mousedown", h);
    document.addEventListener("keydown", k);
    return () => {document.removeEventListener("mousedown", h);document.removeEventListener("keydown", k);};
  }, []);
  const opts = options.map((o) => typeof o === "object" ? o : { value: o, label: o });
  const sel = opts.find((o) => o.value === value);
  const filtered = searchable && q ? opts.filter((o) => o.label.toLowerCase().includes(q.toLowerCase())) : opts;
  return (
    <div ref={ref} style={{ position: "relative", width: "100%" }}>
      <button type="button" className={"input" + (error ? " err" : "")} onClick={() => setOpen((o) => !o)}
      style={{ display: "flex", alignItems: "center", justifyContent: "space-between", cursor: "pointer",
        textAlign: "left", gap: 8, borderColor: open ? "var(--accent)" : undefined,
        boxShadow: open ? "0 0 0 3px #10295A1f" : undefined }}>
        <span style={{ color: sel ? "var(--foreground)" : "#98A0AB", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", fontWeight: sel ? 600 : 500 }}>
          {sel ? sel.short || sel.label : placeholder}
        </span>
        <Icon name="chevDown" size={16} style={{ color: "var(--muted)", transform: open ? "rotate(180deg)" : "none", transition: "transform .18s ease", flexShrink: 0 }} />
      </button>
      {open &&
      <div className="thin-scroll" style={{ position: "absolute", top: "calc(100% + 6px)", left: 0, width: "max(100%, 220px)",
        background: "#fff", border: "1px solid var(--border)", borderRadius: 12, boxShadow: "0 14px 36px #10295A24",
        zIndex: 80, padding: 6, maxHeight: 296, overflowY: "auto", animation: "fadeUp .16s ease both" }}>
          {searchable &&
        <div style={{ position: "sticky", top: -6, background: "#fff", padding: "0 0 6px", marginBottom: 2, zIndex: 1 }}>
              <div style={{ position: "relative" }}>
                <Icon name="search" size={15} style={{ position: "absolute", left: 11, top: 11, color: "var(--muted)" }} />
                <input autoFocus value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search..."
            style={{ width: "100%", height: 38, borderRadius: 9, border: "1px solid var(--border)", padding: "0 10px 0 33px",
              fontFamily: "inherit", fontSize: 13.5, outline: "none", background: "#FBFCFD" }} />
              </div>
            </div>
        }
          {filtered.length === 0 && <div style={{ padding: "12px", color: "var(--muted)", fontSize: 13 }}>No matches</div>}
          {filtered.map((o) => {
          const on = o.value === value;
          return (
            <button key={o.value} type="button" onClick={() => {onChange(o.value);setOpen(false);setQ("");}}
            style={{ width: "100%", display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8, border: "none",
              cursor: "pointer", fontFamily: "inherit", fontSize: 13.5, fontWeight: on ? 700 : 500,
              color: on ? "var(--accent)" : "var(--label-2)", background: on ? "var(--accent-soft)" : "transparent",
              padding: "9px 11px", borderRadius: 8, textAlign: "left" }}
            onMouseEnter={(e) => {if (!on) e.currentTarget.style.background = "#00000006";}}
            onMouseLeave={(e) => {if (!on) e.currentTarget.style.background = "transparent";}}>
                {o.label}{on && <Icon name="check" size={15} stroke={2.5} />}
              </button>);

        })}
        </div>
      }
    </div>);

}

/* ---------- StatusBadge ---------- */
const TONE_VARS = {
  neutral: { fg: "var(--st-neutral-fg)", bg: "var(--st-neutral-bg)", dot: "#98A0AB" },
  blue: { fg: "var(--st-blue-fg)", bg: "var(--st-blue-bg)", dot: "#1570EF" },
  mid: { fg: "var(--st-mid-fg)", bg: "var(--st-mid-bg)", dot: "#10295A" },
  high: { fg: "var(--st-high-fg)", bg: "var(--st-high-bg)", dot: "#1A9175" },
  low: { fg: "var(--st-low-fg)", bg: "var(--st-low-bg)", dot: "#DB1263" }
};
function StatusBadge({ status }) {
  const meta = window.ROA_DATA.STATUS[status] || { tone: "neutral", label: status };
  const t = TONE_VARS[meta.tone];
  return (
    <span className="badge" style={{ color: t.fg, background: t.bg }}>
      <span className="dot" style={{ background: t.dot }}></span>{meta.label}
    </span>);

}

/* ---------- TypeChip ---------- */
const TYPE_STYLE = {
  Buy: { c: "var(--blue)", b: "#CFE0FB" },
  Sell: { c: "var(--emerald)", b: "#C3E5DC" },
  Lease: { c: "#7A4FD0", b: "#DDD2F4" }
};
function TypeChip({ t }) {
  const s = TYPE_STYLE[t] || { c: "var(--label-2)", b: "var(--border)" };
  return <span className="tchip" style={{ color: s.c, borderColor: s.b, background: "#fff" }}>{t}</span>;
}

/* ---------- Avatar ---------- */
function Avatar({ agent, size = 32 }) {
  if (!agent) {
    return (
      <span style={{ width: size, height: size, borderRadius: 99, background: "#F1F2F4",
        display: "grid", placeItems: "center", color: "#98A0AB", flexShrink: 0 }}>
        <Icon name="user" size={size * 0.5} stroke={2.2} />
      </span>);

  }
  const hue = agent.initials.charCodeAt(0) * 13 % 360;
  return (
    <span style={{ width: size, height: size, borderRadius: 99, flexShrink: 0,
      background: `oklch(0.62 0.11 ${hue})`, color: "#fff",
      display: "grid", placeItems: "center", fontSize: size * 0.4, fontWeight: 700 }}>
      {agent.initials}
    </span>);

}

/* ---------- Checkbox ---------- */
function Checkbox({ checked, onChange, label }) {
  return (
    <label className="checkbox">
      <input type="checkbox" checked={checked} onChange={(e) => onChange(e.target.checked)} />
      <span className="box"><Icon name="check" size={13} stroke={3} style={{ color: "#fff" }} /></span>
      {label && <span style={{ fontWeight: 500, color: "var(--foreground)" }}>{label}</span>}
    </label>);

}

/* ---------- Segmented ---------- */
function Segmented({ options, value, onChange, emerald = false }) {
  return (
    <div className="seg" role="tablist">
      {options.map((o) =>
      <button key={o} type="button" role="tab"
      className={"seg-opt" + (value === o ? " on" + (emerald ? " on-emerald" : "") : "")}
      onClick={() => onChange(o)}>{o}</button>
      )}
    </div>);

}

/* ---------- Field wrapper ---------- */
function Field({ label, required, optional, error, children, hint }) {
  return (
    <div>
      {label &&
      <label className="field-label">
          {label}{required && <span className="req">*</span>}
          {optional && <span className="opt">optional</span>}
        </label>
      }
      {children}
      {hint && !error && <div style={{ fontSize: 12, color: "var(--muted)", marginTop: 6 }}>{hint}</div>}
      {error && <div className="err-msg"><Icon name="alert" size={13} stroke={2.2} />{error}</div>}
    </div>);

}

/* ---------- Toast host ---------- */
function ToastHost({ toasts }) {
  return (
    <div style={{ position: "fixed", bottom: 24, left: "50%", transform: "translateX(-50%)",
      display: "flex", flexDirection: "column", gap: 10, zIndex: 9000, alignItems: "center" }}>
      {toasts.map((t) =>
      <div key={t.id} style={{ animation: "toastIn .32s cubic-bezier(.2,.8,.3,1) both",
        background: "#fff", boxShadow: "0 12px 36px #10295A22, 0 2px 8px #0000000f",
        borderRadius: 12, padding: "13px 18px 13px 14px", display: "flex", alignItems: "center", gap: 11,
        border: "1px solid var(--border)", minWidth: 280 }}>
          <span style={{ width: 26, height: 26, borderRadius: 99, background: "var(--st-high-bg)",
          display: "grid", placeItems: "center", color: "var(--emerald)", flexShrink: 0 }}>
            <Icon name="check" size={15} stroke={3} />
          </span>
          <div>
            <div style={{ fontWeight: 600, fontSize: 14 }}>{t.title}</div>
            {t.sub && <div style={{ fontSize: 12.5, color: "var(--muted)", marginTop: 1 }}>{t.sub}</div>}
          </div>
        </div>
      )}
    </div>);

}

/* ---------- Brand marks ---------- */
function RoaLogo({ size = 34, onDark = false }) {
  return (
    <span style={{ width: size, height: size, borderRadius: size * 0.27, flexShrink: 0,
      background: onDark ? "#fff" : "var(--navy)", display: "grid", placeItems: "center",
      boxShadow: onDark ? "none" : "0 1px 2px #10295A33" }}>
      <span style={{ fontWeight: 800, color: onDark ? "var(--navy)" : "#fff", fontSize: size * 0.5, letterSpacing: "-.04em" }}>R</span>
    </span>);

}
function MainstayLogo({ size = 34 }) {
  return (
    <span style={{ width: size, height: size, borderRadius: size * 0.27, flexShrink: 0, position: "relative",
      background: "linear-gradient(150deg, #1FA384, #16806a)", display: "grid", placeItems: "center",
      boxShadow: "0 1px 2px #1A917533" }}>
      <span style={{ fontWeight: 800, color: "#fff", fontSize: size * 0.5, letterSpacing: "-.04em" }}>M</span>
    </span>);

}

/* ---------- PreQualPill ---------- */
function PreQualPill({ v }) {
  const map = {
    "Yes": { fg: "var(--emerald)", bg: "var(--st-high-bg)" },
    "No": { fg: "var(--desc)", bg: "var(--st-neutral-bg)" },
    "Not sure": { fg: "var(--blue)", bg: "var(--st-blue-bg)" }
  };
  const s = map[v] || map["Not sure"];
  return <span style={{ fontSize: 12.5, fontWeight: 600, color: s.fg, background: s.bg, padding: "3px 10px", borderRadius: 99, whiteSpace: "nowrap" }}>{v}</span>;
}

Object.assign(window, {
  Icon, ICONS, fmtDate, fmtDateTime, relTime, MONTHS, formatPhone, CustomSelect, RoaLogo, MainstayLogo,
  StatusBadge, TypeChip, Avatar, Checkbox, Segmented, Field, ToastHost, TONE_VARS, TYPE_STYLE, PreQualPill
});