// Health view + Orderbook view + Logs view

function ViewHealth({ data }) {
  const { health, spark, now } = data;
  const isNum = ZW.isFiniteNumber;
  const upText = isNum(health.process.uptime)
    ? `${Math.floor(Number(health.process.uptime) / 86400)}d ${Math.floor((Number(health.process.uptime) % 86400) / 3600)}h`
    : ZW.NA;
  const memPct = isNum(health.process.memoryMb) && isNum(health.process.memoryLimitMb) && Number(health.process.memoryLimitMb) > 0
    ? Math.floor((Number(health.process.memoryMb) / Number(health.process.memoryLimitMb)) * 100)
    : null;
  const scanWarn = isNum(health.zec.scanLag) && health.zec.scanLag > 20;

  return (
    <div style={{ padding: 14, display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, alignContent: "start", overflowY: "auto" }}>
      {/* BTC backend */}
      <Panel title="Bitcoin Backend"
        right={<Badge tone={health.btc.rpc.status === "ok" ? "ok" : "err"}><StatusDot status={health.btc.rpc.status || "err"} size={6} />{health.btc.rpc.status === "ok" ? "ready" : "unavailable"}</Badge>}>
        <ParamGrid rows={[
          ["RPC endpoint", <span className="mono" style={{ fontSize: 11 }}>{health.btc.rpc.endpoint || ZW.NA}</span>],
          ["Latency", <span className="mono">{ZW.fmtMs(health.btc.rpc.latencyMs)}</span>],
          ["Tip height", <span className="mono">{ZW.fmtInt(health.btc.height)}</span>],
          ["Last block", <span className="mono">{ZW.fmtDurationMs(health.btc.lastBlockMs) === ZW.NA ? ZW.NA : `${ZW.fmtDurationMs(health.btc.lastBlockMs)} ago`}</span>],
          ["Wallet balance", <span className="mono" style={{ color: "var(--btc)" }}>{ZW.fmtSats(health.btc.walletBalance)} BTC</span>],
          ["Reserved (locked UTXOs)", <span className="mono">{ZW.fmtSats(health.btc.reservedSats)} BTC</span>],
          ["UTXO count", <span className="mono">{ZW.fmtInt(health.btc.utxoCount)}</span>],
          ["Pending spends", <span className="mono">{ZW.fmtInt(health.btc.pendingSpends)}</span>],
          ["Fee (econ / fast)", <span className="mono">{isNum(health.btc.mempoolFee.sats_vb_econ) && isNum(health.btc.mempoolFee.sats_vb_fast) ? `${health.btc.mempoolFee.sats_vb_econ} / ${health.btc.mempoolFee.sats_vb_fast} sat/vB` : ZW.NA}</span>],
        ]} />
      </Panel>

      {/* ZEC backend */}
      <Panel title="Zcash / Orchard Backend"
        right={<Badge tone={scanWarn ? "warn" : isNum(health.zec.scanLag) ? "ok" : "neutral"}>
          <StatusDot status={scanWarn ? "warn" : isNum(health.zec.scanLag) ? "ok" : "idle"} size={6} blink={scanWarn} />
          {scanWarn ? "lagging" : isNum(health.zec.scanLag) ? "in sync" : "N/A"}
        </Badge>}>
        <ParamGrid rows={[
          ["zebrad RPC", <span className="mono" style={{ fontSize: 11 }}>{health.zec.rpc.endpoint || ZW.NA}</span>],
          ["ZEC node info", <span className="mono" style={{ fontSize: 11 }}>{health.zec.lwd.endpoint || ZW.NA}</span>],
          ["RPC / node latency", <span className="mono">{ZW.fmtMs(health.zec.rpc.latencyMs)} / {ZW.fmtMs(health.zec.lwd.latencyMs)}</span>],
          ["Tip height", <span className="mono">{ZW.fmtInt(health.zec.tipHeight)}</span>],
          ["Scan height", <span className="mono">{ZW.fmtInt(health.zec.scanHeight)}</span>],
          ["Scan lag", <span className="mono" style={{ color: scanWarn ? "var(--warn)" : "var(--fg-1)" }}>{isNum(health.zec.scanLag) ? `−${health.zec.scanLag} blk` : ZW.NA}</span>],
          ["Wallet balance", <span className="mono" style={{ color: "var(--zec)" }}>{ZW.fmtZats(health.zec.walletBalance)} ZEC</span>],
          ["Notes / pending", <span className="mono">{isNum(health.zec.noteCount) && isNum(health.zec.pendingSpends) ? `${health.zec.noteCount} notes · ${health.zec.pendingSpends} pending` : ZW.NA}</span>],
          ["24h reorgs", <span className="mono">{ZW.fmtInt(health.zec.reorgDepthSeen24h)}</span>],
        ]} />
      </Panel>

      {/* Quote source */}
      <Panel title="Quote Source"
        right={<Badge tone={health.quotes.stale ? "warn" : "ok"}>{health.quotes.source}</Badge>}>
        <ParamGrid rows={[
          ["BTC/USD", <span className="mono" style={{ color: "var(--btc)" }}>{ZW.fmtUsd(health.quotes.btcUsd)}</span>],
          ["ZEC/USD", <span className="mono" style={{ color: "var(--zec)" }}>{ZW.fmtUsd(health.quotes.zecUsd)}</span>],
          ["Implied rate", <span className="mono">{isNum(health.quotes.midZatsPerSat) ? `${Number(health.quotes.midZatsPerSat).toFixed(2)} ZEC/BTC` : ZW.NA}</span>],
          ["Spread", <span className="mono">{isNum(health.quotes.spreadBps) ? `${health.quotes.spreadBps} bps` : ZW.NA}</span>],
          ["TTL", <span className="mono">{isNum(health.quotes.ttlSecs) ? `${health.quotes.ttlSecs}s` : ZW.NA}</span>],
          ["Last observed", <span className="mono">{isNum(health.quotes.observedAgo) ? `${health.quotes.observedAgo}s ago` : ZW.NA}</span>],
        ]} />
      </Panel>

      {/* Preflight */}
      <Panel title="Preflight & Safety"
        right={<Badge tone={health.preflight.ok === true ? "ok" : health.preflight.ok === false ? "err" : "neutral"}>
          {isNum(health.preflight.passed) && isNum(health.preflight.total) ? `${health.preflight.passed}/${health.preflight.total} pass` : ZW.NA}
        </Badge>}>
        <ParamGrid rows={[
          ["Mainnet enabled", <Badge tone={health.preflight.mainnetEnabled === true ? "ok" : health.preflight.mainnetEnabled === false ? "warn" : "neutral"} subtle>
            {health.preflight.mainnetEnabled === true ? "yes" : health.preflight.mainnetEnabled === false ? "no" : ZW.NA}
          </Badge>],
          ["Strict preflight", <Badge tone={health.preflight.strictMode === true ? "ok" : health.preflight.strictMode === false ? "warn" : "neutral"} subtle>
            {health.preflight.strictMode === true ? "enabled" : health.preflight.strictMode === false ? "off" : ZW.NA}
          </Badge>],
          ["Keystore mode", <span className="mono">{health.preflight.keystoreMode || ZW.NA}</span>],
          ["Last preflight run", <span className="mono">{ZW.fmtRelTime(health.preflight.lastRun, now) === ZW.NA ? ZW.NA : `${ZW.fmtRelTime(health.preflight.lastRun, now)} ago`}</span>],
          ...(health.preflight.error ? [["Error", <span style={{ color: "var(--err)", fontSize: 11 }}>{health.preflight.error}</span>]] : []),
        ]} />
        <div style={{ marginTop: 10, display: "flex", gap: 6 }}>
          <Button size="sm" variant="primary">Run preflight</Button>
          <Button size="sm">View report</Button>
        </div>
      </Panel>

      {/* Process / DB */}
      <Panel title="Process">
        <ParamGrid rows={[
          ["Version", <span className="mono" style={{ fontSize: 11 }}>{health.process.version || ZW.NA}</span>],
          ["Host", <span className="mono">{health.process.host || ZW.NA}</span>],
          ["Uptime", <span className="mono">{upText}</span>],
          ["Memory", <span className="mono">{isNum(health.process.memoryMb) ? ZW.fmtInt(health.process.memoryMb) : ZW.NA} / {isNum(health.process.memoryLimitMb) ? ZW.fmtInt(health.process.memoryLimitMb) : ZW.NA} MB</span>],
          ["CPU", <span className="mono">{isNum(health.process.cpu) ? `${health.process.cpu}%` : ZW.NA}</span>],
        ]} />
        <div style={{ marginTop: 8 }}>
          <div style={{ display: "flex", justifyContent: "space-between", fontSize: 11, color: "var(--fg-2)", marginBottom: 4 }}>
            <span>Memory headroom</span>
            <span className="mono">{memPct == null ? ZW.NA : `${memPct}%`}</span>
          </div>
          <div style={{ height: 6, background: "var(--bg-3)", borderRadius: 3, overflow: "hidden" }}>
            <div style={{ width: `${memPct == null ? 0 : memPct}%`, height: "100%", background: "var(--alice)" }} />
          </div>
        </div>
      </Panel>

      <Panel title="Persistent State">
        <ParamGrid rows={[
          ["Orderbook DB", <span className="mono">{isNum(health.db.orderbookSize) ? `${Number(health.db.orderbookSize).toFixed(1)} MB` : ZW.NA}</span>],
          ["BTC metadata DB", <span className="mono">{isNum(health.db.btcMetaSize) ? `${Number(health.db.btcMetaSize).toFixed(1)} MB` : ZW.NA}</span>],
          ["ZEC wallet DB", <span className="mono">{isNum(health.db.zecWalletSize) ? `${Number(health.db.zecWalletSize).toFixed(1)} MB` : ZW.NA}</span>],
          ["Last hourly backup", <span className="mono">{ZW.fmtRelTime(health.db.lastBackup, now) === ZW.NA ? ZW.NA : `${ZW.fmtRelTime(health.db.lastBackup, now)} ago`}</span>],
        ]} />
        <div style={{ marginTop: 10, display: "flex", gap: 6 }}>
          <Button size="sm">Backup now</Button>
          <Button size="sm">Verify last</Button>
        </div>
      </Panel>
    </div>
  );
}

