// ── Veritee · shared design-system primitives ──────────────────────────────
// Cream canvas, navy ink, teal accent. Square corners, 2px borders, hard
// offset shadows, 1-bit pixel icons and dotted "window" title bars. Hover
// states live in index.html as small utility classes (.v-press, .v-wash, …)
// because inline styles can't express :hover.
const { useState: useStateDS } = React;

/* ---------- Pixel icons (crisp-edge, fill currentColor) ---------- */
const PixelSvg = ({ size, box, d, style, color, evenOdd }) => (
  <svg width={size} height={size} viewBox={`0 0 ${box} ${box}`} fill={color || "currentColor"} fillRule={evenOdd ? "evenodd" : undefined} shapeRendering="crispEdges"
    style={{ display: "inline-block", verticalAlign: "middle", flexShrink: 0, ...style }} aria-hidden="true"><path d={d} /></svg>
);
const CHEVRON = "M2 0h2v2H2zM4 2h2v2H4zM6 4h2v2H6zM4 6h2v2H4zM2 8h2v2H2z";
const Icon = {
  ArrowRight: ({ size = 10, color }) => <PixelSvg size={size} box={10} color={color} d={CHEVRON} />,
  ArrowUpRight: ({ size = 12, color }) => <PixelSvg size={size} box={12} color={color} d="M3 1h8v8H9V5L4 10 2 8l5-5H3z" />,
  Search: ({ size = 14, color }) => <PixelSvg size={size} box={14} color={color} d="M2 1h6v1H2zM1 2h1v6H1zM8 2h1v6H8zM2 8h6v1H2zM9 9h1v1H9zM10 10h1v1h-1zM11 11h1v1h-1zM12 12h1v1h-1z" />,
  Chevron: ({ size = 10, dir = "right", color }) => {
    const rot = { right: 0, down: 90, left: 180, up: 270 }[dir];
    return <PixelSvg size={size} box={10} color={color} d={CHEVRON} style={{ transform: `rotate(${rot}deg)` }} />;
  },
  Copy: ({ size = 12, color }) => <PixelSvg size={size} box={12} color={color} d="M1 1h7v1H1zM1 1h1v7H1zM4 4h7v1H4zM4 4h1v7H4zM10 4h1v7h-1zM4 10h7v1H4z" />,
  Check: ({ size = 12, color }) => <PixelSvg size={size} box={10} color={color} d="M8 1h2v2H8zM7 3h2v2H7zM5 5h2v2H5zM1 4h2v2H1zM2 6h2v2H2zM3 7h3v2H3z" />,
  X: ({ size = 12, color }) => <PixelSvg size={size} box={10} color={color} d="M1 1h2v2H1zM7 1h2v2H7zM3 3h2v2H3zM5 3h2v2H5zM4 4h2v2H4zM3 5h2v2H3zM5 5h2v2H5zM1 7h2v2H1zM7 7h2v2H7z" />,
  Link: ({ size = 12, color }) => <PixelSvg size={size} box={14} color={color} d="M1 4h5v1H1zM1 4h1v6H1zM1 9h5v1H1zM8 4h5v1H8zM12 4h1v6h-1zM8 9h5v1H8zM4 6h6v2H4z" />,
  Info: ({ size = 14, color }) => <PixelSvg size={size} box={14} color={color} d="M4 0h6v1H4zM2 1h2v1H2zM10 1h2v1h-2zM1 2h1v2H1zM12 2h1v2h-1zM0 4h1v6H0zM13 4h1v6h-1zM1 10h1v2H1zM12 10h1v2h-1zM2 12h2v1H2zM10 12h2v1h-2zM4 13h6v1H4zM6 3h2v2H6zM6 6h2v5H6z" />,
  Grid: ({ size = 14, color }) => <PixelSvg size={size} box={14} color={color} d="M1 1h5v5H1zM8 1h5v5H8zM1 8h5v5H1zM8 8h5v5H8z" />,
  // Pixel cat head (GitHub mark); the eyes are cut out via even-odd fill.
  GitHub: ({ size = 12, color }) => <PixelSvg size={size} box={12} color={color} evenOdd d="M1 0h1v1H1zM10 0h1v1h-1zM1 1h2v1H1zM9 1h2v1H9zM1 2h10v1H1zM0 3h12v4H0zM3 4h2v2H3zM7 4h2v2H7zM1 7h10v1H1zM2 8h8v1H2zM4 9h4v3H4zM1 9h1v1H1zM2 10h2v1H2z" />,
  List: ({ size = 14, color }) => <PixelSvg size={size} box={14} color={color} d="M1 2h12v2H1zM1 6h12v2H1zM1 10h12v2H1z" />,
};

