{% extends "base.html" %}

{% block title %}Monitoring — Timmy Time{% endblock %}

{% block content %}
<!-- Page header -->
<div class="card">
  <div class="card-header">
    <h2 class="card-title">Real-Time Monitoring</h2>
    <div class="d-flex align-items-center gap-2">
      <span class="badge" id="mon-overall-badge">Loading...</span>
      <span class="mon-last-updated" id="mon-last-updated"></span>
    </div>
  </div>

  <!-- Uptime stat bar -->
  <div class="grid grid-4">
    <div class="stat">
      <div class="stat-value" id="mon-uptime">—</div>
      <div class="stat-label">Uptime</div>
    </div>
    <div class="stat">
      <div class="stat-value" id="mon-agents-count">—</div>
      <div class="stat-label">Agents</div>
    </div>
    <div class="stat">
      <div class="stat-value" id="mon-alerts-count">0</div>
      <div class="stat-label">Alerts</div>
    </div>
    <div class="stat">
      <div class="stat-value" id="mon-ollama-badge">—</div>
      <div class="stat-label">LLM Backend</div>
    </div>
  </div>
</div>

<!-- Alerts panel (conditionally shown) -->
<div class="card mc-card-spaced" id="mon-alerts-card" style="display:none">
  <div class="card-header">
    <h2 class="card-title">Alerts</h2>
    <span class="badge badge-danger" id="mon-alerts-badge">0</span>
  </div>
  <div id="mon-alerts-list"></div>
</div>

<!-- Agent Status -->
<div class="card mc-card-spaced">
  <div class="card-header">
    <h2 class="card-title">Agent Status</h2>
  </div>
  <div id="mon-agents-list">
    <p class="chat-history-placeholder">Loading agents...</p>
  </div>
</div>

<!-- System Resources + Economy row -->
<div class="grid grid-2 mc-card-spaced mc-section-gap">

  <!-- System Resources -->
  <div class="card">
    <div class="card-header">
      <h2 class="card-title">System Resources</h2>
    </div>
    <div class="grid grid-2">
      <div class="stat">
        <div class="stat-value" id="mon-cpu">—</div>
        <div class="stat-label">CPU</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-ram">—</div>
        <div class="stat-label">RAM</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-disk">—</div>
        <div class="stat-label">Disk</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-models-loaded">—</div>
        <div class="stat-label">Models Loaded</div>
      </div>
    </div>
    <!-- Resource bars -->
    <div class="mon-resource-bars" id="mon-resource-bars">
      <div class="mon-bar-row">
        <span class="mon-bar-label">RAM</span>
        <div class="mon-bar-track">
          <div class="mon-bar-fill" id="mon-ram-bar" style="width:0%"></div>
        </div>
        <span class="mon-bar-pct" id="mon-ram-pct">—</span>
      </div>
      <div class="mon-bar-row">
        <span class="mon-bar-label">Disk</span>
        <div class="mon-bar-track">
          <div class="mon-bar-fill" id="mon-disk-bar" style="width:0%"></div>
        </div>
        <span class="mon-bar-pct" id="mon-disk-pct">—</span>
      </div>
      <div class="mon-bar-row" id="mon-cpu-bar-row">
        <span class="mon-bar-label">CPU</span>
        <div class="mon-bar-track">
          <div class="mon-bar-fill" id="mon-cpu-bar" style="width:0%"></div>
        </div>
        <span class="mon-bar-pct" id="mon-cpu-pct">—</span>
      </div>
    </div>
  </div>

  <!-- Economy -->
  <div class="card">
    <div class="card-header">
      <h2 class="card-title">Economy</h2>
    </div>
    <div class="grid grid-2">
      <div class="stat">
        <div class="stat-value" id="mon-balance">—</div>
        <div class="stat-label">Balance (sats)</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-earned">—</div>
        <div class="stat-label">Earned</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-spent">—</div>
        <div class="stat-label">Spent</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-injections">—</div>
        <div class="stat-label">Injections</div>
      </div>
    </div>
    <div class="grid grid-2 mc-section-heading">
      <div class="stat">
        <div class="stat-value" id="mon-tx-count">—</div>
        <div class="stat-label">Transactions</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-auction">—</div>
        <div class="stat-label">Auction</div>
      </div>
    </div>
  </div>
</div>

