{% extends "base.html" %}

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

{% block extra_styles %}{% endblock %}

{% block content %}
<div class="container-fluid tower-container py-3">

  <div class="tower-header">
    <div class="tower-title">TOWER</div>
    <div class="tower-subtitle">
      Real-time Spark visualization &mdash;
      <span id="tower-conn" class="tower-conn-badge tower-conn-connecting">CONNECTING</span>
    </div>
  </div>

  <div class="row g-3">

    <!-- Left: THINKING (events) -->
    <div class="col-12 col-lg-4 d-flex flex-column gap-3">
      <div class="card mc-panel tower-phase-card">
        <div class="card-header mc-panel-header tower-phase-thinking">// THINKING</div>
        <div class="card-body p-3 tower-scroll" id="tower-events">
          <div class="tower-empty">Waiting for Spark data&hellip;</div>
        </div>
      </div>
    </div>

    <!-- Middle: PREDICTING (EIDOS) -->
    <div class="col-12 col-lg-4 d-flex flex-column gap-3">
      <div class="card mc-panel tower-phase-card">
        <div class="card-header mc-panel-header tower-phase-predicting">// PREDICTING</div>
        <div class="card-body p-3" id="tower-predictions">
          <div class="tower-empty">Waiting for Spark data&hellip;</div>
        </div>
      </div>
      <div class="card mc-panel">
        <div class="card-header mc-panel-header">// EIDOS STATS</div>
        <div class="card-body p-3">
          <div class="tower-stat-grid" id="tower-stats">
            <div class="tower-stat"><span class="tower-stat-label">EVENTS</span><span class="tower-stat-value" id="ts-events">0</span></div>
            <div class="tower-stat"><span class="tower-stat-label">MEMORIES</span><span class="tower-stat-value" id="ts-memories">0</span></div>
            <div class="tower-stat"><span class="tower-stat-label">PREDICTIONS</span><span class="tower-stat-value" id="ts-preds">0</span></div>
            <div class="tower-stat"><span class="tower-stat-label">ACCURACY</span><span class="tower-stat-value" id="ts-accuracy">—</span></div>
          </div>
        </div>
      </div>
    </div>

    <!-- Right: ADVISING -->
    <div class="col-12 col-lg-4 d-flex flex-column gap-3">
      <div class="card mc-panel tower-phase-card">
        <div class="card-header mc-panel-header tower-phase-advising">// ADVISING</div>
        <div class="card-body p-3 tower-scroll" id="tower-advisories">
          <div class="tower-empty">Waiting for Spark data&hellip;</div>
        </div>
      </div>
    </div>

  </div>
</div>