/* ---------- Small building blocks ---------- */
// A solid pixel square — bullets, status dots, swatches. `blink` = sync dot.
const PixelSquare = ({ size = 6, color = "var(--v-teal)", blink, outline, style }) => (
  <span className={blink ? "v-blink" : undefined} style={{
    width: size, height: size, display: "inline-block", flexShrink: 0,
    background: outline ? "transparent" : color, border: outline ? `2px solid ${color}` : "none", ...style,
  }} />
);

const DottedRule = ({ opacity = 1, style }) => (
  <span style={{ flex: 1, height: 2, minWidth: 12, background: "var(--v-dotted)", opacity, ...style }} />
);

// Mono uppercase label (table heads, section labels).
const vLabel = { fontFamily: "var(--font-mono)", fontSize: 10.5, textTransform: "uppercase", letterSpacing: "0.1em", color: "var(--v-ink)" };
// White card with the hard navy shadow.
const vCard = { border: "var(--v-border)", background: "var(--v-surface)", boxShadow: "var(--v-shadow-card)" };

/* "Window" title bar: square (or close button) + dotted rule + label + dotted rule. */
const WindowBar = ({ label, onClose, small }) => (
  <div style={{ display: "flex", alignItems: "center", gap: 8, padding: small ? "6px 10px" : "6px 12px", borderBottom: "var(--v-border)", background: "var(--v-canvas)" }}>
    {onClose
      ? <button onClick={onClose} title="Close" aria-label="Close" className="v-tint" style={{ width: 14, height: 14, border: "var(--v-border)", background: "var(--v-surface)", cursor: "pointer", padding: 0, flexShrink: 0 }} />
      : <span style={{ width: 9, height: 9, border: "var(--v-border)", display: "inline-block", flexShrink: 0 }} />}
    <DottedRule />
    <span style={{ fontFamily: "var(--font-mono)", fontSize: small ? 10.5 : 11, letterSpacing: "0.08em", textTransform: "uppercase", whiteSpace: "nowrap" }}>{label}</span>
    <DottedRule />
  </div>
);

/* Section label with a trailing dotted rule (drawer groups, status columns). */
const SectionLabel = ({ children, style }) => (
  <div style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 4, ...style }}>
    <span style={{ fontFamily: "var(--font-mono)", fontSize: 11, letterSpacing: "0.12em", textTransform: "uppercase", color: "var(--v-ink)", whiteSpace: "nowrap" }}>{children}</span>
    <DottedRule opacity={0.5} />
  </div>
);

/* Square glyph tile — Jersey letters on navy / cream / teal. */
const GlyphTile = ({ glyph, size = 44, bg = "var(--v-ink)", fg = "var(--v-canvas)", fontSize = 15, shadow }) => (
  <span style={{
    width: size, height: size, border: "var(--v-border)", background: bg, color: fg, flexShrink: 0,
    display: "flex", alignItems: "center", justifyContent: "center",
    fontFamily: "var(--font-display)", fontSize, lineHeight: 1, letterSpacing: "0.02em", boxShadow: shadow,
  }}>{glyph}</span>
);

/* Outlined mono chip (format / OS / batch tags). */
const Chip = ({ children, tone, title, style }) => {
  const tones = {
    danger: { color: "var(--v-danger)", borderColor: "var(--v-danger)", background: "var(--v-danger-tint)" },
    teal: { color: "var(--v-ink)", borderColor: "var(--v-ink)", background: "var(--v-teal-tint)" },
  };
  return (
    <span title={title} style={{
      fontFamily: "var(--font-mono)", fontSize: 10.5, letterSpacing: "0.05em", color: "var(--v-ink)",
      background: "var(--v-canvas)", border: "1px solid var(--v-ink)", padding: "2px 7px", whiteSpace: "nowrap", flexShrink: 0,
      ...(tones[tone] || {}), ...style,
    }}>{children}</span>
  );
};

/* ---------- Button ---------- */
// primary   — navy fill, cream text, teal shadow (CTAs)
// secondary — white fill, navy shadow, teal-tint hover
// small     — mono 11.5px, 2px shadow (Copy link, Load older, Back)
const Button = ({ variant = "primary", size = "md", children, onClick, as = "button", href, target, title, disabled, style }) => {
  const sm = variant === "small";
  const base = {
    display: "inline-flex", alignItems: "center", justifyContent: "center", gap: 8,
    fontFamily: sm ? "var(--font-mono)" : "var(--font-sans)", fontWeight: sm ? 400 : 600,
    cursor: disabled ? "default" : "pointer", textDecoration: "none", border: "var(--v-border)", borderRadius: 0,
    padding: sm ? "4px 12px" : size === "sm" ? "8px 14px" : "10px 18px",
    fontSize: sm ? 11.5 : size === "sm" ? 13 : 14, whiteSpace: "nowrap", lineHeight: 1.4,
    opacity: disabled ? 0.6 : 1,
  };
  const variants = {
    primary: { background: "var(--v-ink)", color: "var(--v-canvas)", boxShadow: "3px 3px 0 var(--v-teal)" },
    secondary: { background: "var(--v-surface)", color: "var(--v-ink)", boxShadow: "var(--v-shadow-btn)" },
    small: { background: "var(--v-surface)", color: "var(--v-ink)", boxShadow: "2px 2px 0 var(--v-ink)" },
  };
  const cls = variant === "primary" ? "v-press v-press-teal" : variant === "small" ? "v-press-sm v-tint" : "v-press v-tint";
  const Tag = as;
  return (
    <Tag href={href} target={target} rel={target ? "noopener noreferrer" : undefined} onClick={onClick} title={title} disabled={disabled}
      className={disabled ? undefined : cls} style={{ ...base, ...variants[variant], ...style }}>{children}</Tag>
  );
};

