<div class="grid min-h-0 flex-1 grid-cols-[minmax(0,1fr)_20rem] overflow-hidden bg-background/50">
  <section class="relative min-h-0 border-r border-border bg-background/70">
    <div
      #graph
      class="h-full min-h-[22rem] w-full"
    ></div>

    <div class="pointer-events-none absolute left-3 top-3 rounded-xl border border-border/80 bg-card/90 px-3 py-2 shadow-xl backdrop-blur-sm">
      <div class="flex flex-wrap gap-2 text-[11px] font-medium text-foreground">
        <span class="rounded-full border border-border bg-secondary px-2 py-0.5">{{ snapshot().summary.clientCount }} clients</span>
        <span class="rounded-full border border-border bg-secondary px-2 py-0.5">{{ snapshot().summary.serverCount }} servers</span>
        <span class="rounded-full border border-border bg-secondary px-2 py-0.5">{{ snapshot().summary.peerConnectionCount }} peer links</span>
        <span class="rounded-full border border-border bg-secondary px-2 py-0.5">{{ snapshot().summary.messageCount }} grouped messages</span>
      </div>

      <div class="mt-2 flex flex-wrap gap-2 text-[10px] text-muted-foreground">
        <span class="rounded-full border border-blue-400/40 bg-blue-500/10 px-2 py-0.5 text-blue-200">Local client</span>
        <span class="rounded-full border border-emerald-400/40 bg-emerald-500/10 px-2 py-0.5 text-emerald-200">Remote client</span>
        <span class="rounded-full border border-orange-400/40 bg-orange-500/10 px-2 py-0.5 text-orange-200">Signaling</span>
        <span class="rounded-full border border-violet-400/40 bg-violet-500/10 px-2 py-0.5 text-violet-200">Server</span>
      </div>
    </div>

    @if (snapshot().edges.length === 0) {
      <div class="pointer-events-none absolute inset-0 flex items-center justify-center px-8 text-center">
        <div class="max-w-sm rounded-2xl border border-border/80 bg-card/85 px-5 py-4 shadow-xl backdrop-blur-sm">
          <p class="text-sm font-semibold text-foreground">No network activity captured yet.</p>
          <p class="mt-1 text-xs text-muted-foreground">
            Enable debugging before connecting to signaling, joining a server, or opening peer channels to populate the live map.
          </p>
        </div>
      </div>
    }
  </section>

  <aside class="min-h-0 overflow-y-auto bg-card/60">
    <div class="space-y-4 p-4">
      <section>
        <div class="flex items-center justify-between gap-3">
          <h3 class="text-sm font-semibold text-foreground">Peer details</h3>
          <span class="text-[11px] text-muted-foreground">Updated {{ formatAge(snapshot().generatedAt) }}</span>
        </div>

        @if (statusNodes().length === 0) {
          <p class="mt-2 text-xs text-muted-foreground">
            Connected clients appear here with IDs, handshakes, text counts, streams, drops, and live download metrics.
          </p>
        } @else {
          <div class="mt-3 space-y-2">
            @for (node of statusNodes(); track node.id) {
              <article class="rounded-xl border border-border/80 bg-background/70 px-3 py-2">
                <div class="flex items-start justify-between gap-3">
                  <div class="min-w-0">
                    <p class="truncate text-sm font-medium text-foreground">{{ node.label }}</p>
                    <p class="truncate text-[11px] text-muted-foreground">{{ node.secondaryLabel }}</p>
                    <p class="mt-1 break-all text-[10px] text-muted-foreground/90">ID {{ formatClientId(node) }}</p>

                    @if (formatPeerIdentity(node); as peerIdentity) {
                      <p class="mt-0.5 break-all text-[10px] text-muted-foreground/80">Peer {{ peerIdentity }}</p>
                    }
                  </div>

                  <span [class]="getStatusBadgeClass(node)">
                    {{ getNodeActivityLabel(node) }}
                  </span>
                </div>

                <div class="mt-2 flex flex-wrap gap-1.5">
                  @for (status of node.statuses; track status) {
                    <span class="rounded-full border border-border bg-secondary/70 px-2 py-0.5 text-[10px] text-muted-foreground">{{ status }}</span>
                  }
                </div>

                <div class="mt-3 grid grid-cols-1 gap-2 text-[11px] text-muted-foreground sm:grid-cols-2">
                  <div class="rounded-lg border border-border/70 bg-secondary/30 px-2.5 py-2">
                    <p class="font-medium text-foreground/90">Streams</p>
                    <p
                      class="mt-1"
                      title="A = audio streams, V = video streams"
                    >
                      Streams
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="Audio streams"
                        >A</span
                      >{{ node.streams.audio }}
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="Video streams"
                        >V</span
                      >{{ node.streams.video }}
                    </p>
                  </div>

                  <div class="rounded-lg border border-border/70 bg-secondary/30 px-2.5 py-2">
                    <p class="font-medium text-foreground/90">Text</p>
                    <p
                      class="mt-1"
                      title="Up arrow = sent messages, down arrow = received messages"
                    >
                      Text
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="Sent messages"
                        >↑</span
                      >{{ node.textMessages.sent }}
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="Received messages"
                        >↓</span
                      >{{ node.textMessages.received }}
                    </p>
                  </div>

                  <div class="rounded-lg border border-border/70 bg-secondary/30 px-2.5 py-2 sm:col-span-2">
                    <p class="font-medium text-foreground/90">Handshakes</p>
                    <p
                      class="mt-1"
                      title="Counts are shown as sent / received"
                    >
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="WebRTC offers"
                        >O</span
                      >
                      {{ node.handshake.offersSent }}/{{ node.handshake.offersReceived }}
                      ·
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="WebRTC answers"
                        >A</span
                      >
                      {{ node.handshake.answersSent }}/{{ node.handshake.answersReceived }}
                      ·
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="ICE candidates"
                        >ICE</span
                      >
                      {{ node.handshake.iceSent }}/{{ node.handshake.iceReceived }}
                    </p>
                  </div>

                  <div class="rounded-lg border border-border/70 bg-secondary/30 px-2.5 py-2 sm:col-span-2">
                    <p class="font-medium text-foreground/90">Download Mbps</p>
                    <p
                      class="mt-1"
                      title="Down arrow = download rate. F = file, A = audio, V = video."
                    >
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="Download rate"
                        >↓</span
                      >
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="File download Mbps"
                        >F</span
                      >
                      {{ formatMbps(node.downloads.fileMbps) }}
                      ·
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="Audio download Mbps"
                        >A</span
                      >
                      {{ formatMbps(node.downloads.audioMbps) }}
                      ·
                      <span
                        class="cursor-help underline decoration-dotted underline-offset-2"
                        title="Video download Mbps"
                        >V</span
                      >
                      {{ formatMbps(node.downloads.videoMbps) }}
                    </p>
                  </div>

                  <div class="rounded-lg border border-border/70 bg-secondary/30 px-2.5 py-2">
                    <p class="font-medium text-foreground/90">Ping</p>
                    <p class="mt-1">{{ node.pingMs !== null ? node.pingMs + ' ms' : '-' }}</p>
                  </div>

                  <div class="rounded-lg border border-border/70 bg-secondary/30 px-2.5 py-2">
                    <p class="font-medium text-foreground/90">Connection drops</p>
                    <p class="mt-1">{{ node.connectionDrops }}</p>
                  </div>
                </div>
              </article>
            }
          </div>
        }
      </section>

      <section>
        <div class="flex items-center justify-between gap-3">
          <h3 class="text-sm font-semibold text-foreground">Connection flows</h3>
          <span class="text-[11px] text-muted-foreground">Grouped by edge + message type</span>
        </div>

        @if (connectionEdges().length === 0) {
          <p class="mt-2 text-xs text-muted-foreground">Once logs arrive, each edge will show grouped signaling or P2P message types with counts.</p>
        } @else {
          <div class="mt-3 space-y-3">
            @for (edge of connectionEdges(); track edge.id) {
              <article class="rounded-xl border border-border/80 bg-background/70 px-3 py-3">
                <div class="flex items-start justify-between gap-3">
                  <div class="min-w-0">
                    <p class="truncate text-sm font-medium text-foreground">{{ formatEdgeHeading(edge) }}</p>
                    <p class="mt-0.5 text-[11px] text-muted-foreground">{{ edge.stateLabel }} · {{ formatAge(edge.lastSeen) }}</p>
                  </div>

                  <span [class]="getConnectionBadgeClass(edge)">
                    {{ getEdgeKindLabel(edge) }}
                  </span>
                </div>

                <div class="mt-2 flex flex-wrap gap-1.5 text-[10px] text-muted-foreground">
                  @if (edge.pingMs !== null) {
                    <span class="rounded-full border border-border bg-secondary/70 px-2 py-0.5">Ping {{ edge.pingMs }} ms</span>
                  }

                  <span class="rounded-full border border-border bg-secondary/70 px-2 py-0.5">{{ edge.messageTotal }} grouped messages</span>
                </div>

                @if (edge.messageGroups.length > 0) {
                  <div class="mt-3 flex flex-wrap gap-1.5">
                    @for (group of getVisibleMessageGroups(edge); track group.id) {
                      <span [class]="getMessageBadgeClass(group)">{{ formatMessageGroup(group) }}</span>
                    }

                    <span
                      class="rounded-full border border-border bg-secondary/70 px-2 py-0.5 text-[10px] text-muted-foreground"
                      [class.hidden]="getHiddenMessageGroupCount(edge) === 0"
                      >+{{ getHiddenMessageGroupCount(edge) }} more</span
                    >
                  </div>
                } @else {
                  <p class="mt-3 text-[11px] text-muted-foreground">No grouped messages on this edge yet.</p>
                }
              </article>
            }
          </div>
        }
      </section>
    </div>
  </aside>
</div>