<script>
(function() {
  var ws = null;
  var badge = document.getElementById('tower-conn');

  function setConn(state) {
    badge.textContent = state.toUpperCase();
    badge.className = 'tower-conn-badge tower-conn-' + state;
  }

  function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }

  function renderEvents(events) {
    var el = document.getElementById('tower-events');
    if (!events || !events.length) { el.innerHTML = '<div class="tower-empty">No events captured yet.</div>'; return; }
    var html = '';
    for (var i = 0; i < events.length; i++) {
      var ev = events[i];
      var dots = ev.importance >= 0.8 ? '\u25cf\u25cf\u25cf' : ev.importance >= 0.5 ? '\u25cf\u25cf' : '\u25cf';
      html += '<div class="tower-event tower-etype-' + esc(ev.event_type) + '">'
        + '<div class="tower-ev-head">'
        + '<span class="tower-ev-badge">' + esc(ev.event_type.replace(/_/g, ' ').toUpperCase()) + '</span>'
        + '<span class="tower-ev-dots">' + dots + '</span>'
        + '</div>'
        + '<div class="tower-ev-desc">' + esc(ev.description) + '</div>'
        + '<div class="tower-ev-time">' + esc((ev.created_at || '').slice(0, 19)) + '</div>'
        + '</div>';
    }
    el.innerHTML = html;
  }

  function renderPredictions(preds) {
    var el = document.getElementById('tower-predictions');
    if (!preds || !preds.length) { el.innerHTML = '<div class="tower-empty">No predictions yet.</div>'; return; }
    var html = '';
    for (var i = 0; i < preds.length; i++) {
      var p = preds[i];
      var cls = p.evaluated ? 'tower-pred-done' : 'tower-pred-pending';
      var accTxt = p.accuracy != null ? Math.round(p.accuracy * 100) + '%' : 'PENDING';
      var accCls = p.accuracy != null ? (p.accuracy >= 0.7 ? 'text-success' : p.accuracy < 0.4 ? 'text-danger' : 'text-warning') : '';
      html += '<div class="tower-pred ' + cls + '">'
        + '<div class="tower-pred-head">'
        + '<span class="tower-pred-task">' + esc(p.task_id) + '</span>'
        + '<span class="tower-pred-acc ' + accCls + '">' + accTxt + '</span>'
        + '</div>';
      if (p.predicted) {
        var pr = p.predicted;
        html += '<div class="tower-pred-detail">';
        if (pr.likely_winner) html += '<span>Winner: ' + esc(pr.likely_winner.slice(0, 8)) + '</span> ';
        if (pr.success_probability != null) html += '<span>Success: ' + Math.round(pr.success_probability * 100) + '%</span> ';
        html += '</div>';
      }
      html += '<div class="tower-ev-time">' + esc((p.created_at || '').slice(0, 19)) + '</div>'
        + '</div>';
    }
    el.innerHTML = html;
  }

  function renderAdvisories(advs) {
    var el = document.getElementById('tower-advisories');
    if (!advs || !advs.length) { el.innerHTML = '<div class="tower-empty">No advisories yet.</div>'; return; }
    var html = '';
    for (var i = 0; i < advs.length; i++) {
      var a = advs[i];
      var prio = a.priority >= 0.7 ? 'high' : a.priority >= 0.4 ? 'medium' : 'low';
      html += '<div class="tower-advisory tower-adv-' + prio + '">'
        + '<div class="tower-adv-head">'
        + '<span class="tower-adv-cat">' + esc(a.category.replace(/_/g, ' ').toUpperCase()) + '</span>'
        + '<span class="tower-adv-prio">' + Math.round(a.priority * 100) + '%</span>'
        + '</div>'
        + '<div class="tower-adv-title">' + esc(a.title) + '</div>'
        + '<div class="tower-adv-detail">' + esc(a.detail) + '</div>'
        + '<div class="tower-adv-action">' + esc(a.suggested_action) + '</div>'
        + '</div>';
    }
    el.innerHTML = html;
  }

  function renderStats(status) {
    if (!status) return;
    document.getElementById('ts-events').textContent = status.events_captured || 0;
    document.getElementById('ts-memories').textContent = status.memories_stored || 0;
    var p = status.predictions || {};
    document.getElementById('ts-preds').textContent = p.total_predictions || 0;
    var acc = p.avg_accuracy;
    var accEl = document.getElementById('ts-accuracy');
    if (acc != null) {
      accEl.textContent = Math.round(acc * 100) + '%';
      accEl.className = 'tower-stat-value ' + (acc >= 0.7 ? 'text-success' : acc < 0.4 ? 'text-danger' : 'text-warning');
    } else {
      accEl.textContent = '\u2014';
    }
  }

  function handleMsg(data) {
    if (data.type !== 'spark_state') return;
    renderEvents(data.events);
    renderPredictions(data.predictions);
    renderAdvisories(data.advisories);
    renderStats(data.status);
  }

  function connect() {
    var proto = location.protocol === 'https:' ? 'wss:' : 'ws:';
    ws = new WebSocket(proto + '//' + location.host + '/tower/ws');
    ws.onopen = function() { setConn('live'); };
    ws.onclose = function() { setConn('offline'); setTimeout(connect, 3000); };
    ws.onerror = function() { setConn('offline'); };
    ws.onmessage = function(e) {
      try { handleMsg(JSON.parse(e.data)); } catch(err) { console.error('Tower WS parse error', err); }
    };
  }

  connect();
})();
</script>
{% endblock %}
