/* eslint-disable */
/**
 * AMPAM Records Authority — Standalone Portal
 * ============================================
 * Self-contained React app. Shares the officials table with Gov Dashboard
 * but is otherwise independent (own token, own URL, own theme details).
 * Backend: /api/gov/ (gov_api.py).
 * Authority chain: Treaty of Madrid (1880) → AMPAM → ADDIF Registry.
 */

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

const GOV_API = "/api/gov/";
const CHAIN   = "Treaty of Madrid (1880) → AMPAM → ADDIF Registry";
const TOKEN_KEY = "ampam_records_token";

const T = {
  bg: "#0a0a12",
  surface: "#12121e",
  surface2: "#1a1a2e",
  surface3: "#232338",
  border: "#2a2a3e",
  borderStrong: "#3a3a52",
  gold: "#d4a843",
  goldBright: "#f0c050",
  goldDim: "#a07830",
  goldFaint: "#665530",
  red: "#8b0000",
  redBright: "#cc0000",
  green: "#00c853",
  blue: "#4fc3f7",
  text: "#e8e8e8",
  textDim: "#999",
  textMute: "#666",
  serif: "'Cormorant Garamond', Georgia, serif",
  sans: "'Inter', system-ui, sans-serif",
  mono: "'JetBrains Mono', 'Cascadia Code', monospace",
};

// ============================================================
//  API + STORAGE
// ============================================================
async function api(action, payload = {}) {
  try {
    const r = await fetch(GOV_API, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ action, ...payload }),
    });
    return await r.json();
  } catch (e) {
    console.error("[api]", action, e);
    return { ok: false, error: "network error: " + (e.message || e) };
  }
}
const loadToken  = () => localStorage.getItem(TOKEN_KEY) || "";
const saveToken  = (t) => localStorage.setItem(TOKEN_KEY, t);
const clearToken = () => localStorage.removeItem(TOKEN_KEY);

// ============================================================
//  PRIMITIVES
// ============================================================
const Card = ({ children, style, padding = 16, ...rest }) => (
  <div style={{
    background: T.surface2, border: `1px solid ${T.border}`,
    borderRadius: 8, padding, ...style,
  }} {...rest}>{children}</div>
);

const Button = ({ variant = "primary", size = "md", disabled, children, style, ...rest }) => {
  const sizes = {
    sm: { padding: "6px 12px", fontSize: 12 },
    md: { padding: "10px 18px", fontSize: 14 },
    lg: { padding: "14px 24px", fontSize: 15 },
  };
  const variants = {
    primary: {
      background: disabled ? T.surface3 : `linear-gradient(135deg, ${T.red} 0%, ${T.redBright} 100%)`,
      color: T.gold, border: `1px solid ${T.gold}`,
    },
    ghost: {
      background: "transparent", color: T.goldDim, border: `1px solid ${T.border}`,
    },
    danger: {
      background: "transparent", color: "#ff8080", border: `1px solid ${T.red}`,
    },
  };
  return (
    <button disabled={disabled} style={{
      ...sizes[size], ...variants[variant],
      borderRadius: 4, fontWeight: 600, letterSpacing: 0.5,
      cursor: disabled ? "not-allowed" : "pointer", fontFamily: T.sans,
      opacity: disabled ? 0.5 : 1, transition: "opacity 0.15s, transform 0.05s",
      ...style,
    }} {...rest}>{children}</button>
  );
};

const Badge = ({ color = "mute", children }) => {
  const c = {
    gold:  { bg: "rgba(212,168,67,0.14)", fg: T.gold,  bd: T.goldDim },
    green: { bg: "rgba(0,200,83,0.12)",   fg: T.green, bd: T.green },
    red:   { bg: "rgba(204,0,0,0.10)",    fg: "#ff8080", bd: T.red },
    blue:  { bg: "rgba(79,195,247,0.10)", fg: T.blue,  bd: T.blue },
    mute:  { bg: T.surface3, fg: T.textDim, bd: T.border },
  }[color] || {};
  return (
    <span style={{
      background: c.bg, color: c.fg, border: `1px solid ${c.bd}`,
      borderRadius: 4, padding: "2px 8px", fontSize: 11,
      fontFamily: T.mono, letterSpacing: 0.5,
      display: "inline-block",
    }}>{children}</span>
  );
};

const Field = ({ label, required, hint, children }) => (
  <div style={{ marginBottom: 14 }}>
    <label style={{
      display: "block", fontSize: 11, color: T.goldDim,
      letterSpacing: 1.2, textTransform: "uppercase", marginBottom: 5,
    }}>
      {label}{required && <span style={{ color: T.red }}> *</span>}
    </label>
    {children}
    {hint && <div style={{ fontSize: 11, color: T.textMute, marginTop: 4 }}>{hint}</div>}
  </div>
);

const Loading = () => (
  <div style={{ padding: 40, textAlign: "center", color: T.goldDim,
    fontFamily: T.mono, fontSize: 12, letterSpacing: 2, textTransform: "uppercase" }}>
    Loading…
  </div>
);

const Empty = ({ message }) => (
  <div style={{ padding: 32, textAlign: "center", color: T.textMute, fontSize: 13 }}>
    {message}
  </div>
);

const SectionHeader = ({ title, subtitle, right }) => (
  <div style={{
    display: "flex", justifyContent: "space-between", alignItems: "flex-end",
    marginBottom: 18, paddingBottom: 12, borderBottom: `1px solid ${T.border}`,
  }}>
    <div>
      <h2 style={{
        fontFamily: T.serif, fontSize: 24, color: T.gold,
        fontWeight: 600, letterSpacing: 1, margin: 0,
      }}>{title}</h2>
      {subtitle && <div style={{ fontSize: 12, color: T.textDim, letterSpacing: 0.8, marginTop: 4 }}>{subtitle}</div>}
    </div>
    <div>{right}</div>
  </div>
);

