// Misc shared chrome — top bar, side nav, alerts rail

function TopBar({ data, paused, onPause, onTickNow, fakeFault, setFakeFault, live }) {
  const { health, aggregate, now } = data;
  const btcLastBlock = ZW.fmtDurationMs(health.btc.lastBlockMs);
  const zecScanLag = ZW.isFiniteNumber(health.zec.scanLag) ? `scan −${health.zec.scanLag}` : ZW.NA;
  const quoteObserved = ZW.isFiniteNumber(health.quotes.observedAgo) ? `${health.quotes.observedAgo}s old` : ZW.NA;
  const sourceEntries = Object.values(live?.sources || {});
  const unavailableSources = sourceEntries.filter((s) => s && !s.ok).length;
  const statusTone = fakeFault || unavailableSources > 0 || health.preflight.ok === false ? "warn" : "ok";
  const statusText = fakeFault
    ? "DEMO: chaos injected"
    : unavailableSources > 0
      ? `${unavailableSources} source${unavailableSources === 1 ? "" : "s"} unavailable`
      : health.preflight.ok === false
        ? "preflight failing"
        : "live sources connected";
  return (
    <header style={{
      display: "flex",
      alignItems: "center",
      gap: 14,
      padding: "0 16px",
      height: 48,
      borderBottom: "1px solid var(--line)",
      background: "var(--bg-1)",
      flex: "none",
    }}>
      {/* Logo */}
      <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
        <svg width="22" height="22" viewBox="0 0 24 24">
          <circle cx="12" cy="12" r="10" fill="none" stroke="var(--alice)" strokeWidth="1.5" />
          <path d="M7 9 L12 14 L17 9" fill="none" stroke="var(--alice)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
          <path d="M7 15 L12 10 L17 15" fill="none" stroke="var(--bob)" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" opacity="0.7" />
        </svg>
        <div style={{ display: "flex", flexDirection: "column", lineHeight: 1.05 }}>
          <span style={{ fontSize: 13, fontWeight: 600, color: "var(--fg-0)" }}>Zwap Solver</span>
          <span className="mono" style={{ fontSize: 9.5, color: "var(--fg-3)", letterSpacing: 0.6 }}>
            {health.process.host || ZW.NA}
          </span>
        </div>
      </div>

      <div style={{ width: 1, height: 24, background: "var(--line)" }} />

      {/* Live blocks */}
      <div style={{ display: "flex", gap: 16 }}>
        <BlockTicker label="BTC" color="var(--btc)" height={health.btc.height} sub={btcLastBlock === ZW.NA ? ZW.NA : `${btcLastBlock} ago`} />
        <BlockTicker label="ZEC" color="var(--zec)" height={health.zec.tipHeight} sub={zecScanLag} warn={ZW.isFiniteNumber(health.zec.scanLag) && health.zec.scanLag > 20} />
        <BlockTicker label="BTC/USD" color="var(--btc)" height={ZW.fmtUsd(health.quotes.btcUsd)} sub={ZW.isFiniteNumber(health.quotes.spreadBps) ? `±${health.quotes.spreadBps}bps` : ZW.NA} mono />
        <BlockTicker label="ZEC/USD" color="var(--zec)" height={ZW.fmtUsd(health.quotes.zecUsd)} sub={quoteObserved} mono />
      </div>

      <div style={{ marginLeft: "auto", display: "flex", alignItems: "center", gap: 10 }}>
        {live && <LiveStatusPill sources={live.sources} ts={live.ts} />}
        <Badge tone={statusTone} subtle>
          <StatusDot status={statusTone} blink size={6} />
          {statusText}
        </Badge>
        <Button size="sm" icon={paused ? "▶" : "❚❚"} onClick={onPause}>{paused ? "Resume" : "Pause stream"}</Button>
        <Button size="sm" icon="↻" onClick={onTickNow}>Tick now</Button>
      </div>
    </header>
  );
}

function BlockTicker({ label, color, height, sub, mono = true, warn = false }) {
  const display = typeof height === "number"
    ? height.toLocaleString()
    : (height === null || height === undefined || height === "" ? ZW.NA : height);
  return (
    <div style={{ display: "flex", flexDirection: "column", lineHeight: 1.1, gap: 1 }}>
      <span style={{ fontSize: 9.5, color: "var(--fg-3)", letterSpacing: 0.5, textTransform: "uppercase", fontWeight: 600 }}>{label}</span>
      <span className={mono ? "mono" : ""} style={{ fontSize: 13, fontWeight: 600, color }}>
        {display}
      </span>
      <span className="mono" style={{ fontSize: 9.5, color: warn ? "var(--warn)" : "var(--fg-3)" }}>{sub}</span>
    </div>
  );
}

