// Swap detail view — FSM graph, on-chain refs, event timeline, parameters

function ViewSwapDetail({ swap, now, onBack, onAction }) {
  if (!swap) return <Empty>Select a swap to inspect.</Empty>;
  return (
    <div style={{ display: "flex", flexDirection: "column", padding: 14, gap: 12, height: "100%", minHeight: 0 }}>
      {/* Header */}
      <div style={{ display: "flex", alignItems: "center", gap: 12, flex: "none" }}>
        <Button size="sm" onClick={onBack} icon="←">Back</Button>
        <span className="mono" style={{ fontSize: 16, fontWeight: 600, color: "var(--fg-0)" }}>{swap.id}</span>
        <DirectionChip direction={swap.direction} />
        <Badge tone={swap.role === "alice" ? "alice" : "bob"}>role: {swap.role}</Badge>
        <StateChip state={swap.state} />
        {swap.stuck && <Badge tone="warn"><StatusDot status="warn" blink size={6} />stalled</Badge>}
        <span style={{ marginLeft: "auto", display: "flex", gap: 6 }}>
          <Button size="sm" icon="↻" onClick={() => onAction("rescan", swap)}>Rescan chains</Button>
          <Button size="sm" icon="⚙" onClick={() => onAction("force-refund", swap)} danger>Force refund</Button>
          <Button size="sm" variant="primary" icon="⏵" onClick={() => onAction("kick", swap)}>Kick FSM</Button>
        </span>
      </div>

      {/* Main grid */}
      <div style={{ display: "grid", gridTemplateColumns: "1.5fr 1fr", gap: 12, flex: 1, minHeight: 0 }}>
        {/* Left: FSM + chain refs + events */}
        <div style={{ display: "flex", flexDirection: "column", gap: 12, minHeight: 0 }}>
          <Panel title="FSM State Graph"
            right={<span style={{ fontSize: 11, color: "var(--fg-3)", fontFamily: "var(--mono)" }}>
              current: <span style={{ color: "var(--fg-0)" }}>{swap.state}</span>
            </span>}
            style={{ flex: "0 0 auto" }}>
            <FSMGraph currentState={swap.state} height={340} />
          </Panel>

          <Panel title="On-Chain References" padded={false}>
            <ChainRefTable swap={swap} />
          </Panel>

          <Panel title="Event Timeline" padded={false} style={{ flex: 1, minHeight: 160 }} scrollable>
            <EventTimeline events={swap.events} now={now} />
          </Panel>
        </div>

        {/* Right: parameters + countdowns + counterparty */}
        <div style={{ display: "flex", flexDirection: "column", gap: 12, minHeight: 0 }}>
          <Panel title="Swap Parameters">
            <ParamGrid
              rows={[
                ["Direction", <DirectionChip direction={swap.direction} />],
                ["Solver role", <Badge tone={swap.role === "alice" ? "alice" : "bob"}>{swap.role}</Badge>],
                ["Counterparty", <span className="mono">{swap.counterparty}</span>],
                ["Solver ID", <span className="mono" style={{ fontSize: 11 }}>{swap.solverId}</span>],
                ["Quote ID", <HashChip value={swap.quoteId} headLen={8} tailLen={4} />],
                [swap.direction === "btc-to-zec" ? "BTC amount" : "ZEC amount",
                  <span className="mono" style={{ color: "var(--fg-0)" }}>
                    {swap.direction === "btc-to-zec" ? ZW.fmtSats(swap.btcSats) + " BTC" : ZW.fmtZats(swap.zecZats) + " ZEC"}
                  </span>],
                ["Counter-amount",
                  <span className="mono" style={{ color: "var(--fg-2)" }}>
                    {swap.direction === "btc-to-zec" ? ZW.fmtZats(swap.zecZats) + " ZEC" : ZW.fmtSats(swap.btcSats) + " BTC"}
                  </span>],
                ["Implied rate",
                  <span className="mono" style={{ fontSize: 11 }}>{ZW.isFiniteNumber(swap.rateZecPerBtc) ? `${Number(swap.rateZecPerBtc).toFixed(2)} ZEC/BTC` : ZW.NA}</span>],
                ["Spread", <span className="mono">{ZW.isFiniteNumber(swap.spreadBps) ? `${swap.spreadBps} bps` : ZW.NA}</span>],
                ["USD value", <span className="mono">{ZW.fmtUsd(swap.usdValue)}</span>],
                ["Est. P&L", <span className="mono" style={{ color: ZW.isFiniteNumber(swap.pnlUsd) ? "var(--ok)" : "var(--fg-3)" }}>
                  {ZW.isFiniteNumber(swap.pnlUsd) ? "+" + ZW.fmtUsd(swap.pnlUsd) : ZW.NA}
                </span>],
              ]}
            />
          </Panel>

          <Panel title="Timelocks">
            <TimelockBlock swap={swap} now={now} />
          </Panel>

          <Panel title="Cryptographic Material" padded={false} style={{ flex: 1, minHeight: 0 }} scrollable>
            <ParamGrid compact rows={[
              ["swap_hash", <HashChip value={swap.swapHash} headLen={10} tailLen={6} />],
              ["Alice BTC addr", <HashChip value={swap.aliceAddress} headLen={10} tailLen={6} />],
              ["Joint ZEC UA",   <HashChip value={swap.bobAddress} headLen={10} tailLen={6} />],
              ["k_a", <span className="mono" style={{ color: swap.materialStatus?.kA === "redacted" ? "var(--fg-2)" : "var(--fg-3)" }}>{swap.materialStatus?.kA || ZW.NA}</span>],
              ["k_b", <span className="mono" style={{ color: swap.materialStatus?.kB === "redacted" ? "var(--fg-2)" : "var(--fg-3)" }}>{swap.materialStatus?.kB || ZW.NA}</span>],
              ["DLEq proof", swap.materialStatus?.dleqProof === "present" ? <Badge tone="ok" subtle>present</Badge> : <span className="mono">{ZW.NA}</span>],
              ["Hashbind",   swap.materialStatus?.hashbind === "present" ? <Badge tone="ok" subtle>present</Badge> : <span className="mono">{ZW.NA}</span>],
            ]} />
          </Panel>
        </div>
      </div>
    </div>
  );
}