function ViewOrderbook({ data, now }) {
  const { orders, aggregate } = data;
  const impliedRate = ZW.isFiniteNumber(aggregate.impliedZecPerBtc)
    ? Number(aggregate.impliedZecPerBtc).toFixed(2)
    : ZW.NA;
  return (
    <div style={{ padding: 14, display: "flex", flexDirection: "column", gap: 12, height: "100%", minHeight: 0 }}>
      <div style={{ display: "grid", gridTemplateColumns: "repeat(4, 1fr)", gap: 10 }}>
        <KPI label="Open Orders" value={orders.filter((o) => o.status === "open").length} />
        <KPI label="Matched" value={orders.filter((o) => o.status === "matched").length} unit="awaiting solverd" />
        <KPI label="Filled 24h" value={orders.filter((o) => o.status === "filled").length} />
        <KPI label="Implied Rate" value={impliedRate} unit={impliedRate === ZW.NA ? undefined : "ZEC/BTC"} />
      </div>
      <Panel padded={false} style={{ flex: 1, minHeight: 0 }} scrollable>
        <div style={{
          display: "grid", gridTemplateColumns: "150px 100px 110px 110px 90px 1fr 70px",
          padding: "9px 14px", fontSize: 10.5, color: "var(--fg-2)",
          letterSpacing: 0.4, textTransform: "uppercase", fontWeight: 600,
          borderBottom: "1px solid var(--line-soft)",
          position: "sticky", top: 0, background: "var(--bg-1)", zIndex: 1,
        }}>
          <span>Order ID</span><span>Direction</span><span>Status</span>
          <span style={{ textAlign: "right" }}>Amount</span>
          <span style={{ textAlign: "right" }}>Age</span>
          <span>Counterparty / Quote</span>
          <span></span>
        </div>
        {orders.map((o) => (
          <div key={o.id} style={{
            display: "grid", gridTemplateColumns: "150px 100px 110px 110px 90px 1fr 70px",
            padding: "9px 14px", fontSize: 12.5, alignItems: "center",
            borderBottom: "1px solid var(--line-soft)",
          }}>
            <span className="mono">{o.id}</span>
            <DirectionChip direction={o.direction} />
            <Badge tone={
              o.status === "filled" ? "ok" :
              o.status === "matched" ? "info" :
              o.status === "expired" ? "neutral" : "warn"
            } subtle>{o.status}</Badge>
            <span className="mono" style={{ textAlign: "right" }}>{ZW.fmtSats(o.amountSats)} BTC</span>
            <span className="mono" style={{ textAlign: "right", color: "var(--fg-3)" }}>{ZW.fmtRelTime(o.createdAt, now)}</span>
            <span style={{ display: "flex", gap: 8, alignItems: "center" }}>
              <span className="mono" style={{ fontSize: 11 }}>{o.counterparty}</span>
              <HashChip value={o.quoteId} headLen={6} tailLen={3} />
            </span>
            <Button size="sm">view</Button>
          </div>
        ))}
      </Panel>
    </div>
  );
}