const NAV_ITEMS = [
  { id: "dashboard", label: "Dashboard", icon: "▦" },
  { id: "swaps", label: "Swaps", icon: "↔" },
  { id: "orderbook", label: "Orderbook", icon: "▤" },
  { id: "health", label: "Health", icon: "♥" },
  { id: "logs", label: "Logs", icon: "⌥" },
];

function SideNav({ active, onNav, alertCount, swapCount }) {
  return (
    <nav style={{
      width: 56, flex: "none",
      background: "var(--bg-1)",
      borderRight: "1px solid var(--line)",
      display: "flex", flexDirection: "column",
      padding: "10px 0", gap: 4, alignItems: "center",
    }}>
      {NAV_ITEMS.map((item) => {
        const isActive = active === item.id || (active === "detail" && item.id === "swaps");
        const badge = item.id === "swaps" ? swapCount : null;
        return (
          <button key={item.id}
            onClick={() => onNav(item.id)}
            title={item.label}
            style={{
              width: 40, height: 40,
              border: "1px solid " + (isActive ? "var(--line)" : "transparent"),
              background: isActive ? "var(--bg-3)" : "transparent",
              color: isActive ? "var(--fg-0)" : "var(--fg-2)",
              borderRadius: 6,
              display: "flex", alignItems: "center", justifyContent: "center",
              cursor: "pointer", position: "relative", fontSize: 16,
            }}
            onMouseEnter={(e) => { if (!isActive) e.currentTarget.style.background = "var(--bg-2)"; }}
            onMouseLeave={(e) => { if (!isActive) e.currentTarget.style.background = "transparent"; }}>
            <span>{item.icon}</span>
            {badge != null && badge > 0 && (
              <span className="mono" style={{
                position: "absolute", top: 2, right: 2,
                fontSize: 9, padding: "0 4px",
                background: "var(--bg-0)",
                color: "var(--fg-2)",
                border: "1px solid var(--line)",
                borderRadius: 8, lineHeight: 1.4,
              }}>{badge}</span>
            )}
          </button>
        );
      })}
      <div style={{ flex: 1 }} />
      {alertCount > 0 && (
        <div style={{
          width: 36, height: 4, borderRadius: 2,
          background: "var(--warn)",
        }} />
      )}
    </nav>
  );
}

function AlertsRail({ alerts, onSelectSwap, now }) {
  return (
    <aside style={{
      width: 320, flex: "none",
      borderLeft: "1px solid var(--line)",
      background: "var(--bg-1)",
      display: "flex", flexDirection: "column", minHeight: 0,
    }}>
      <header style={{
        padding: "10px 14px",
        borderBottom: "1px solid var(--line-soft)",
        display: "flex", alignItems: "center", justifyContent: "space-between",
        flex: "none",
      }}>
        <h3 style={{ margin: 0, fontSize: 12, fontWeight: 600, letterSpacing: 0.4, textTransform: "uppercase", color: "var(--fg-2)" }}>
          Alerts & Activity
        </h3>
        <Badge tone={alerts.some((a) => a.severity === "warn" || a.severity === "err") ? "warn" : "ok"} subtle>
          {alerts.length}
        </Badge>
      </header>
      <div style={{ flex: 1, minHeight: 0, overflowY: "auto" }}>
        {alerts.map((a) => (
          <div key={a.id}
            onClick={() => a.swapId && onSelectSwap(a.swapId)}
            style={{
              padding: "10px 14px",
              borderBottom: "1px solid var(--line-soft)",
              cursor: a.swapId ? "pointer" : "default",
              display: "flex", flexDirection: "column", gap: 4,
              borderLeft: `3px solid ${
                a.severity === "err" ? "var(--err)" :
                a.severity === "warn" ? "var(--warn)" :
                a.severity === "ok" ? "var(--ok)" :
                "var(--info)"
              }`,
            }}
            onMouseEnter={(e) => { if (a.swapId) e.currentTarget.style.background = "var(--bg-2)"; }}
            onMouseLeave={(e) => { if (a.swapId) e.currentTarget.style.background = "transparent"; }}>
            <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", gap: 8 }}>
              <span style={{ fontSize: 12.5, fontWeight: 600, color: "var(--fg-0)" }}>{a.title}</span>
              <span className="mono" style={{ fontSize: 10, color: "var(--fg-3)" }}>{ZW.fmtRelTime(a.ts, now)}</span>
            </div>
            <span style={{ fontSize: 11.5, color: "var(--fg-2)", lineHeight: 1.4 }}>{a.body}</span>
            {a.swapId && (
              <span className="mono" style={{ fontSize: 10.5, color: "var(--alice)" }}>→ {a.swapId}</span>
            )}
          </div>
        ))}
      </div>
    </aside>
  );
}

Object.assign(window, { TopBar, SideNav, AlertsRail });
