// VK Quantum — small reusable primitives.
// All components attached to window at the bottom so other JSX files can use them.

const { useState, useEffect, useRef, useMemo, useCallback } = React;

// ---------- Pill ----------
function Pill({ kind = "neutral", children }) {
  const cls = `vk-pill vk-pill--${kind}`;
  return <span className={cls}>{children}</span>;
}

// ---------- Score (color-coded number) ----------
function scoreKind(n) {
  if (n == null) return "mute";
  if (n >= 85) return "high";
  if (n >= 70) return "med";
  return "low";
}
function Score({ value, riskScale = false, className = "" }) {
  // riskScale = true → invert (high number = bad)
  let kind;
  if (riskScale) {
    if (value == null) kind = "mute";
    else if (value >= 70) kind = "low";       // bad
    else if (value >= 40) kind = "med";
    else kind = "high";                       // good (low risk)
  } else {
    kind = scoreKind(value);
  }
  return (
    <span className={`vk-mono vk-score--${kind} ${className}`}>
      {value == null ? "—" : value}
    </span>
  );
}

// ---------- Confidence pill (high / med / low) ----------
function ConfPill({ confidence }) {
  const map = { high: "high", med: "med", medium: "med", low: "low" };
  const k = map[confidence] || "neutral";
  return <Pill kind={k}>{confidence === "medium" ? "med" : confidence}</Pill>;
}

// ---------- KPI tile ----------
function KpiTile({ label, value, scoreColor }) {
  return (
    <div className="vk-card" style={{ padding: 14, flex: 1, minWidth: 0 }}>
      <div style={{ fontSize: 11, color: "var(--vk-text-secondary)", marginBottom: 6 }}>
        {label}
      </div>
      <div
        className="vk-kpi-number"
        style={{ color: scoreColor || "var(--vk-text-primary)" }}
      >
        {value}
      </div>
    </div>
  );
}

// ---------- Avatar (initials, gradient bg) ----------
function initials(name) {
  if (!name) return "??";
  return name
    .replace("[redacted name]", "—")
    .split(/\s+/)
    .filter(Boolean)
    .slice(0, 2)
    .map((p) => p[0])
    .join("")
    .toUpperCase();
}
function Avatar({ name, size = 28 }) {
  const isRedacted = name && name.startsWith("[redacted");
  return (
    <div
      style={{
        width: size,
        height: size,
        flex: `0 0 ${size}px`,
        borderRadius: 999,
        background: isRedacted
          ? "var(--vk-surface-3)"
          : "linear-gradient(135deg, #E91E63 0%, #FF6B35 100%)",
        color: isRedacted ? "var(--vk-text-tertiary)" : "#fff",
        fontFamily: "var(--vk-font-mono)",
        fontSize: Math.round(size * 0.36),
        fontWeight: 500,
        display: "flex",
        alignItems: "center",
        justifyContent: "center",
        letterSpacing: 0,
      }}
    >
      {isRedacted ? "—" : initials(name)}
    </div>
  );
}

// ---------- Inline entity link ----------
function EntityLink({ entity, onOpen, children }) {
  return (
    <a
      href="#"
      className="vk-link"
      onClick={(ev) => {
        ev.preventDefault();
        if (onOpen) onOpen(entity);
      }}
    >
      {children || entity?.canonical_name}
    </a>
  );
}

// ---------- Evidence info button ----------
function EvidenceIcon({ evidence, onOpen, label = "evidence" }) {
  return (
    <button
      onClick={(ev) => {
        ev.stopPropagation();
        onOpen(evidence);
      }}
      aria-label={`Open ${label}`}
      style={{
        background: "transparent",
        border: 0,
        padding: 2,
        margin: 0,
        color: "var(--vk-text-tertiary)",
        cursor: "pointer",
        display: "inline-flex",
        alignItems: "center",
      }}
      onMouseEnter={(e) => (e.currentTarget.style.color = "var(--vk-text-secondary)")}
      onMouseLeave={(e) => (e.currentTarget.style.color = "var(--vk-text-tertiary)")}
    >
      <Icon name="ti-info-circle" style={{ fontSize: 14 }} />
    </button>
  );
}

