// Shared UI primitives — pill, button, input, etc.
// Civic-tech aesthetic: off-white, dark text, navy accent, plain sans-serif.

const Pill = ({ tone = "neutral", children, mono = false }) => {
  const map = {
    neutral: { bg: "var(--pill-bg)",    fg: "var(--pill-fg)",    bd: "var(--pill-bd)" },
    info:    { bg: "var(--pill-info-bg)",    fg: "var(--pill-info-fg)",    bd: "var(--pill-info-bd)" },
    ok:      { bg: "var(--pill-ok-bg)",      fg: "var(--pill-ok-fg)",      bd: "var(--pill-ok-bd)" },
    warn:    { bg: "var(--pill-warn-bg)",    fg: "var(--pill-warn-fg)",    bd: "var(--pill-warn-bd)" },
    danger:  { bg: "var(--pill-danger-bg)",  fg: "var(--pill-danger-fg)",  bd: "var(--pill-danger-bd)" }
  };
  const c = map[tone] || map.neutral;
  return (
    <span style={{
      display: "inline-flex",
      alignItems: "center",
      gap: 6,
      background: c.bg,
      color: c.fg,
      border: `1px solid ${c.bd}`,
      padding: "2px 8px",
      borderRadius: 2,
      fontSize: 12,
      lineHeight: "18px",
      fontFamily: mono ? "var(--font-mono)" : "inherit",
      fontWeight: 500,
      whiteSpace: "nowrap"
    }}>
      {tone !== "neutral" && (
        <span style={{
          width: 6, height: 6, borderRadius: "50%",
          background: c.fg,
          display: "inline-block"
        }} />
      )}
      {children}
    </span>
  );
};

const StatusPill = ({ status }) => {
  const meta = window.STATUS_META[status] || { label: status, tone: "neutral" };
  return <Pill tone={meta.tone}>{meta.label}</Pill>;
};

const Button = ({ variant = "primary", children, onClick, disabled, icon, full, size = "md", type = "button" }) => {
  const styles = {
    primary:   { bg: "var(--accent)",        fg: "#fff",             bd: "var(--accent)" },
    secondary: { bg: "var(--surface)",       fg: "var(--text)",      bd: "var(--rule)" },
    ghost:     { bg: "transparent",          fg: "var(--text)",      bd: "transparent" },
    danger:    { bg: "var(--surface)",       fg: "var(--danger-fg)", bd: "var(--danger-fg)" }
  };
  const s = styles[variant];
  const pad = size === "sm" ? "4px 10px" : "8px 14px";
  const fs = size === "sm" ? 13 : 14;
  return (
    <button
      type={type}
      onClick={onClick}
      disabled={disabled}
      style={{
        background: s.bg,
        color: s.fg,
        border: `1px solid ${s.bd}`,
        padding: pad,
        fontSize: fs,
        fontFamily: "inherit",
        fontWeight: 500,
        borderRadius: 2,
        cursor: disabled ? "not-allowed" : "pointer",
        opacity: disabled ? 0.5 : 1,
        display: "inline-flex",
        alignItems: "center",
        gap: 8,
        width: full ? "100%" : "auto",
        justifyContent: full ? "center" : "flex-start",
        transition: "background 120ms ease, transform 80ms ease",
        boxShadow: variant === "primary" ? "0 1px 0 rgba(0,0,0,0.05), inset 0 -2px 0 rgba(0,0,0,0.1)" : "none"
      }}
      onMouseDown={(e) => { if (!disabled) e.currentTarget.style.transform = "translateY(1px)"; }}
      onMouseUp={(e) =>   { e.currentTarget.style.transform = "translateY(0)"; }}
      onMouseLeave={(e) => { e.currentTarget.style.transform = "translateY(0)"; }}
    >
      {icon && <span style={{ display: "inline-flex" }}>{icon}</span>}
      {children}
    </button>
  );
};

const Field = ({ label, hint, children, error }) => (
  <label style={{ display: "block", marginBottom: 16 }}>
    <div style={{ fontSize: 13, fontWeight: 600, color: "var(--text)", marginBottom: 4 }}>{label}</div>
    {hint && <div style={{ fontSize: 12, color: "var(--muted)", marginBottom: 6 }}>{hint}</div>}
    {children}
    {error && <div style={{ fontSize: 12, color: "var(--danger-fg)", marginTop: 4 }}>{error}</div>}
  </label>
);