function ChainRefTable({ swap }) {
  const refs = [
    { label: "BTC Lock TX", chain: "btc", value: swap.lockTxid, status: swap.lockTxid ? "confirmed" : "pending", height: swap.lockTxid ? swap.lockHeight : null },
    { label: "ZEC Deposit TX", chain: "zec", value: swap.zecDepositTxid, status: swap.zecDepositTxid ? "confirmed" : "pending", height: swap.zecDepositTxid ? 2_612_300 : null },
    { label: "BTC Buy TX", chain: "btc", value: swap.buyTxid, status: swap.buyTxid ? "confirmed" : "pending", height: swap.buyTxid ? swap.lockHeight + 4 : null },
    { label: "ZEC Orchard claim", chain: "zec", value: swap.orchardTxid, status: swap.orchardTxid ? "confirmed" : "pending", height: swap.orchardTxid ? 2_612_350 : null },
    { label: "BTC Refund TX", chain: "btc", value: swap.refundTxid, status: swap.refundTxid ? "confirmed" : ZW.NA, height: swap.refundTxid && ZW.isFiniteNumber(swap.lockHeight) ? swap.lockHeight + 144 : null },
  ];
  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      {refs.map((r, i) => (
        <div key={i} style={{
          display: "grid", gridTemplateColumns: "150px 50px 1fr 100px 80px",
          padding: "8px 14px", alignItems: "center", fontSize: 12,
          borderTop: i ? "1px solid var(--line-soft)" : "none",
        }}>
          <span style={{ color: "var(--fg-2)" }}>{r.label}</span>
          <Badge tone={r.chain === "btc" ? "btc" : "zec"} subtle>{r.chain.toUpperCase()}</Badge>
          {r.value
            ? <HashChip value={r.value} headLen={10} tailLen={8} />
            : <span style={{ color: "var(--fg-3)" }}>{ZW.NA}</span>}
          <span className="mono" style={{ color: "var(--fg-3)", fontSize: 11 }}>
            {r.height ? "blk " + r.height.toLocaleString() : ""}
          </span>
          {r.value
            ? <Badge tone="ok" subtle><StatusDot status="ok" size={6} />{r.status}</Badge>
            : <Badge tone="neutral" subtle>{ZW.NA}</Badge>}
        </div>
      ))}
    </div>
  );
}