const DataTable = ({ columns, rows, onRowClick, emptyMessage = "No rows" }) => {
  if (!rows || rows.length === 0) return <Empty message={emptyMessage} />;
  return (
    <div style={{ overflowX: "auto", border: `1px solid ${T.border}`, borderRadius: 6 }}>
      <table style={{ width: "100%", borderCollapse: "collapse" }}>
        <thead>
          <tr style={{ background: T.surface }}>
            {columns.map((c) => (
              <th key={c.key} style={{
                textAlign: "left", padding: "10px 12px",
                color: T.goldDim, fontSize: 10, letterSpacing: 1.5,
                textTransform: "uppercase", fontWeight: 600,
                borderBottom: `1px solid ${T.border}`,
              }}>{c.label}</th>
            ))}
          </tr>
        </thead>
        <tbody>
          {rows.map((row, i) => (
            <tr key={row.id || row.catalog_number || i}
              onClick={onRowClick ? () => onRowClick(row) : undefined}
              style={{
                background: i % 2 === 0 ? T.surface2 : T.surface,
                borderBottom: `1px solid ${T.border}`,
                cursor: onRowClick ? "pointer" : "default",
                transition: "background 0.10s",
              }}
              onMouseEnter={(e) => { if (onRowClick) e.currentTarget.style.background = T.surface3; }}
              onMouseLeave={(e) => { e.currentTarget.style.background = i % 2 === 0 ? T.surface2 : T.surface; }}
            >
              {columns.map((c) => (
                <td key={c.key} style={{
                  padding: "10px 12px", color: T.text,
                  fontFamily: c.mono ? T.mono : T.sans,
                  fontSize: c.mono ? 12 : 13,
                }}>
                  {c.render ? c.render(row) : (row[c.key] ?? "")}
                </td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
};

function formatNumber(n) {
  const x = parseFloat(n);
  if (isNaN(x)) return n ?? "—";
  if (x === 0) return "0";
  if (Math.abs(x) < 0.0001) return x.toExponential(2);
  return x.toLocaleString(undefined, { maximumFractionDigits: 4 });
}

// ============================================================
//  LOGIN
// ============================================================
function LoginScreen({ onLogin }) {
  const [username, setUsername] = useState("");
  const [password, setPassword] = useState("");
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState("");
  const [showPw, setShowPw] = useState(false);

  const submit = async () => {
    if (!username || !password) { setErr("Username and password required"); return; }
    setBusy(true); setErr("");
    const r = await api("officials_login", { username, password });
    setBusy(false);
    if (r.ok && r.token) { saveToken(r.token); onLogin(r.official, r.token); }
    else setErr(r.error || "Login failed");
  };

  return (
    <div style={{
      minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center",
      background: `linear-gradient(160deg, #1a0000 0%, #0a0000 30%, ${T.bg} 100%)`,
      fontFamily: T.serif, padding: 20,
    }}>
      <Card padding={48} style={{
        width: 440, background: "rgba(20,10,10,0.92)",
        border: `1px solid ${T.gold}`, borderRadius: 14,
        boxShadow: "0 0 80px rgba(212,168,67,0.18), inset 0 0 40px rgba(0,0,0,0.6)",
      }}>
        <div style={{ textAlign: "center", marginBottom: 30 }}>
          <img src="/seal.png" alt="AMPAM Seal"
            style={{ height: 140, marginBottom: 18, filter: "drop-shadow(0 0 12px rgba(212,168,67,0.3))" }}
            onError={(e) => (e.target.style.display = "none")} />
          <div style={{ fontSize: 11, letterSpacing: 5, color: T.goldDim, textTransform: "uppercase", marginBottom: 6 }}>
            Allodial Moroccan Praedium Ante Michigan
          </div>
          <h1 style={{ fontSize: 28, color: T.gold, fontWeight: 600, letterSpacing: 3, margin: "8px 0" }}>
            AMPAM RECORDS
          </h1>
          <div style={{ fontSize: 11, color: T.goldFaint, letterSpacing: 3, textTransform: "uppercase" }}>
            Records Authority Portal
          </div>
        </div>

        <Field label="Username" required>
          <input value={username} onChange={(e) => setUsername(e.target.value)}
            onKeyDown={(e) => e.key === "Enter" && submit()}
            placeholder="watley" autoCapitalize="off" autoComplete="username"
            style={{ width: "100%", background: T.bg, border: `1px solid ${T.goldFaint}`,
              borderRadius: 6, padding: "12px 14px", fontFamily: T.mono, fontSize: 15, color: "#e8e0d0" }} />
        </Field>
        <Field label="Password" required>
          <div style={{ position: "relative" }}>
            <input type={showPw ? "text" : "password"}
              value={password} onChange={(e) => setPassword(e.target.value)}
              onKeyDown={(e) => e.key === "Enter" && submit()}
              placeholder="••••••••" autoComplete="current-password"
              style={{ width: "100%", background: T.bg, border: `1px solid ${T.goldFaint}`,
                borderRadius: 6, padding: "12px 56px 12px 14px",
                fontFamily: T.mono, fontSize: 15, letterSpacing: showPw ? 1 : 2, color: "#e8e0d0" }} />
            <button type="button" onClick={() => setShowPw((v) => !v)}
              aria-label={showPw ? "Hide password" : "Show password"}
              style={{ position: "absolute", right: 8, top: "50%", transform: "translateY(-50%)",
                background: "transparent", border: "none", color: T.goldDim,
                fontSize: 11, letterSpacing: 1.5, textTransform: "uppercase", cursor: "pointer", padding: "6px 8px" }}>
              {showPw ? "Hide" : "Show"}
            </button>
          </div>
        </Field>

        {err && (
          <div style={{
            padding: "10px 14px", marginBottom: 14,
            background: "rgba(200,0,0,0.12)", border: "1px solid rgba(200,0,0,0.3)",
            borderRadius: 6, color: "#ff8080", fontSize: 13,
          }}>{err}</div>
        )}

        <Button onClick={submit} disabled={busy} size="lg"
          style={{ width: "100%", fontFamily: T.serif, fontSize: 16, letterSpacing: 3 }}>
          {busy ? "VERIFYING…" : "ENTER RECORDS"}
        </Button>

        <div style={{
          marginTop: 26, paddingTop: 14, borderTop: `1px solid ${T.border}`,
          textAlign: "center", fontSize: 10, color: T.goldFaint,
          letterSpacing: 1.5, fontFamily: T.sans,
        }}>{CHAIN}</div>
      </Card>
    </div>
  );
}

// ============================================================
//  STATS TILES
// ============================================================
function StatsRow({ summary, royaltyTotal }) {
  const tiles = [
    { label: "Cataloged",        value: summary?.cataloged },
    { label: "Validated",        value: summary?.validated },
    { label: "Needs Review",     value: summary?.needs_review },
    { label: "In Mint Queue",    value: summary?.in_mint_queue },
    { label: "Minted",           value: summary?.minted },
    { label: "Royalty Payments", value: summary?.royalty_payments },
    { label: "Total Royalties",  value: royaltyTotal },
    { label: "ALDC Collected",   value: summary?.aldc_collected || "0" },
  ];
  return (
    <div style={{
      display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(150px, 1fr))",
      gap: 10, marginBottom: 18,
    }}>
      {tiles.map((t) => (
        <Card key={t.label} padding={14} style={{ textAlign: "center" }}>
          <div style={{ fontFamily: T.serif, fontSize: 24, fontWeight: 700,
            color: T.gold, lineHeight: 1, wordBreak: "break-all" }}>
            {t.value ?? "—"}
          </div>
          <div style={{ fontSize: 10, color: T.textDim, letterSpacing: 1.5,
            textTransform: "uppercase", marginTop: 6 }}>
            {t.label}
          </div>
        </Card>
      ))}
    </div>
  );
}

// ============================================================
//  PIPELINE FUNNEL
// ============================================================
const STAGES = [
  { key: "intake",       label: "Intake"       },
  { key: "needs_review", label: "Needs Review" },
  { key: "registered",   label: "Registered"   },
  { key: "stored",       label: "Stored"       },
  { key: "mint_ready",   label: "Mint Ready"   },
  { key: "minted",       label: "Minted"       },
];

function PipelineFunnel({ funnel, byType }) {
  const maxN = Math.max(1, ...STAGES.map((s) => funnel[s.key] || 0));
  return (
    <div>
      <Card padding={20}>
        <div style={{ fontSize: 11, color: T.goldDim, letterSpacing: 1.5,
          textTransform: "uppercase", marginBottom: 14 }}>
          Funnel — every Submit to Registry from a tool lands at intake
        </div>
        <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
          {STAGES.map((s) => {
            const n = funnel[s.key] || 0;
            const pct = (n / maxN) * 100;
            return (
              <div key={s.key} style={{ display: "flex", alignItems: "center", gap: 12 }}>
                <div style={{ width: 130, color: T.textDim, fontSize: 12,
                  letterSpacing: 1, textTransform: "uppercase" }}>
                  {s.label}
                </div>
                <div style={{ flex: 1, height: 30, background: T.surface3,
                  border: `1px solid ${T.border}`, borderRadius: 4, overflow: "hidden", position: "relative" }}>
                  <div style={{
                    width: pct + "%", height: "100%",
                    background: n > 0
                      ? `linear-gradient(90deg, ${T.gold} 0%, ${T.goldDim} 100%)`
                      : "transparent",
                    transition: "width 0.4s",
                  }} />
                  <span style={{
                    position: "absolute", left: 10, top: "50%", transform: "translateY(-50%)",
                    color: n > 0 ? "#1a0000" : T.textMute,
                    fontFamily: T.mono, fontSize: 12, fontWeight: 700,
                    textShadow: n > 0 ? "0 0 4px rgba(255,255,255,0.4)" : "none",
                  }}>{n}</span>
                </div>
              </div>
            );
          })}
        </div>
      </Card>
      {byType && byType.length > 0 && (
        <Card padding={20} style={{ marginTop: 14 }}>
          <div style={{ fontSize: 11, color: T.goldDim, letterSpacing: 1.5,
            textTransform: "uppercase", marginBottom: 10 }}>
            By Instrument Type
          </div>
          <div style={{ display: "grid",
            gridTemplateColumns: "repeat(auto-fill, minmax(200px, 1fr))", gap: 8 }}>
            {byType.map((b) => (
              <div key={b.instrument_type}
                style={{ display: "flex", justifyContent: "space-between",
                  padding: "8px 12px", border: `1px solid ${T.border}`, borderRadius: 4,
                  background: T.surface3 }}>
                <span style={{ color: T.text, fontSize: 13 }}>{b.instrument_type}</span>
                <span style={{ color: T.gold, fontFamily: T.mono, fontSize: 13, fontWeight: 600 }}>{b.n}</span>
              </div>
            ))}
          </div>
        </Card>
      )}
    </div>
  );
}

// ============================================================
//  CATALOG (with detail drawer)
// ============================================================
function statusColor(s) {
  return s === "minted"        ? "green"
       : s === "mint_ready"    ? "gold"
       : s === "registered"    ? "blue"
       : s === "stored"        ? "blue"
       : s === "needs_review"  ? "red"
       : "mute";
}

function CatalogView({ token }) {
  const [rows, setRows] = useState([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [statusFilter, setStatusFilter] = useState("all");
  const [openEntry, setOpenEntry] = useState(null);  // {catalog, validations, mint_queue_entry}

  const reload = useCallback(async () => {
    setLoading(true);
    const r = await api("list_catalog", { token, search, status: statusFilter });
    setRows((r.ok && r.catalog) || []);
    setLoading(false);
  }, [token, search, statusFilter]);

  useEffect(() => { reload(); }, [reload]);

  const openDetail = async (row) => {
    const r = await api("get_catalog_entry", { token, catalog_number: row.catalog_number });
    if (r.ok) setOpenEntry({
      catalog: r.catalog,
      validations: r.validations || [],
      mint_queue_entry: r.mint_queue_entry,
    });
  };

  const columns = [
    {
      key: "catalog_number", label: "Catalog #", mono: true,
      render: (r) => <span style={{ color: T.gold, fontWeight: 600 }}>{r.catalog_number}</span>,
    },
    { key: "instrument_type", label: "Type" },
    {
      key: "title", label: "Title",
      render: (r) => (
        <div>
          <div style={{ color: T.text, fontWeight: 500 }}>{r.title}</div>
          {r.description && (
            <div style={{ color: T.textMute, fontSize: 11, marginTop: 2,
              maxWidth: 400, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
              {r.description}
            </div>
          )}
        </div>
      ),
    },
    { key: "status", label: "Status",
      render: (r) => <Badge color={statusColor(r.status)}>{r.status}</Badge> },
    {
      key: "validation_score", label: "Score", mono: true,
      render: (r) => (
        <span style={{
          color: r.validation_score >= 80 ? T.green
               : r.validation_score >= 70 ? T.gold
               : "#ff8080",
          fontWeight: 600,
        }}>{r.validation_score}</span>
      ),
    },
    { key: "risk_level", label: "Risk",
      render: (r) => r.risk_level
        ? <Badge color={r.risk_level === "low" ? "green" : r.risk_level === "medium" ? "gold" : "red"}>{r.risk_level}</Badge>
        : "—" },
    {
      key: "created_at", label: "Cataloged", mono: true,
      render: (r) => (r.created_at || "").substring(0, 16).replace("T", " "),
    },
  ];

  return (
    <div>
      <div style={{ display: "flex", gap: 10, marginBottom: 12, flexWrap: "wrap", alignItems: "center" }}>
        <input placeholder="Search catalog #, title, type…"
          value={search} onChange={(e) => setSearch(e.target.value)}
          style={{ width: 320, padding: "8px 12px", fontSize: 13 }} />
        <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}
          style={{ padding: "8px 10px" }}>
          <option value="all">All statuses</option>
          {STAGES.map((s) => <option key={s.key} value={s.key}>{s.label}</option>)}
        </select>
        <Button variant="ghost" size="sm" onClick={reload}>Refresh</Button>
        <div style={{ marginLeft: "auto", fontSize: 11, color: T.textMute, fontFamily: T.mono }}>
          {rows.length} entries · click a row for validation detail
        </div>
      </div>
      {loading ? <Loading /> : <DataTable columns={columns} rows={rows} onRowClick={openDetail}
        emptyMessage="No catalog entries. Records flow in from controlled_records.status='pending'." />}

      {openEntry && <CatalogDrawer entry={openEntry} onClose={() => setOpenEntry(null)} />}
    </div>
  );
}

function CatalogDrawer({ entry, onClose }) {
  const c = entry.catalog;
  const v = entry.validations[0]; // latest
  const m = entry.mint_queue_entry;
  // Browser-back also closes the drawer.
  useEffect(() => {
    window.history.pushState({ records: "catalog-detail" }, "");
    const onPop = () => onClose();
    window.addEventListener("popstate", onPop);
    return () => window.removeEventListener("popstate", onPop);
    // eslint-disable-next-line
  }, []);

  const fmtTs = (s) => (s || "").substring(0, 19).replace("T", " ");

  return (
    <div style={{
      position: "fixed", inset: 0, background: "rgba(0,0,0,0.6)",
      zIndex: 9000, display: "flex", justifyContent: "flex-end",
    }} onClick={onClose}>
      <div onClick={(e) => e.stopPropagation()} style={{
        width: "min(680px, 100vw)", height: "100vh", overflowY: "auto",
        background: T.surface, borderLeft: `1px solid ${T.gold}`, padding: 0,
        display: "flex", flexDirection: "column",
      }}>
        {/* sticky back bar */}
        <div style={{
          position: "sticky", top: 0, zIndex: 1, background: T.surface,
          padding: "14px 24px", borderBottom: `1px solid ${T.border}`,
          display: "flex", justifyContent: "space-between", alignItems: "center",
        }}>
          <Button variant="ghost" size="sm" onClick={onClose}>← Back to Catalog</Button>
          <div style={{ fontFamily: T.mono, color: T.goldDim, fontSize: 11, letterSpacing: 1.5 }}>
            {c.catalog_number}
          </div>
        </div>

        <div style={{ padding: 24, flex: 1 }}>
          <div style={{ marginBottom: 18 }}>
            <h2 style={{ fontFamily: T.serif, color: T.gold, fontSize: 24, fontWeight: 600, margin: 0 }}>
              {c.title}
            </h2>
            <div style={{ fontSize: 12, color: T.textDim, marginTop: 4 }}>
              {c.instrument_type} · created {fmtTs(c.created_at_iso)}
            </div>
          </div>

          <div style={{ display: "flex", gap: 8, marginBottom: 18, flexWrap: "wrap" }}>
            <Badge color={statusColor(c.status)}>{c.status}</Badge>
            {v && <Badge color={v.validation_score >= 70 ? "green" : "red"}>score {v.validation_score}</Badge>}
            {v && v.risk_level && <Badge color={v.risk_level === "low" ? "green" : v.risk_level === "medium" ? "gold" : "red"}>{v.risk_level} risk</Badge>}
            {v && v.requires_manual_review && <Badge color="red">needs review</Badge>}
          </div>

          {/* Core fact card — entity, hashes, IPFS, controlled-record link */}
          <Card padding={14} style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 10, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase", marginBottom: 8 }}>
              Instrument
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "160px 1fr", gap: 6, fontSize: 13 }}>
              <div style={{ color: T.textDim }}>Catalog #</div>
              <div style={{ fontFamily: T.mono, color: T.gold, fontWeight: 600 }}>{c.catalog_number}</div>

              <div style={{ color: T.textDim }}>Type</div>
              <div>{c.instrument_type}</div>

              <div style={{ color: T.textDim }}>Status</div>
              <div><Badge color={statusColor(c.status)}>{c.status}</Badge></div>

              {c.entity_name && (
                <>
                  <div style={{ color: T.textDim }}>Entity</div>
                  <div>{c.entity_name}{c.entity_addif_number ? <span style={{ color: T.textMute, fontSize: 11, marginLeft: 8, fontFamily: T.mono }}>{c.entity_addif_number}</span> : null}</div>
                </>
              )}

              <div style={{ color: T.textDim }}>Created</div>
              <div style={{ fontFamily: T.mono, fontSize: 12 }}>{fmtTs(c.created_at_iso)} UTC</div>

              <div style={{ color: T.textDim }}>Updated</div>
              <div style={{ fontFamily: T.mono, fontSize: 12 }}>{fmtTs(c.updated_at_iso)} UTC</div>

              {c.controlled_record_id && (
                <>
                  <div style={{ color: T.textDim }}>Controlled Record</div>
                  <div style={{ fontFamily: T.mono, fontSize: 11, wordBreak: "break-all", color: T.textDim }}>{c.controlled_record_id}</div>
                </>
              )}

              {c.content_hash && (
                <>
                  <div style={{ color: T.textDim }}>Content Hash</div>
                  <div style={{ fontFamily: T.mono, fontSize: 11, wordBreak: "break-all", color: T.gold }}>{c.content_hash}</div>
                </>
              )}

              {c.ipfs_cid && (
                <>
                  <div style={{ color: T.textDim }}>IPFS CID</div>
                  <div style={{ fontFamily: T.mono, fontSize: 11, wordBreak: "break-all" }}>
                    <a href={`https://ipfs.io/ipfs/${c.ipfs_cid}`} target="_blank" rel="noopener noreferrer" style={{ color: T.gold }}>
                      {c.ipfs_cid}
                    </a>
                  </div>
                </>
              )}

              {c.jurisdictional_basis && (
                <>
                  <div style={{ color: T.textDim }}>Authority Chain</div>
                  <div style={{ fontSize: 11, color: T.goldFaint }}>{c.jurisdictional_basis}</div>
                </>
              )}
            </div>
          </Card>

          {c.description && (
            <Card padding={14} style={{ marginBottom: 14 }}>
              <div style={{ fontSize: 10, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase", marginBottom: 6 }}>
                Description
              </div>
              <div style={{ fontSize: 13, color: T.text, whiteSpace: "pre-wrap" }}>{c.description}</div>
            </Card>
          )}

        {v && (
          <Card padding={14} style={{ marginBottom: 14 }}>
            <div style={{ fontSize: 10, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase", marginBottom: 8 }}>
              Validation Checks
            </div>
            <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
              {(v.checks_passed || []).map((ch) => (
                <div key={"p_" + ch.name} style={{ display: "flex", gap: 8, alignItems: "center" }}>
                  <span style={{ color: T.green, width: 16, textAlign: "center" }}>✓</span>
                  <span style={{ flex: 1, color: T.text, fontSize: 12 }}>{ch.note || ch.name}</span>
                  <span style={{ color: T.goldDim, fontFamily: T.mono, fontSize: 11 }}>+{ch.weight}</span>
                </div>
              ))}
              {(v.checks_failed || []).map((ch) => (
                <div key={"f_" + ch.name} style={{ display: "flex", gap: 8, alignItems: "center" }}>
                  <span style={{ color: "#ff8080", width: 16, textAlign: "center" }}>✗</span>
                  <span style={{ flex: 1, color: T.text, fontSize: 12 }}>{ch.note || ch.name}</span>
                  <span style={{ color: T.textMute, fontFamily: T.mono, fontSize: 11 }}>−{ch.weight}</span>
                </div>
              ))}
            </div>
            {v.validation_notes && (
              <div style={{ marginTop: 10, paddingTop: 10, borderTop: `1px solid ${T.border}`, fontSize: 12, color: T.textDim }}>
                {v.validation_notes}
              </div>
            )}
            <div style={{ marginTop: 8, fontSize: 11, color: T.textMute, fontFamily: T.mono }}>
              validated by {v.validated_by || "—"} · {(v.validated_at || "").substring(0, 16).replace("T", " ")}
            </div>
          </Card>
        )}

        {m && (
          <Card padding={14}>
            <div style={{ fontSize: 10, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase", marginBottom: 8 }}>
              Mint Queue Entry
            </div>
            <div style={{ display: "grid", gridTemplateColumns: "140px 1fr", gap: 6, fontSize: 13 }}>
              <div style={{ color: T.textDim }}>Status</div><div><Badge color={statusColor(m.status === "minted" ? "minted" : m.status === "approved" ? "mint_ready" : "registered")}>{m.status}</Badge></div>
              <div style={{ color: T.textDim }}>ALDC fee</div><div style={{ fontFamily: T.mono }}>{m.aldc_fee} · {m.aldc_paid ? "paid" : "unpaid"}</div>
              <div style={{ color: T.textDim }}>Royalty</div><div style={{ fontFamily: T.mono }}>{m.royalty_percentage}%</div>
              {m.token_id && (<><div style={{ color: T.textDim }}>Token ID</div><div style={{ fontFamily: T.mono }}>{m.token_id}</div></>)}
              {m.mint_tx_hash && (<><div style={{ color: T.textDim }}>Tx Hash</div><div style={{ fontFamily: T.mono, fontSize: 11, wordBreak: "break-all" }}>{m.mint_tx_hash}</div></>)}
              {m.contract_address && (<><div style={{ color: T.textDim }}>Contract</div><div style={{ fontFamily: T.mono, fontSize: 11, wordBreak: "break-all" }}>{m.contract_address}</div></>)}
            </div>
          </Card>
        )}
        </div>
      </div>
    </div>
  );
}

// ============================================================
//  MINT QUEUE
// ============================================================
function MintQueueView({ token }) {
  const [rows, setRows] = useState([]);
  const [loading, setLoading] = useState(true);
  const [statusFilter, setStatusFilter] = useState("all");
  const [msg, setMsg] = useState(null);

  const reload = useCallback(async () => {
    setLoading(true);
    const r = await api("list_mint_queue", { token, status: statusFilter });
    setRows((r.ok && r.mint_queue) || []);
    setLoading(false);
  }, [token, statusFilter]);

  useEffect(() => { reload(); }, [reload]);

  const approve = async (row) => {
    const r = await api("approve_mint", { token, mint_id: row.id });
    if (r.ok) { setMsg({ type: "ok", text: `Approved ${row.catalog_number}` }); reload(); }
    else setMsg({ type: "err", text: r.error || "Approve failed" });
  };
  const deny = async (row) => {
    const reason = window.prompt(`Deny ${row.catalog_number}? Optional reason:`) || "";
    if (reason === null) return;
    const r = await api("deny_mint", { token, mint_id: row.id, reason });
    if (r.ok) { setMsg({ type: "ok", text: `Denied ${row.catalog_number}` }); reload(); }
    else setMsg({ type: "err", text: r.error || "Deny failed" });
  };

  const columns = [
    { key: "catalog_number", label: "Catalog #", mono: true,
      render: (r) => <span style={{ color: T.gold, fontWeight: 600 }}>{r.catalog_number}</span> },
    { key: "instrument_type", label: "Type" },
    { key: "status", label: "Status",
      render: (r) => <Badge color={
        r.status === "minted" ? "green"
        : r.status === "approved" ? "gold"
        : r.status === "denied" ? "red"
        : "blue"
      }>{r.status}</Badge> },
    { key: "aldc_fee", label: "ALDC Fee", mono: true,
      render: (r) => <span>{r.aldc_fee}{r.aldc_paid ? <span style={{ color: T.green, marginLeft: 6 }}>✓ paid</span> : <span style={{ color: T.textMute, marginLeft: 6 }}>unpaid</span>}</span> },
    { key: "royalty_percentage", label: "Royalty %", mono: true,
      render: (r) => `${r.royalty_percentage}%` },
    { key: "token_id", label: "Token", render: (r) => r.token_id || "—" },
    { key: "tx", label: "Tx", mono: true,
      render: (r) => r.mint_tx_hash ? r.mint_tx_hash.substring(0, 14) + "…" : "—" },
    { key: "created_at", label: "Queued", mono: true,
      render: (r) => (r.created_at || "").substring(0, 16).replace("T", " ") },
    { key: "actions", label: "",
      render: (r) => (
        ["pending_payment", "queued"].includes(r.status)
          ? (<div style={{ display: "flex", gap: 6 }}>
              <Button size="sm" onClick={(e) => { e.stopPropagation(); approve(r); }}>Approve</Button>
              <Button variant="danger" size="sm" onClick={(e) => { e.stopPropagation(); deny(r); }}>Deny</Button>
            </div>)
          : null
      ) },
  ];

  const flash = msg && (
    <div style={{
      padding: "8px 12px", marginBottom: 12, borderRadius: 6,
      background: msg.type === "ok" ? "rgba(0,200,83,0.10)" : "rgba(204,0,0,0.10)",
      border: `1px solid ${msg.type === "ok" ? T.green : T.red}`,
      color: msg.type === "ok" ? T.green : "#ff8080", fontSize: 13,
    }}>{msg.text}</div>
  );

  return (
    <div>
      <div style={{ display: "flex", gap: 10, marginBottom: 12, alignItems: "center" }}>
        <select value={statusFilter} onChange={(e) => setStatusFilter(e.target.value)}
          style={{ padding: "8px 10px" }}>
          <option value="all">All</option>
          <option value="pending_payment">Pending Payment</option>
          <option value="queued">Queued</option>
          <option value="approved">Approved</option>
          <option value="minted">Minted</option>
          <option value="denied">Denied</option>
        </select>
        <Button variant="ghost" size="sm" onClick={reload}>Refresh</Button>
        <div style={{ marginLeft: "auto", fontSize: 11, color: T.textMute, fontFamily: T.mono }}>
          {rows.length} in queue
        </div>
      </div>
      {flash}
      {loading ? <Loading /> : <DataTable columns={columns} rows={rows} emptyMessage="Mint queue is empty." />}
    </div>
  );
}

// ============================================================
//  ROYALTY LEDGER
// ============================================================
function RoyaltyView({ token }) {
  const [rows, setRows] = useState([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    api("list_royalty_ledger", { token }).then((r) => {
      if (cancelled) return;
      setRows((r.ok && r.royalties) || []);
      setLoading(false);
    });
    return () => { cancelled = true; };
  }, [token]);

  const total = rows.reduce((acc, r) => acc + (parseFloat(r.amount) || 0), 0);

  const columns = [
    { key: "received_at", label: "Received", mono: true,
      render: (r) => (r.received_at || "").substring(0, 16).replace("T", " ") },
    { key: "catalog_number", label: "Catalog #", mono: true,
      render: (r) => r.catalog_number || "—" },
    { key: "token_id", label: "Token", mono: true, render: (r) => r.token_id || "—" },
    { key: "sale_price", label: "Sale Price", mono: true,
      render: (r) => r.sale_price ? formatNumber(r.sale_price) : "—" },
    { key: "amount", label: "Royalty", mono: true,
      render: (r) => <span style={{ color: T.gold, fontWeight: 600 }}>{formatNumber(r.amount)} {r.currency}</span> },
    { key: "network", label: "Net", render: (r) => r.network || "—" },
    { key: "payer_address", label: "Payer", mono: true,
      render: (r) => r.payer_address ? r.payer_address.substring(0, 12) + "…" : "—" },
    { key: "tx_hash", label: "Tx", mono: true,
      render: (r) => r.tx_hash ? r.tx_hash.substring(0, 14) + "…" : "—" },
  ];

  return (
    <div>
      <Card padding={14} style={{ marginBottom: 14, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
        <div>
          <div style={{ fontSize: 11, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase" }}>
            EIP-2981 Royalty Receiver
          </div>
          <div style={{ fontFamily: T.mono, color: T.gold, fontSize: 13, marginTop: 4 }}>
            0xfe6eAfB7C3f574F63C80b06B72aa2775bfD58296
          </div>
          <div style={{ fontSize: 11, color: T.textMute, marginTop: 4 }}>
            2.5% on every secondary sale of InstrumentToken NFTs
          </div>
        </div>
        <div style={{ textAlign: "right" }}>
          <div style={{ fontFamily: T.serif, fontSize: 28, color: T.gold, fontWeight: 700 }}>
            {formatNumber(total)}
          </div>
          <div style={{ fontSize: 10, color: T.textDim, letterSpacing: 1.5, textTransform: "uppercase", marginTop: 2 }}>
            Total received ({rows.length} payments)
          </div>
        </div>
      </Card>
      {loading ? <Loading /> : <DataTable columns={columns} rows={rows} emptyMessage="No royalty payments received yet." />}
    </div>
  );
}

// ============================================================
//  ENGINE STATUS
// ============================================================
function EngineView({ token }) {
  const [status, setStatus] = useState(null);
  const [loading, setLoading] = useState(true);

  const reload = useCallback(async () => {
    setLoading(true);
    const r = await api("engine_status", { token });
    setStatus(r.ok ? { engine: r.engine, queue: r.queue } : null);
    setLoading(false);
  }, [token]);

  useEffect(() => {
    reload();
    const id = setInterval(reload, 10000);
    return () => clearInterval(id);
  }, [reload]);

  if (loading && !status) return <Loading />;

  const eng = status?.engine || {};
  const q   = status?.queue  || {};
  const reachable = eng.reachable;

  return (
    <div>
      <Card padding={20} style={{ marginBottom: 14, borderColor: reachable ? T.green : T.red }}>
        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 10 }}>
          <div>
            <div style={{ fontFamily: T.serif, fontSize: 20, color: T.gold }}>record-engine.service</div>
            <div style={{ fontSize: 11, color: T.textMute, marginTop: 4 }}>:9800 · poll every {eng.poll_interval_seconds || "?"}s</div>
          </div>
          <Badge color={reachable ? "green" : "red"}>{reachable ? "Running" : "Unreachable"}</Badge>
        </div>
        {eng.error && (
          <div style={{ padding: 10, background: "rgba(204,0,0,0.10)",
            border: `1px solid ${T.red}`, color: "#ff8080", fontSize: 12,
            borderRadius: 4, fontFamily: T.mono }}>
            {eng.error}
          </div>
        )}
      </Card>

      <div style={{ display: "grid", gridTemplateColumns: "repeat(auto-fit, minmax(220px, 1fr))", gap: 10, marginBottom: 14 }}>
        <Card padding={14}>
          <div style={{ fontSize: 10, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase" }}>Queue Depth</div>
          <div style={{ fontFamily: T.serif, fontSize: 28, color: T.gold, marginTop: 6 }}>
            {q.pending_depth ?? "—"}
          </div>
          <div style={{ fontSize: 11, color: T.textMute, marginTop: 4 }}>
            controlled_records with status='pending'
          </div>
        </Card>
        <Card padding={14}>
          <div style={{ fontSize: 10, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase" }}>Awaiting Intake</div>
          <div style={{ fontFamily: T.serif, fontSize: 28, color: T.gold, marginTop: 6 }}>
            {q.intake_depth ?? "—"}
          </div>
          <div style={{ fontSize: 11, color: T.textMute, marginTop: 4 }}>
            catalog rows at 'intake'
          </div>
        </Card>
        <Card padding={14}>
          <div style={{ fontSize: 10, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase" }}>Last Activity</div>
          <div style={{ fontFamily: T.mono, fontSize: 14, color: T.gold, marginTop: 8 }}>
            {q.last_activity_at ? q.last_activity_at.substring(0, 19).replace("T", " ") : "—"}
          </div>
          <div style={{ fontSize: 11, color: T.textMute, marginTop: 4 }}>UTC</div>
        </Card>
      </div>

      {q.last_event && (
        <Card padding={16}>
          <div style={{ fontSize: 10, color: T.goldDim, letterSpacing: 1.5, textTransform: "uppercase", marginBottom: 8 }}>
            Most Recent Event
          </div>
          <div style={{ display: "flex", gap: 10, alignItems: "center", marginBottom: 8 }}>
            <Badge color="gold">{q.last_event.event_type}</Badge>
            <span style={{ fontSize: 11, color: T.textMute, fontFamily: T.mono }}>
              {(q.last_event.at || "").substring(0, 19).replace("T", " ")} UTC · {q.last_event.actor}
            </span>
          </div>
          <pre style={{
            background: T.bg, border: `1px solid ${T.border}`, borderRadius: 4,
            padding: 10, fontFamily: T.mono, fontSize: 11, color: T.text,
            overflowX: "auto", whiteSpace: "pre-wrap",
          }}>
            {JSON.stringify(q.last_event.details, null, 2)}
          </pre>
        </Card>
      )}

      <div style={{ marginTop: 14, fontSize: 11, color: T.textMute, fontFamily: T.mono, textAlign: "right" }}>
        auto-refreshes every 10s · last fetched {new Date().toLocaleTimeString()}
      </div>
    </div>
  );
}

// ============================================================
//  HEADER
// ============================================================
function Header({ official, onLogout }) {
  return (
    <header style={{
      background: `linear-gradient(135deg, ${T.red} 0%, #1a0000 50%, ${T.surface} 100%)`,
      borderBottom: `2px solid ${T.gold}`,
      padding: "14px 28px",
      display: "flex", justifyContent: "space-between", alignItems: "center", gap: 24,
    }}>
      <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
        <img src="/seal.png" alt="AMPAM"
          style={{ height: 60, filter: "drop-shadow(0 0 8px rgba(212,168,67,0.4))" }}
          onError={(e) => (e.target.style.display = "none")} />
        <div>
          <h1 style={{ fontFamily: T.serif, fontSize: 22, color: T.gold,
            fontWeight: 600, letterSpacing: 2.5, margin: 0 }}>
            AMPAM RECORDS AUTHORITY
          </h1>
          <div style={{ fontSize: 10, color: T.goldFaint, letterSpacing: 2, marginTop: 2, textTransform: "uppercase" }}>
            Digital Instrument Administration · {CHAIN}
          </div>
        </div>
      </div>
      <div style={{ display: "flex", alignItems: "center", gap: 16 }}>
        <div style={{ textAlign: "right" }}>
          <div style={{ color: T.gold, fontFamily: T.serif, fontSize: 15 }}>{official.display_name}</div>
          <div style={{ fontSize: 10, color: T.goldFaint, letterSpacing: 1.5, textTransform: "uppercase", marginTop: 1 }}>
            {official.title || official.primary_department}
          </div>
        </div>
        <Button variant="ghost" size="sm" onClick={onLogout}>Log out</Button>
      </div>
    </header>
  );
}

// ============================================================
//  APP
// ============================================================
function App() {
  const [token, setToken] = useState(loadToken());
  const [official, setOfficial] = useState(null);
  const [bootLoading, setBootLoading] = useState(true);
  const [tab, setTab] = useState("pipeline");
  const [stats, setStats] = useState({ summary: {}, funnel: {}, by_type: [] });

  useEffect(() => {
    let cancelled = false;
    if (!token) { setBootLoading(false); return; }
    api("officials_session", { token }).then((r) => {
      if (cancelled) return;
      if (r.ok && r.official) setOfficial(r.official);
      else { clearToken(); setToken(""); }
      setBootLoading(false);
    });
    return () => { cancelled = true; };
  }, [token]);

  const refreshStats = useCallback(async () => {
    if (!token) return;
    const r = await api("catalog_stats", { token });
    if (r.ok) setStats({ summary: r.summary || {}, funnel: r.funnel || {}, by_type: r.by_instrument_type || [] });
  }, [token]);

  useEffect(() => {
    if (!official) return;
    refreshStats();
    const id = setInterval(refreshStats, 30000);
    return () => clearInterval(id);
  }, [official, refreshStats]);

  const onLogin = (o, t) => { setOfficial(o); setToken(t); };
  const onLogout = () => { clearToken(); setOfficial(null); setToken(""); };

  if (bootLoading) {
    return (
      <div style={{
        minHeight: "100vh", display: "flex", alignItems: "center", justifyContent: "center",
        color: T.gold, letterSpacing: 4, textTransform: "uppercase",
        fontFamily: T.serif, fontSize: 22,
      }}>
        AMPAM RECORDS LOADING…
      </div>
    );
  }

  if (!official) return <LoginScreen onLogin={onLogin} />;

  const tabs = [
    { k: "pipeline",   l: "Pipeline" },
    { k: "catalog",    l: "Catalog" },
    { k: "mint_queue", l: "Mint Queue" },
    { k: "royalties",  l: "Royalty Ledger" },
    { k: "engine",     l: "Engine" },
  ];

  return (
    <div style={{ display: "flex", flexDirection: "column", minHeight: "100vh", background: T.bg }}>
      <Header official={official} onLogout={onLogout} />
      <div style={{
        background: T.surface2, borderBottom: `1px solid ${T.border}`,
        padding: "6px 28px", display: "flex", gap: 4, flexWrap: "wrap",
      }}>
        {tabs.map((t) => {
          const active = tab === t.k;
          return (
            <button key={t.k} onClick={() => setTab(t.k)} style={{
              background: "transparent", color: active ? T.gold : T.textDim,
              border: "none", borderBottom: `2px solid ${active ? T.gold : "transparent"}`,
              padding: "10px 14px", fontSize: 12, fontWeight: 600,
              letterSpacing: 0.8, textTransform: "uppercase", transition: "all 0.15s",
            }}>{t.l}</button>
          );
        })}
        <div style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 8 }}>
          <Button variant="ghost" size="sm" onClick={refreshStats}>Refresh Stats</Button>
        </div>
      </div>
      <main style={{ padding: "20px 28px", flex: 1, overflowY: "auto" }}>
        <StatsRow summary={stats.summary} royaltyTotal={stats.summary?.total_royalties} />
        {tab === "pipeline" && (
          <>
            <SectionHeader title="Pipeline Funnel" subtitle="intake → validated → registered → stored → mint_ready → minted" />
            <PipelineFunnel funnel={stats.funnel} byType={stats.by_type} />
          </>
        )}
        {tab === "catalog" && (
          <>
            <SectionHeader title="Catalog" subtitle="every cataloged instrument · AMPAM-REC-YYYY-NNNN" />
            <CatalogView token={token} />
          </>
        )}
        {tab === "mint_queue" && (
          <>
            <SectionHeader title="Mint Queue" subtitle="instruments awaiting approval and on-chain mint" />
            <MintQueueView token={token} />
          </>
        )}
        {tab === "royalties" && (
          <>
            <SectionHeader title="Royalty Ledger" subtitle="EIP-2981 receipts on InstrumentToken NFTs" />
            <RoyaltyView token={token} />
          </>
        )}
        {tab === "engine" && (
          <>
            <SectionHeader title="Engine Status" subtitle="record-engine.service · pipeline worker on :9800" />
            <EngineView token={token} />
          </>
        )}
      </main>
      <footer style={{
        padding: "12px 28px", background: T.surface, borderTop: `1px solid ${T.border}`,
        fontSize: 10, color: T.goldFaint, letterSpacing: 2,
        textAlign: "center", textTransform: "uppercase", fontFamily: T.sans,
      }}>
        {CHAIN} · AMPAM Records Authority · Operating under Treaty of Peace and Friendship 1786/1836
      </footer>
      {window.AIChatAssistant && React.createElement(window.AIChatAssistant, {
        portal: "records",
        official: official,
        systemPrompt:
          "You are the AMPAM Records Authority Assistant operating under Treaty of Madrid (1880). " +
          "You help officials with the instrument pipeline (intake → validated → registered → stored → mint_ready → minted), " +
          "catalog lookup, mint queue approvals, EIP-2981 royalty ledger, and engine status. " +
          "Always cite the authority chain: Treaty of Madrid (1880) → AMPAM → ADDIF Registry.",
        contextLine:
          "The official is currently viewing the AMPAM Records '" + tab + "' tab. " +
          "Their role is " + ((official && (official.title || official.role)) || "—") + ".",
      })}
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
