<h1>Monitoring</h1>

<% if (forbidden) { %>
  <div class="alert alert-danger">Your role does not have permission to view monitoring data.</div>
<% } else { %>

<% if (checkResult) { %>
  <div class="alert <%= checkResult.ok ? 'alert-ok' : 'alert-danger' %>"><%= checkResult.message %></div>
<% } %>

<div class="card">
  <div style="display:flex;justify-content:space-between;align-items:center">
    <h2 style="font-size:15px;margin:0">Service Health</h2>
    <form method="post" action="/monitoring/health/run" id="health-check-form">
      <button class="btn" type="submit" id="health-check-btn">Run Check Now</button>
    </form>
  </div>
  <div class="progress-track" id="health-check-progress"><div class="progress-bar"></div></div>
  <div style="display:flex;gap:24px;flex-wrap:wrap;margin-top:16px">
    <% for (const s of services) { %>
    <div style="min-width:160px">
      <p style="color:var(--muted);font-size:11px;text-transform:uppercase"><%= s.service %></p>
      <span class="badge <%= { up: 'badge-ok', degraded: 'badge-warn', down: 'badge-danger', unknown: 'badge-warn' }[s.status] %>"><%= s.status %></span>
      <p style="margin:6px 0 0;font-size:12px">Latency: <%= s.latencyMs != null ? s.latencyMs + 'ms' : '—' %></p>
      <p style="margin:2px 0 0;font-size:12px">24h uptime: <%= s.uptimePercent24h != null ? s.uptimePercent24h + '%' : '—' %></p>
    </div>
    <% } %>
  </div>
</div>

<div class="card">
  <h2 style="font-size:15px;margin-top:0">Recent Background Job Runs</h2>
  <p style="color:var(--muted);font-size:12px;margin:0 0 12px">
    tenant-api's own scheduled jobs — reminder emails, invoice-overdue sweeps, recurring invoices,
    email sync, and the rest of its cron schedule (see backend/jobs/scheduler.js) — not this admin
    console's health checks. Every job writes its own run here through a shared wrapper the moment it
    starts and finishes, so this is a live log, not a snapshot: "running" means still in progress right now.
  </p>
  <table>
    <thead><tr><th>Job</th><th>Status</th><th>Started</th><th>Duration</th><th>Error</th></tr></thead>
    <tbody>
      <% for (const j of jobRuns) { %>
      <tr>
        <td><%= j.job_name %></td>
        <td><span class="badge <%= { succeeded: 'badge-ok', running: 'badge-warn', failed: 'badge-danger' }[j.status] %>"><%= j.status %></span></td>
        <td><%= new Date(j.started_at).toLocaleString() %></td>
        <td><%= j.duration_ms != null ? j.duration_ms + 'ms' : '—' %></td>
        <td style="color:var(--danger);font-size:12px"><%= j.error_message || '' %></td>
      </tr>
      <% } %>
      <% if (!jobRuns.length) { %><tr><td colspan="5" style="color:var(--muted)">No job runs recorded yet.</td></tr><% } %>
    </tbody>
  </table>
</div>

<div class="card">
  <h2 style="font-size:15px;margin-top:0">Deployments</h2>
  <p style="color:var(--muted);font-size:12px;margin:0 0 12px">
    Detected automatically — each service reports its own version and commit on its health endpoint,
    and a new row appears here the moment a health check (manual or scheduled) sees that change.
    No one needs to remember to log a deploy by hand.
  </p>
  <table>
    <thead><tr><th>Service</th><th>Version</th><th>Status</th><th>Recorded By</th><th>When</th><th></th></tr></thead>
    <tbody>
      <% for (const d of deployments) { %>
      <tr>
        <td><%= d.service_name %></td>
        <td><code class="mono"><%= d.version %></code><% if (d.commit_sha) { %> <span style="color:var(--muted);font-size:11px">@<%= d.commit_sha %></span><% } %></td>
        <td><span class="badge <%= { succeeded: 'badge-ok', in_progress: 'badge-warn', failed: 'badge-danger', rolled_back: 'badge-danger' }[d.status] %>"><%= d.status %></span></td>
        <td><%= d.deployed_by %></td>
        <td><%= new Date(d.deployed_at).toLocaleString() %></td>
        <td><% if (d.status === 'succeeded' && !d.rollback_of) { %><form method="post" action="/monitoring/deployments/<%= d.id %>/rollback"><button class="link-btn" type="submit">Rollback</button></form><% } %></td>
      </tr>
      <% } %>
      <% if (!deployments.length) { %><tr><td colspan="6" style="color:var(--muted)">No deployments detected yet — run a health check once each service is up.</td></tr><% } %>
    </tbody>
  </table>
</div>

<div class="card">
  <h2 style="font-size:15px;margin-top:0">Database Migrations (tenant-api)</h2>
  <p style="color:var(--muted);font-size:12px;margin:0 0 12px">
    Read-only view of every migration file on tenant-api's disk cross-referenced against its
    <code class="mono">knex_migrations</code> table. Moved here from the firm-facing Settings page — schema/migration
    state is shared-backend infrastructure, not something any single firm's admin should see or act on. Migrations
    themselves are still applied manually via <code class="mono">npm run migrate</code>, never from this UI.
  </p>
  <% if (migrationsSummary) { %>
  <div style="display:flex;gap:24px;flex-wrap:wrap;margin-bottom:16px">
    <div><p style="color:var(--muted);font-size:11px;text-transform:uppercase">Total</p><p style="margin:2px 0 0;font-size:14px"><%= migrationsSummary.total %></p></div>
    <div><p style="color:var(--muted);font-size:11px;text-transform:uppercase">Applied</p><p style="margin:2px 0 0;font-size:14px"><%= migrationsSummary.applied %></p></div>
    <div><p style="color:var(--muted);font-size:11px;text-transform:uppercase">Pending</p><p style="margin:2px 0 0;font-size:14px"><span class="badge <%= migrationsSummary.pending ? 'badge-warn' : 'badge-ok' %>"><%= migrationsSummary.pending %></span></p></div>
    <div><p style="color:var(--muted);font-size:11px;text-transform:uppercase">Current Batch</p><p style="margin:2px 0 0;font-size:14px"><%= migrationsSummary.currentBatch %></p></div>
    <div><p style="color:var(--muted);font-size:11px;text-transform:uppercase">Last Applied</p><p style="margin:2px 0 0;font-size:14px"><%= migrationsSummary.lastAppliedAt ? new Date(migrationsSummary.lastAppliedAt).toLocaleString() : '—' %></p></div>
  </div>
  <% } %>
  <% if (migrationsOrphaned && migrationsOrphaned.length) { %>
  <div class="alert alert-danger" style="margin-bottom:12px">
    <%= migrationsOrphaned.length %> migration(s) recorded as applied whose file no longer exists on disk — possible drift: <%= migrationsOrphaned.map(o => o.name).join(', ') %>
  </div>
  <% } %>
  <table>
    <thead><tr><th>Migration</th><th>Status</th><th>Batch</th><th>Applied</th></tr></thead>
    <tbody>
      <% for (const m of migrations) { %>
      <tr>
        <td><code class="mono"><%= m.name %></code></td>
        <td><span class="badge <%= m.status === 'applied' ? 'badge-ok' : 'badge-warn' %>"><%= m.status %></span></td>
        <td><%= m.batch != null ? m.batch : '—' %></td>
        <td><%= m.appliedAt ? new Date(m.appliedAt).toLocaleString() : '—' %></td>
      </tr>
      <% } %>
      <% if (!migrations.length) { %><tr><td colspan="4" style="color:var(--muted)">No migration files found.</td></tr><% } %>
    </tbody>
  </table>
</div>

<% } %>