<!-- Stream Health + Content Pipeline row -->
<div class="grid grid-2 mc-card-spaced mc-section-gap">

  <!-- Stream Health -->
  <div class="card">
    <div class="card-header">
      <h2 class="card-title">Stream Health</h2>
      <span class="badge" id="mon-stream-badge">Offline</span>
    </div>
    <div class="grid grid-2">
      <div class="stat">
        <div class="stat-value" id="mon-viewers">—</div>
        <div class="stat-label">Viewers</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-bitrate">—</div>
        <div class="stat-label">Bitrate (kbps)</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-stream-uptime">—</div>
        <div class="stat-label">Stream Uptime</div>
      </div>
      <div class="stat">
        <div class="stat-value mon-stream-title" id="mon-stream-title">—</div>
        <div class="stat-label">Title</div>
      </div>
    </div>
  </div>

  <!-- Content Pipeline -->
  <div class="card">
    <div class="card-header">
      <h2 class="card-title">Content Pipeline</h2>
      <span class="badge" id="mon-pipeline-badge">—</span>
    </div>
    <div class="grid grid-2">
      <div class="stat">
        <div class="stat-value" id="mon-highlights">—</div>
        <div class="stat-label">Highlights</div>
      </div>
      <div class="stat">
        <div class="stat-value" id="mon-clips">—</div>
        <div class="stat-label">Clips</div>
      </div>
    </div>
    <div class="mon-last-episode" id="mon-last-episode-wrap" style="display:none">
      <span class="mon-bar-label">Last episode: </span>
      <span id="mon-last-episode">—</span>
    </div>
  </div>
</div>

<script>
// -----------------------------------------------------------------------
// Utility
// -----------------------------------------------------------------------
function _pct(val) {
  if (val === null || val === undefined) return '—';
  return val.toFixed(0) + '%';
}

function _barColor(pct) {
  if (pct >= 90) return 'var(--red)';
  if (pct >= 75) return 'var(--amber)';
  return 'var(--green)';
}

function _setBar(barId, pct) {
  var bar = document.getElementById(barId);
  if (!bar) return;
  var w = Math.min(100, Math.max(0, pct || 0));
  bar.style.width = w + '%';
  bar.style.background = _barColor(w);
}

function _uptime(secs) {
  if (!secs && secs !== 0) return '—';
  secs = Math.floor(secs);
  if (secs < 60) return secs + 's';
  if (secs < 3600) return Math.floor(secs / 60) + 'm';
  var h = Math.floor(secs / 3600);
  var m = Math.floor((secs % 3600) / 60);
  return h + 'h ' + m + 'm';
}

function _setText(id, val) {
  var el = document.getElementById(id);
  if (el) el.textContent = (val !== null && val !== undefined) ? val : '—';
}

// -----------------------------------------------------------------------
// Render helpers
// -----------------------------------------------------------------------
function renderAgents(agents) {
  var container = document.getElementById('mon-agents-list');
  if (!agents || agents.length === 0) {
    container.innerHTML = '';
    var p = document.createElement('p');
    p.className = 'chat-history-placeholder';
    p.textContent = 'No agents configured';
    container.appendChild(p);
    return;
  }
  container.innerHTML = '';
  agents.forEach(function(a) {
    var row = document.createElement('div');
    row.className = 'mon-agent-row';

    var dot = document.createElement('span');
    dot.className = 'mon-agent-dot';
    dot.style.background = a.status === 'running' ? 'var(--green)' :
                           a.status === 'idle'    ? 'var(--amber)' : 'var(--red)';

    var name = document.createElement('span');
    name.className = 'mon-agent-name';
    name.textContent = a.name;

    var model = document.createElement('span');
    model.className = 'mon-agent-model';
    model.textContent = a.model;

    var status = document.createElement('span');
    status.className = 'mon-agent-status';
    status.textContent = a.status || '—';

    var action = document.createElement('span');
    action.className = 'mon-agent-action';
    action.textContent = a.last_action || '—';

    row.appendChild(dot);
    row.appendChild(name);
    row.appendChild(model);
    row.appendChild(status);
    row.appendChild(action);
    container.appendChild(row);
  });
}

function renderAlerts(alerts) {
  var card = document.getElementById('mon-alerts-card');
  var list = document.getElementById('mon-alerts-list');
  var badge = document.getElementById('mon-alerts-badge');
  var countEl = document.getElementById('mon-alerts-count');

  badge.textContent = alerts.length;
  countEl.textContent = alerts.length;

  if (alerts.length === 0) {
    card.style.display = 'none';
    return;
  }
  card.style.display = '';
  list.innerHTML = '';
  alerts.forEach(function(a) {
    var item = document.createElement('div');
    item.className = 'mon-alert-item mon-alert-' + (a.level || 'warning');
    var title = document.createElement('strong');
    title.textContent = a.title;
    var detail = document.createElement('span');
    detail.className = 'mon-alert-detail';
    detail.textContent = ' — ' + (a.detail || '');
    item.appendChild(title);
    item.appendChild(detail);
    list.appendChild(item);
  });
}