function EventTimeline({ events, now }) {
  if (!events || events.length === 0) return <Empty>{ZW.NA}</Empty>;
  return (
    <div style={{ padding: "0 0 0 0" }}>
      {events.map((e, i) => (
        <div key={i} style={{
          display: "grid", gridTemplateColumns: "16px 90px 1fr 60px",
          gap: 8,
          padding: "8px 14px",
          borderTop: i ? "1px solid var(--line-soft)" : "none",
          fontSize: 12,
          alignItems: "start",
        }}>
          <span style={{ position: "relative", height: 16 }}>
            <span style={{
              position: "absolute", left: 4, top: 4,
              width: 8, height: 8, borderRadius: 999,
              background: e.kind === "warning" ? "var(--warn)" :
                          e.kind === "match_accepted" ? "var(--info)" :
                          "var(--alice)",
              boxShadow: "0 0 0 2px var(--bg-1)",
            }} />
            {i < (events.length - 1) && (
              <span style={{
                position: "absolute", left: 7.5, top: 14, bottom: -8,
                width: 1, background: "var(--line)",
              }} />
            )}
          </span>
          <span className="mono" style={{ fontSize: 10.5, color: "var(--fg-3)", textTransform: "uppercase", letterSpacing: 0.4 }}>{e.kind}</span>
          <span style={{ color: "var(--fg-1)", lineHeight: 1.5 }}>
            {e.from && e.to
              ? <span>
                  <span className="mono" style={{ color: "var(--fg-3)" }}>{e.from}</span>
                  <span style={{ margin: "0 6px", color: "var(--fg-3)" }}>→</span>
                  <span className="mono" style={{ color: "var(--fg-0)" }}>{e.to}</span>
                </span>
              : e.note}
          </span>
          <span className="mono" style={{ fontSize: 10.5, color: "var(--fg-3)", textAlign: "right" }}>
            {ZW.fmtRelTime(e.ts, now)} ago
          </span>
        </div>
      ))}
    </div>
  );
}

function ParamGrid({ rows, compact }) {
  return (
    <div style={{ display: "flex", flexDirection: "column" }}>
      {rows.map(([k, v], i) => (
        <div key={i} style={{
          display: "grid", gridTemplateColumns: "120px 1fr",
          padding: compact ? "5px 0" : "6px 0",
          fontSize: 12,
          borderTop: i ? "1px solid var(--line-soft)" : "none",
          alignItems: "center", gap: 8,
        }}>
          <span style={{ color: "var(--fg-2)", fontSize: 11 }}>{k}</span>
          <span>{v}</span>
        </div>
      ))}
    </div>
  );
}

function TimelockBlock({ swap, now }) {
  const t0 = ZW.isFiniteNumber(swap.csvDeadline) ? (swap.csvDeadline - now) / 1000 : null;
  const t1 = ZW.isFiniteNumber(swap.csv2Deadline) ? (swap.csv2Deadline - now) / 1000 : null;
  const t0Label = ZW.isFiniteNumber(swap.timelock0_blocks)
    ? `Lock CSV (timelock₀ · ${swap.timelock0_blocks} blocks)`
    : "Lock CSV (timelock₀)";
  const t1Label = ZW.isFiniteNumber(swap.timelock1_blocks)
    ? `Refund CSV (timelock₁ · ${swap.timelock1_blocks} blocks)`
    : "Refund CSV (timelock₁)";
  function bar(secsRemaining, totalSecs, color) {
    if (secsRemaining == null) return null;
    const pct = Math.max(0, Math.min(1, secsRemaining / totalSecs));
    return (
      <div style={{ position: "relative", height: 6, background: "var(--bg-3)", borderRadius: 3, overflow: "hidden" }}>
        <div style={{
          position: "absolute", left: 0, top: 0, bottom: 0,
          width: `${pct * 100}%`,
          background: pct < 0.2 ? "var(--err)" : pct < 0.5 ? "var(--warn)" : color,
          transition: "width 600ms",
        }} />
      </div>
    );
  }

  return (
    <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
      <div>
        <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 5 }}>
          <span style={{ fontSize: 11, color: "var(--fg-2)" }}>{t0Label}</span>
          <span className="mono" style={{ fontSize: 12, color: t0 != null && t0 < 1800 ? "var(--warn)" : "var(--fg-0)" }}>
            {t0 != null ? ZW.fmtCountdown(t0) : ZW.NA}
          </span>
        </div>
        {bar(t0, 24 * 3600, "var(--alice)")}
      </div>
      <div>
        <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 5 }}>
          <span style={{ fontSize: 11, color: "var(--fg-2)" }}>{t1Label}</span>
          <span className="mono" style={{ fontSize: 12, color: t1 != null && t1 < 1800 ? "var(--warn)" : "var(--fg-0)" }}>
            {t1 != null ? ZW.fmtCountdown(t1) : ZW.NA}
          </span>
        </div>
        {bar(t1, 24 * 3600, "var(--info)")}
      </div>
      <div style={{ fontSize: 11, color: "var(--fg-3)", display: "flex", justifyContent: "space-between" }}>
        <span>Lock height: <span className="mono" style={{ color: "var(--fg-1)" }}>{ZW.fmtInt(swap.lockHeight)}</span></span>
        <span>BTC tip: <span className="mono" style={{ color: "var(--fg-1)" }}>{ZW.fmtInt(swap.btcTip)}</span></span>
      </div>
    </div>
  );
}

Object.assign(window, { ViewSwapDetail });