// ---------- Card chrome ----------
function Card({ children, style, padding = 16, onClick }) {
  return (
    <div
      className="vk-card"
      style={{ padding, ...(onClick ? { cursor: "pointer" } : {}), ...style }}
      onClick={onClick}
    >
      {children}
    </div>
  );
}
function CardHeader({ title, subtitle, action, onTitleClick }) {
  return (
    <div
      style={{
        display: "flex",
        alignItems: "baseline",
        justifyContent: "space-between",
        gap: 12,
        marginBottom: 12,
      }}
    >
      <div style={{ display: "flex", alignItems: "baseline", gap: 10, minWidth: 0 }}>
        <h3
          style={{
            margin: 0,
            fontSize: 14,
            fontWeight: 500,
            color: "var(--vk-text-primary)",
            cursor: onTitleClick ? "pointer" : "default",
          }}
          onClick={onTitleClick}
        >
          {title}
        </h3>
        {subtitle && (
          <span style={{ fontSize: 11, color: "var(--vk-text-tertiary)" }}>
            {subtitle}
          </span>
        )}
      </div>
      {action}
    </div>
  );
}

// ---------- Mini table ----------
function MiniTable({ columns, rows, onRowClick }) {
  const gridTemplate = columns.map((c) => c.width || "1fr").join(" ");
  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      <div
        style={{
          display: "grid",
          gridTemplateColumns: gridTemplate,
          gap: 12,
          fontSize: 11,
          color: "var(--vk-text-tertiary)",
          letterSpacing: "0.08em",
          textTransform: "uppercase",
          fontWeight: 500,
          paddingBottom: 8,
          borderBottom: "1px solid var(--vk-border-subtle)",
        }}
      >
        {columns.map((c) => (
          <span key={c.key} style={{ textAlign: c.align || "left" }}>
            {c.label}
          </span>
        ))}
      </div>
      {rows.map((row, i) => (
        <div
          key={row.key || i}
          onClick={onRowClick ? () => onRowClick(row) : undefined}
          style={{
            display: "grid",
            gridTemplateColumns: gridTemplate,
            gap: 12,
            alignItems: "center",
            padding: "8px 0",
            borderBottom:
              i === rows.length - 1 ? "none" : "1px solid var(--vk-border-subtle)",
            cursor: onRowClick ? "pointer" : "default",
            transition: "background 120ms",
          }}
          onMouseEnter={(e) =>
            onRowClick &&
            (e.currentTarget.style.background = "rgba(255,255,255,0.02)")
          }
          onMouseLeave={(e) => (e.currentTarget.style.background = "transparent")}
        >
          {columns.map((c) => (
            <div
              key={c.key}
              style={{
                textAlign: c.align || "left",
                fontSize: 13,
                color: "var(--vk-text-primary)",
                minWidth: 0,
                overflow: "hidden",
                textOverflow: "ellipsis",
                whiteSpace: c.nowrap ? "nowrap" : "normal",
              }}
            >
              {row[c.key]}
            </div>
          ))}
        </div>
      ))}
    </div>
  );
}

// ---------- Demo badge ----------
function DemoBadge() {
  return (
    <span
      style={{
        display: "inline-flex",
        alignItems: "center",
        gap: 4,
        height: 18,
        padding: "0 8px",
        borderRadius: 999,
        fontSize: 10,
        letterSpacing: "0.08em",
        textTransform: "uppercase",
        fontWeight: 500,
        background: "var(--vk-gradient-soft)",
        color: "var(--vk-orange)",
      }}
      title="All rendered data carries _mock: true"
    >
      <Icon name="ti-shield-half" style={{ fontSize: 12 }} />
      demo
    </span>
  );
}

// ---------- Tag (small category) ----------
function MicroCap({ children, color }) {
  return (
    <span
      style={{
        fontSize: 10,
        letterSpacing: "0.08em",
        textTransform: "uppercase",
        fontWeight: 500,
        color: color || "var(--vk-text-tertiary)",
      }}
    >
      {children}
    </span>
  );
}

// Find helpers
function findEntity(id) {
  return window.VK_DATA.ENTITIES.find((e) => e.entity_id === id);
}
function findEvidence(id) {
  return window.VK_DATA.EVIDENCE.find((e) => e.evidence_id === id);
}

Object.assign(window, {
  Pill, Score, ConfPill, KpiTile, Avatar, EntityLink, EvidenceIcon,
  Card, CardHeader, MiniTable, DemoBadge, MicroCap,
  scoreKind, initials, findEntity, findEvidence,
});