/* ---------- Eyebrow ---------- */
// Mono uppercase teal kicker with a leading pixel square (`blink` = live dot).
const Eyebrow = ({ children, style, square = true, blink, color = "var(--v-teal)" }) => (
  <span style={{
    fontFamily: "var(--font-mono)", fontSize: 12, letterSpacing: "0.12em", textTransform: "uppercase", color,
    display: "inline-flex", alignItems: "center", gap: 8, ...style,
  }}>{square && <PixelSquare size={blink ? 7 : 6} color={color} blink={blink} />}{children}</span>
);

/* ---------- Veritee wordmark ---------- */
const VeriteeLogo = ({ height = 44, onClick }) => (
  <a href="#explorer" onClick={onClick} style={{ display: "inline-flex", alignItems: "center", textDecoration: "none", flexShrink: 0 }}>
    <img src="assets/veritee-logo.png" alt="Veritee" style={{ height, width: "auto", display: "block", imageRendering: "pixelated" }} />
  </a>
);

/* ---------- Mono value with copy ---------- */
// `full` — the complete value the copy button copies when the rendered
// children are a shortened display form (e.g. a truncated hash).
const Mono = ({ children, copyable, full, color, size = 13 }) => {
  const [copied, setCopied] = useStateDS(false);
  const text = String(full != null ? full : children);
  const doCopy = (e) => {
    e.stopPropagation();
    navigator.clipboard?.writeText(text).then(() => { setCopied(true); setTimeout(() => setCopied(false), 1200); }).catch(() => {});
  };
  return (
    <span style={{ display: "inline-flex", alignItems: "center", gap: 7, fontFamily: "var(--font-mono)", fontSize: size, color: color || "var(--v-ink)", letterSpacing: 0 }}>
      <span style={{ wordBreak: "break-all" }}>{children}</span>
      {copyable && (
        <button onClick={doCopy} title="Copy" style={{ background: "none", border: "none", padding: 0, cursor: "pointer", color: copied ? "var(--v-teal)" : "var(--v-ink-40)", display: "inline-flex", lineHeight: 0 }}>
          {copied ? <Icon.Check size={11} /> : <Icon.Copy size={11} />}
        </button>
      )}
    </span>
  );
};

/* ---------- Status pill ---------- */
// Filled teal tint = vouched / verified; amber tint = signed but not rebuilt;
// red tint = revoked / rejected; white = nothing vouches.
const StatusPill = ({ kind }) => {
  const ok = { bg: "var(--v-teal-tint)", fg: "var(--v-ink)" };
  const warn = { bg: "var(--v-warn-tint)", fg: "var(--v-ink)" };
  const bad = { bg: "var(--v-danger-tint)", fg: "var(--v-danger)" };
  const off = { bg: "var(--v-surface)", fg: "var(--v-ink-70)" };
  const map = {
    trusted: { label: "Trusted", ...ok },
    revoked: { label: "Revoked", ...bad },
    registration: { label: "Reproduced", ...ok },
    verification: { label: "Verified", ...ok },
    rejected: { label: "Rejected", ...bad },
    staging: { label: "Staging", ...warn },
    // Stack-identity "vouched by" pills.
    hardwareSigned: { label: "Hardware-signed", ...ok },
    wardenReproduced: { label: "Warden-reproduced", ...ok },
    osDevSigned: { label: "Developer-signed", ...warn },
    osReproduced: { label: "Warden-reproduced", ...ok },
    unregistered: { label: "Not registered", ...off },
  };
  const m = map[kind] || map.trusted;
  return (
    <span style={{
      display: "inline-flex", alignItems: "center", gap: 6, fontFamily: "var(--font-mono)", fontSize: 10.5,
      letterSpacing: "0.06em", textTransform: "uppercase", color: m.fg, background: m.bg,
      border: `1px solid ${m.fg === "var(--v-danger)" ? "var(--v-danger)" : "var(--v-ink)"}`, padding: "2px 8px", whiteSpace: "nowrap",
    }}>
      <PixelSquare size={5} color={m.fg} />{m.label}
    </span>
  );
};