const TextInput = ({ value, onChange, placeholder, mono, ...rest }) => (
  <input
    type="text"
    value={value}
    onChange={(e) => onChange && onChange(e.target.value)}
    placeholder={placeholder}
    style={{
      width: "100%",
      padding: "8px 10px",
      fontSize: 14,
      fontFamily: mono ? "var(--font-mono)" : "inherit",
      color: "var(--text)",
      background: "var(--surface)",
      border: "1px solid var(--rule)",
      borderRadius: 2,
      outline: "none",
      boxShadow: "inset 0 1px 0 rgba(0,0,0,0.03)"
    }}
    onFocus={(e) => e.currentTarget.style.borderColor = "var(--accent)"}
    onBlur={(e) => e.currentTarget.style.borderColor = "var(--rule)"}
    {...rest}
  />
);

const TextArea = ({ value, onChange, placeholder, rows = 6, mono }) => (
  <textarea
    value={value}
    onChange={(e) => onChange && onChange(e.target.value)}
    placeholder={placeholder}
    rows={rows}
    style={{
      width: "100%",
      padding: "10px 12px",
      fontSize: 14,
      fontFamily: mono ? "var(--font-mono)" : "inherit",
      lineHeight: 1.55,
      color: "var(--text)",
      background: "var(--surface)",
      border: "1px solid var(--rule)",
      borderRadius: 2,
      outline: "none",
      resize: "vertical",
      boxShadow: "inset 0 1px 0 rgba(0,0,0,0.03)"
    }}
    onFocus={(e) => e.currentTarget.style.borderColor = "var(--accent)"}
    onBlur={(e) => e.currentTarget.style.borderColor = "var(--rule)"}
  />
);

const Select = ({ value, onChange, children }) => (
  <select
    value={value}
    onChange={(e) => onChange && onChange(e.target.value)}
    style={{
      width: "100%",
      padding: "8px 10px",
      fontSize: 14,
      fontFamily: "inherit",
      color: "var(--text)",
      background: "var(--surface)",
      border: "1px solid var(--rule)",
      borderRadius: 2,
      outline: "none"
    }}
  >
    {children}
  </select>
);

const Card = ({ children, pad = 20, style }) => (
  <div style={{
    background: "var(--surface)",
    border: "1px solid var(--rule)",
    borderRadius: 2,
    padding: pad,
    ...style
  }}>{children}</div>
);

const SectionTitle = ({ children, action, sub }) => (
  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-end", marginBottom: 16, gap: 16 }}>
    <div>
      <h2 style={{ margin: 0, fontSize: 22, fontWeight: 700, letterSpacing: "-0.01em", color: "var(--text)" }}>{children}</h2>
      {sub && <div style={{ fontSize: 13, color: "var(--muted)", marginTop: 4 }}>{sub}</div>}
    </div>
    {action}
  </div>
);

const Bar = ({ pct, tone = "info" }) => {
  const colorMap = {
    info:   "var(--accent)",
    ok:     "var(--ok-fg)",
    warn:   "var(--warn-fg)",
    danger: "var(--danger-fg)"
  };
  return (
    <div style={{ height: 6, background: "var(--track)", borderRadius: 2, overflow: "hidden" }}>
      <div style={{ width: `${Math.min(100, Math.max(0, pct))}%`, height: "100%", background: colorMap[tone] || colorMap.info, transition: "width 320ms ease" }} />
    </div>
  );
};

// Tiny inline icons (1.4em stroke icons — minimal, civic feel)
const Ico = {
  Plus: () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M7 2v10M2 7h10"/></svg>,
  Send: () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M2 12L12 7 2 2l1.5 5L2 12z"/></svg>,
  Check:() => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.75"><path d="M2.5 7.5l3 3 6-7"/></svg>,
  Edit: () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M2 12h3l7-7-3-3-7 7v3z"/></svg>,
  Search:() => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><circle cx="6" cy="6" r="4"/><path d="M12 12L9 9"/></svg>,
  Filter:() => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M2 3h10l-4 5v4l-2-1V8L2 3z"/></svg>,
  Arrow:() => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M2 7h10M8 3l4 4-4 4"/></svg>,
  Dot:  () => <svg width="14" height="14" viewBox="0 0 14 14"><circle cx="7" cy="7" r="2" fill="currentColor"/></svg>,
  Mail: () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><rect x="2" y="3" width="10" height="8" rx="0.5"/><path d="M2 4l5 4 5-4"/></svg>,
  Doc:  () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M3 1h6l3 3v9H3z"/><path d="M9 1v3h3"/></svg>,
  Eye:  () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M1 7s2-4 6-4 6 4 6 4-2 4-6 4-6-4-6-4z"/><circle cx="7" cy="7" r="1.5"/></svg>,
  Warn: () => <svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" strokeWidth="1.5"><path d="M7 2l6 10H1L7 2z"/><path d="M7 6v3M7 10.5v.5"/></svg>
};

Object.assign(window, { Pill, StatusPill, Button, Field, TextInput, TextArea, Select, Card, SectionTitle, Bar, Ico });