function ViewLogs({ data, onSelectSwap }) {
  const { logs, now } = data;
  const [level, setLevel] = React.useState("all");
  const filtered = level === "all" ? logs : logs.filter((l) => l.level === level);
  return (
    <div style={{ padding: 14, display: "flex", flexDirection: "column", gap: 12, height: "100%", minHeight: 0 }}>
      <div style={{ display: "flex", gap: 6, alignItems: "center", flex: "none" }}>
        <span style={{ fontSize: 11, color: "var(--fg-2)", textTransform: "uppercase", letterSpacing: 0.4 }}>Level</span>
        <div style={{ display: "flex", gap: 4, background: "var(--bg-1)", padding: 3, borderRadius: 6, border: "1px solid var(--line-soft)" }}>
          {["all", "debug", "info", "warn", "error"].map((l) => (
            <button key={l} onClick={() => setLevel(l)}
              style={{
                background: level === l ? "var(--bg-3)" : "transparent",
                border: "1px solid " + (level === l ? "var(--line)" : "transparent"),
                color: level === l ? "var(--fg-0)" : "var(--fg-2)",
                padding: "5px 10px", fontSize: 12, borderRadius: 4, cursor: "pointer",
              }}>{l}</button>
          ))}
        </div>
        <span style={{ marginLeft: "auto", fontSize: 11, color: "var(--fg-3)" }}>{filtered.length} lines · live</span>
        <Button size="sm" icon="⏸">Pause</Button>
      </div>
      <Panel padded={false} style={{ flex: 1, minHeight: 0 }} scrollable>
        <div className="mono" style={{ fontSize: 11.5 }}>
          {filtered.map((l, i) => (
            <div key={i}
              onClick={() => l.swapId && onSelectSwap(l.swapId)}
              style={{
                display: "grid", gridTemplateColumns: "100px 56px 110px 1fr 130px",
                gap: 12,
                padding: "5px 14px",
                borderBottom: "1px solid var(--line-soft)",
                cursor: l.swapId ? "pointer" : "default",
                color: "var(--fg-1)",
              }}
              onMouseEnter={(e) => { if (l.swapId) e.currentTarget.style.background = "var(--bg-2)"; }}
              onMouseLeave={(e) => { if (l.swapId) e.currentTarget.style.background = "transparent"; }}>
              <span style={{ color: "var(--fg-3)" }}>{new Date(l.ts).toISOString().slice(11, 23)}</span>
              <Badge tone={l.level === "warn" ? "warn" : l.level === "error" ? "err" : l.level === "debug" ? "neutral" : "info"} subtle>
                {l.level}
              </Badge>
              <span style={{ color: "var(--fg-2)" }}>{l.source}</span>
              <span style={{ color: "var(--fg-1)" }}>{l.msg}</span>
              <span style={{ color: "var(--fg-3)", textAlign: "right" }}>{l.swapId || ""}</span>
            </div>
          ))}
        </div>
      </Panel>
    </div>
  );
}

Object.assign(window, { ViewHealth, ViewOrderbook, ViewLogs });
