// Shared UI atoms for app + admin

const { useState: useStateU, useEffect: useEffectU } = React;

const Dot = ({ c = "var(--ink-3)", size = 6 }) => (
  <span style={{ display: "inline-block", width: size, height: size, borderRadius: 999, background: c, verticalAlign: "middle" }} />
);

const Pill = ({ children, tone = "ink", small }) => {
  const tones = {
    ink:    { bg: "var(--bg-2)",     fg: "var(--ink-2)",  bd: "var(--line)" },
    accent: { bg: "var(--accent-soft)", fg: "var(--accent)", bd: "transparent" },
    warn:   { bg: "var(--warn-soft)", fg: "var(--warn)",   bd: "transparent" },
    bad:    { bg: "color-mix(in oklab, var(--bad) 14%, var(--bg))", fg: "var(--bad)", bd: "transparent" },
    ghost:  { bg: "transparent", fg: "var(--ink-2)", bd: "var(--line)" },
  }[tone];
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 5,
      padding: small ? "2px 7px" : "3px 9px", borderRadius: 999,
      background: tones.bg, color: tones.fg, border: `1px solid ${tones.bd}`,
      fontFamily: "var(--mono)", fontSize: small ? 10 : 11, letterSpacing: 0.02,
    }}>{children}</span>
  );
};

const Btn = ({ children, variant = "primary", onClick, small, disabled, icon, title }) => {
  const pad = small ? "6px 11px" : "8px 14px";
  const fs = small ? 12 : 13;
  const variants = {
    primary: { background: "var(--ink)", color: "var(--bg)", border: "1px solid var(--ink)" },
    ghost: { background: "transparent", color: "var(--ink)", border: "1px solid var(--line)" },
    soft:  { background: "var(--bg-2)", color: "var(--ink)", border: "1px solid var(--line-2)" },
    danger: { background: "transparent", color: "var(--bad)", border: "1px solid var(--bad)" },
  };
  return (
    <button title={title} onClick={onClick} disabled={disabled} style={{
      display: "inline-flex", alignItems: "center", gap: 6,
      padding: pad, borderRadius: 6, fontSize: fs, fontWeight: 500,
      cursor: disabled ? "not-allowed" : "pointer",
      opacity: disabled ? 0.5 : 1,
      transition: "all 100ms ease",
      ...variants[variant],
    }}>{icon && <span style={{ fontFamily: "var(--mono)", fontSize: fs }}>{icon}</span>}{children}</button>
  );
};

const Card = ({ children, pad = 18, title, action, compact }) => (
  <div style={{
    background: "var(--bg)", border: "1px solid var(--line)", borderRadius: 12,
    overflow: "hidden",
  }}>
    {title && (
      <div style={{
        padding: compact ? "10px 16px" : "14px 18px",
        borderBottom: "1px solid var(--line-2)",
        background: "var(--bg-2)",
        display: "flex", alignItems: "center", justifyContent: "space-between",
      }}>
        <div style={{ fontSize: 13, fontWeight: 500 }}>{title}</div>
        {action}
      </div>
    )}
    <div style={{ padding: pad }}>{children}</div>
  </div>
);

const Stat = ({ value, label, sub, tone }) => (
  <div style={{
    padding: 18, borderRadius: 12, background: "var(--bg)", border: "1px solid var(--line)",
  }}>
    <div className="kicker" style={{ marginBottom: 10 }}>{label}</div>
    <div style={{ fontSize: 30, fontWeight: 500, fontFamily: "var(--mono)", color: tone || "var(--ink)", letterSpacing: -0.01 }}>{value}</div>
    {sub && <div style={{ fontSize: 12, color: "var(--ink-3)", marginTop: 6 }}>{sub}</div>}
  </div>
);

// WideWired mark — inline SVG: two brackets flanking a filled square.
// The whole mark scales with `size` (height in px).
const LogoMark = ({ size = 28, showWord = true }) => {
  const [src, setSrc] = React.useState(() => {
    const t = typeof document !== "undefined" ? document.documentElement.dataset.theme : "light";
    return t === "dark" ? "assets/widewired-logo-white.svg" : "assets/widewired-logo-ink.svg";
  });
  React.useEffect(() => {
    const update = () => {
      const t = document.documentElement.dataset.theme;
      setSrc(t === "dark" ? "assets/widewired-logo-white.svg" : "assets/widewired-logo-ink.svg");
    };
    update();
    const obs = new MutationObserver(update);
    obs.observe(document.documentElement, { attributes: true, attributeFilter: ["data-theme"] });
    return () => obs.disconnect();
  }, []);
  return (
    <img src={src} alt="WideWired"
         style={{ height: size * 2, width: "auto", display: "block", flexShrink: 0 }}/>
  );
};

const Segmented = ({ value, options, onChange, small }) => (
  <div style={{
    display: "inline-flex", border: "1px solid var(--line)", borderRadius: 6, padding: 2,
    background: "var(--bg-2)", fontSize: 12,
  }}>
    {options.map(([k, l]) => (
      <button key={k} onClick={() => onChange(k)} style={{
        padding: small ? "4px 9px" : "6px 12px", border: 0, borderRadius: 4,
        background: value === k ? "var(--bg)" : "transparent",
        color: value === k ? "var(--ink)" : "var(--ink-3)",
        cursor: "pointer",
        fontFamily: "inherit", fontSize: small ? 11 : 12,
      }}>{l}</button>
    ))}
  </div>
);

// Role → permission matrix (from docs/19)
const CAN = {
  edit:    { owner: true, editor: true,  reader: false },
  delete:  { owner: true, editor: false, reader: false },
  invite:  { owner: true, editor: false, reader: false },
  billing: { owner: true, editor: false, reader: false },
};

function can(role, op) { return !!CAN[op]?.[role]; }

// Avatar
const Avatar = ({ name, size = 28, tone = "ink" }) => {
  const initial = (name || "?").trim().charAt(0).toUpperCase();
  const bg = tone === "accent" ? "var(--accent-soft)" : "var(--bg-3)";
  const fg = tone === "accent" ? "var(--accent)" : "var(--ink-2)";
  return (
    <div style={{
      width: size, height: size, borderRadius: size >= 28 ? 8 : 6,
      background: bg, color: fg,
      display: "inline-flex", alignItems: "center", justifyContent: "center",
      fontSize: size * 0.42, fontWeight: 600,
      border: "1px solid var(--line)",
    }}>{initial}</div>
  );
};

// Small icon (monospace symbol-based to avoid emoji / SVG complexity)
const Ic = ({ c, color }) => (
  <span className="mono" style={{ fontSize: 13, color: color || "var(--ink-3)", width: 16, display: "inline-block", textAlign: "center" }}>{c}</span>
);

Object.assign(window, { Dot, Pill, Btn, Card, Stat, LogoMark, Segmented, Avatar, Ic, can });