function renderResources(r) {
  _setText('mon-cpu', r.cpu_percent !== null ? r.cpu_percent.toFixed(0) + '%' : '—');
  _setText('mon-ram',
    r.ram_available_gb !== null
      ? r.ram_available_gb.toFixed(1) + ' GB free'
      : '—'
  );
  _setText('mon-disk',
    r.disk_free_gb !== null
      ? r.disk_free_gb.toFixed(1) + ' GB free'
      : '—'
  );
  _setText('mon-models-loaded', r.loaded_models ? r.loaded_models.length : '—');

  if (r.ram_percent !== null) {
    _setBar('mon-ram-bar', r.ram_percent);
    _setText('mon-ram-pct', _pct(r.ram_percent));
  }
  if (r.disk_percent !== null) {
    _setBar('mon-disk-bar', r.disk_percent);
    _setText('mon-disk-pct', _pct(r.disk_percent));
  }
  if (r.cpu_percent !== null) {
    _setBar('mon-cpu-bar', r.cpu_percent);
    _setText('mon-cpu-pct', _pct(r.cpu_percent));
  }

  var ollamaBadge = document.getElementById('mon-ollama-badge');
  ollamaBadge.textContent = r.ollama_reachable ? 'Online' : 'Offline';
  ollamaBadge.style.color = r.ollama_reachable ? 'var(--green)' : 'var(--red)';
}

function renderEconomy(e) {
  _setText('mon-balance', e.balance_sats);
  _setText('mon-earned', e.earned_sats);
  _setText('mon-spent', e.spent_sats);
  _setText('mon-injections', e.injection_count);
  _setText('mon-tx-count', e.tx_count);
  _setText('mon-auction', e.auction_active ? 'Active' : 'None');
}

function renderStream(s) {
  var badge = document.getElementById('mon-stream-badge');
  if (s.live) {
    badge.textContent = 'LIVE';
    badge.className = 'badge badge-success';
  } else {
    badge.textContent = 'Offline';
    badge.className = 'badge badge-danger';
  }
  _setText('mon-viewers', s.viewer_count);
  _setText('mon-bitrate', s.bitrate_kbps);
  _setText('mon-stream-uptime', _uptime(s.uptime_seconds));
  _setText('mon-stream-title', s.title || '—');
}

function renderPipeline(p) {
  var badge = document.getElementById('mon-pipeline-badge');
  badge.textContent = p.pipeline_healthy ? 'Healthy' : 'Degraded';
  badge.className = p.pipeline_healthy ? 'badge badge-success' : 'badge badge-warning';
  _setText('mon-highlights', p.highlight_count);
  _setText('mon-clips', p.clip_count);
  if (p.last_episode) {
    var wrap = document.getElementById('mon-last-episode-wrap');
    wrap.style.display = '';
    _setText('mon-last-episode', p.last_episode);
  }
}

// -----------------------------------------------------------------------
// Poll /monitoring/status
// -----------------------------------------------------------------------
async function pollMonitoring() {
  try {
    var resp = await fetch('/monitoring/status');
    if (!resp.ok) throw new Error('HTTP ' + resp.status);
    var data = await resp.json();

    // Overall badge
    var overall = document.getElementById('mon-overall-badge');
    var alertCount = (data.alerts || []).length;
    if (alertCount === 0) {
      overall.textContent = 'All Systems Nominal';
      overall.className = 'badge badge-success';
    } else {
      var critical = (data.alerts || []).filter(function(a) { return a.level === 'critical'; });
      overall.textContent = critical.length > 0 ? 'Critical Issues' : 'Warnings';
      overall.className = critical.length > 0 ? 'badge badge-danger' : 'badge badge-warning';
    }

    // Uptime
    _setText('mon-uptime', _uptime(data.uptime_seconds));
    _setText('mon-agents-count', (data.agents || []).length);

    // Last updated
    var updEl = document.getElementById('mon-last-updated');
    if (updEl) updEl.textContent = 'Updated ' + new Date().toLocaleTimeString();

    // Panels
    renderAgents(data.agents || []);
    renderAlerts(data.alerts || []);
    if (data.resources) renderResources(data.resources);
    if (data.economy) renderEconomy(data.economy);
    if (data.stream) renderStream(data.stream);
    if (data.pipeline) renderPipeline(data.pipeline);

  } catch (err) {
    console.error('Monitoring poll failed:', err);
    var overall = document.getElementById('mon-overall-badge');
    overall.textContent = 'Poll Error';
    overall.className = 'badge badge-danger';
  }
}

// Start immediately, then every 10 s
pollMonitoring();
setInterval(pollMonitoring, 10000);
</script>
{% endblock %}