/* ---------- Identicon ----------
   No icon exists on-chain, so tiles derive one from a hash: a deterministic
   5×5 mirror-symmetric pixel glyph in teal on cream — the same identity
   always draws the same mark. `size` is the outer box in px. */
const Identicon = ({ seed, size = 44 }) => {
  const s = String(seed || "");
  const cells = [];
  for (let row = 0; row < 5; row++) {
    for (let col = 0; col < 3; col++) {
      const byte = parseInt(s.slice((row * 3 + col) * 2, (row * 3 + col) * 2 + 2), 16) || 0;
      if (byte % 2 === 0) {
        cells.push([col, row]);
        if (col < 2) cells.push([4 - col, row]);
      }
    }
  }
  const pad = size >= 40 ? 4 : 2;
  return (
    <span style={{ width: size, height: size, padding: pad, background: "var(--v-canvas)", border: "var(--v-border)", flexShrink: 0, display: "inline-block", lineHeight: 0 }}>
      <svg width="100%" height="100%" viewBox="0 0 5 5" shapeRendering="crispEdges" aria-hidden="true">
        {cells.map(([x, y], i) => <rect key={i} x={x} y={y} width="1" height="1" fill="var(--v-teal)" />)}
      </svg>
    </span>
  );
};

/* ---------- Stacked-layers "sealed as one" visual ---------- */
const STACK_LAYERS = [
  { glyph: "CPU", label: "Silicon", sub: "AMD SEV-SNP", meas: "launch · e15c4479", bg: "var(--v-ink)", fg: "var(--v-canvas)" },
  { glyph: "BOOT", label: "Boot chain", sub: "UKI · initrd · dm-verity root", meas: "PCR 0–4 · 3d458cfe", bg: "var(--v-ink)", fg: "var(--v-canvas)" },
  { glyph: "OS", label: "Immutable OS", sub: "reproducible squashfs", meas: "root-verity · 5c214346", bg: "var(--v-canvas)", fg: "var(--v-ink)" },
  { glyph: "APP", label: "Application disk", sub: "dm-verity app partition", meas: "PCR 15 · app_root_hash", bg: "var(--v-teal-tint)", fg: "var(--v-ink)" },
];

const StackedLayers = () => {
  const line = { position: "absolute", background: "var(--v-ink)" };
  return (
    <div style={{ display: "grid", gridTemplateColumns: "1fr 56px", alignItems: "stretch" }}>
      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
        {STACK_LAYERS.map((L) => (
          <div key={L.label} className="v-wash" style={{
            display: "grid", gridTemplateColumns: "40px 1fr auto", alignItems: "center", gap: 14, padding: "10px 14px",
            background: "var(--v-canvas)", border: "var(--v-border)", boxShadow: "var(--v-shadow-btn)",
          }}>
            <GlyphTile glyph={L.glyph} size={40} bg={L.bg} fg={L.fg} fontSize={14} />
            <span style={{ minWidth: 0 }}>
              <span style={{ display: "block", fontSize: 14.5, fontWeight: 600 }}>{L.label}</span>
              <span style={{ display: "block", fontSize: 12, opacity: 0.7, marginTop: 1 }}>{L.sub}</span>
            </span>
            <span className="tem-stack-meas" style={{ fontFamily: "var(--font-mono)", fontSize: 11, color: "var(--v-teal)", textAlign: "right", whiteSpace: "nowrap" }}>{L.meas}</span>
          </div>
        ))}
      </div>
      {/* binding bracket → one identity */}
      <div style={{ position: "relative", display: "flex", alignItems: "center", justifyContent: "center" }}>
        <div style={{ ...line, left: 14, top: 22, bottom: 22, width: 2 }} />
        <div style={{ ...line, left: 14, top: 22, width: 14, height: 2 }} />
        <div style={{ ...line, left: 14, bottom: 22, width: 14, height: 2 }} />
        <div style={{ ...line, left: 28, top: "50%", width: 10, height: 2, transform: "translateY(-50%)" }} />
        <div style={{ position: "relative", marginLeft: 30, width: 28, height: 28, background: "var(--v-teal)", border: "var(--v-border)", boxShadow: "2px 2px 0 var(--v-ink)" }} />
      </div>
    </div>
  );
};

Object.assign(window, {
  Icon, PixelSquare, DottedRule, WindowBar, SectionLabel, GlyphTile, Chip, vLabel, vCard,
  Button, Eyebrow, VeriteeLogo, Mono, StatusPill, Identicon, StackedLayers,
});
