{% extends "base.html" %}
{% block title %}Federation — psyc admin{% endblock %}
{% block content %}

<section class="panel">
  <div class="panel-head">
    <h1>Federation Identity</h1>
    <span class="count">{{ peers|length }} peer{{ '' if peers|length == 1 else 's' }}</span>
  </div>
  <p class="page-intro">This node's Ed25519 identity. The fingerprint goes into a DNS TXT record so other psyc nodes can discover this one. The public key lets them verify any feed we publish — the private key never leaves this box.</p>
  <p class="back"><a href="/admin">← back to admin</a></p>

  <div class="card" style="margin-bottom:14px;">
    <div class="lg-sub">node fingerprint</div>
    <div style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:18px; word-break:break-all; margin:6px 0 12px; color:var(--accent); text-shadow:0 0 12px var(--accent-glow);">{{ fingerprint }}</div>
    <details>
      <summary class="lg-sub" style="cursor:pointer;">public key (PEM)</summary>
      <pre style="background:var(--panel-2); border:1px solid var(--border); border-radius:6px; padding:10px; margin-top:8px; overflow-x:auto; font-size:11.5px;">{{ pubkey_pem }}</pre>
    </details>
  </div>
</section>

<section class="panel">
  <div class="panel-head">
    <h2>Publish via DNS</h2>
    <span class="count">SRV + TXT records</span>
  </div>
  <p class="page-intro">Paste these into your zone file. Once they're live, any peer that knows your domain can discover the node and pin the right key without out-of-band coordination.</p>

  <form method="get" action="/admin/federation" class="lookup-form" style="margin-bottom:12px;">
    <input type="text" name="domain" value="{{ suggested_domain }}" class="lookup-input" placeholder="domain to publish on (e.g. psyc.example.com)">
    <button type="submit" class="btn btn-enforce">regenerate</button>
  </form>

  <pre style="background:var(--panel-2); border:1px solid var(--border); border-radius:6px; padding:12px; overflow-x:auto; font-size:12px; line-height:1.5;">{{ dns.human_instructions }}</pre>
</section>

<section class="panel">
  <div class="panel-head">
    <h2>Known Peers</h2>
    <span class="count">{{ peers|length }} registered</span>
  </div>
  <p class="page-intro">Trusted peers' feeds are signature-verified on every poll. Blocked peers are recorded but ignored. Unknown peers are kept for review — nothing flows from them until you set them trusted.</p>

  {% if peers %}
  <table class="ledger">
    <thead><tr><th>Domain</th><th>Fingerprint</th><th>Status</th><th>Discovered</th><th>Last seen</th><th></th></tr></thead>
    <tbody>
    {% for p in peers %}
      <tr class="ledger-row">
        <td><strong>{{ p.domain }}</strong></td>
        <td class="lg-sub" style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace;">{{ p.fingerprint[:8] }}…{{ p.fingerprint[-8:] }}</td>
        <td>
          {% if p.status == 'trusted' %}
            <span class="sev-badge" style="background:rgba(74,222,128,0.10); color:var(--green); border-color:var(--green);">trusted</span>
          {% elif p.status == 'blocked' %}
            <span class="sev-badge" style="background:rgba(248,113,113,0.10); color:var(--red); border-color:var(--red);">blocked</span>
          {% else %}
            <span class="sev-badge">unknown</span>
          {% endif %}
        </td>
        <td class="lg-ts">{{ (p.discovered_at or '')[:16] | replace('T', ' ') }}</td>
        <td class="lg-ts">{{ ((p.last_seen or '')[:16] | replace('T', ' ')) or '—' }}</td>
        <td>
          <form method="post" action="/admin/federation/peers/{{ p.domain }}/status" class="queue-action">
            <input type="hidden" name="status" value="trusted">
            <button type="submit" class="btn btn-enforce" {% if p.status == 'trusted' %}disabled{% endif %}>trust</button>
          </form>
          <form method="post" action="/admin/federation/peers/{{ p.domain }}/status" class="queue-action">
            <input type="hidden" name="status" value="blocked">
            <button type="submit" class="btn btn-reject" {% if p.status == 'blocked' %}disabled{% endif %}>block</button>
          </form>
          <form method="post" action="/admin/federation/peers/{{ p.domain }}/remove" class="queue-action"
                onsubmit="return confirm('Remove {{ p.domain }}? Their signals will no longer count toward quorum.');">
            <button type="submit" class="btn">remove</button>
          </form>
        </td>
      </tr>
    {% endfor %}
    </tbody>
  </table>
  {% else %}
  <p class="page-intro">(no peers yet — add one below)</p>
  {% endif %}
</section>

<section class="panel">
  <div class="panel-head">
    <h2>Add Peer</h2>
  </div>
  <p class="page-intro">Pin a peer's identity manually: their domain, their fingerprint (from their DNS TXT record), and the public key they publish at <code>/federation/key</code>.</p>
  <form method="post" action="/admin/federation/peers/add" style="display:grid; gap:10px; max-width:680px;">
    <input type="text" name="domain" placeholder="peer domain (e.g. peer.example.com)" class="lookup-input" required>
    <input type="text" name="fingerprint" placeholder="fingerprint (32 hex chars)" class="lookup-input" maxlength="64" required style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace;">
    <textarea name="pubkey_pem" placeholder="-----BEGIN PUBLIC KEY-----&#10;…&#10;-----END PUBLIC KEY-----" rows="6" class="lookup-input" required style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px;"></textarea>
    <select name="status" class="lookup-input">
      <option value="unknown">unknown — record only, don't trust yet</option>
      <option value="trusted">trusted — count toward quorum</option>
      <option value="blocked">blocked — ignore</option>
    </select>
    <button type="submit" class="btn btn-enforce">+ register peer</button>
  </form>
</section>

<section class="panel">
  <div class="panel-head">
    <h2>Recent Signals</h2>
    <span class="count">last {{ signals|length }} of buffer</span>
  </div>
  <p class="page-intro">Verified federation signals from peers — case + IOC reports awaiting quorum. The signal buffer is what later quorum logic will count over.</p>

  {% if signals %}
  <table class="ledger">
    <thead><tr><th>Received</th><th>Peer</th><th>Type</th><th>Id</th><th>Hash</th></tr></thead>
    <tbody>
    {% for s in signals %}
      <tr class="ledger-row">
        <td class="lg-ts">{{ (s.received_at or '')[:19] | replace('T', ' ') }}</td>
        <td class="lg-sub" style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace;">{{ s.peer_fingerprint[:8] }}…</td>
        <td><span class="sev-badge">{{ s.signal_type }}</span></td>
        <td style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px;">{{ s.signal_id[:48] }}</td>
        <td class="lg-sub" style="font-family:ui-monospace,SFMono-Regular,Menlo,monospace; font-size:11.5px;">{{ s.signal_hash[:16] }}…</td>
      </tr>
    {% endfor %}
    </tbody>
  </table>
  {% else %}
  <p class="page-intro">(no signals received yet — quorum stage will populate this)</p>
  {% endif %}
</section>

{% endblock %}
