<!DOCTYPE html>
<html lang="en" data-bs-theme="dark">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover, interactive-widget=resizes-content" />
  <meta name="apple-mobile-web-app-capable" content="yes" />
  <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
  <meta name="theme-color" content="#080412" />
  <title>{% block title %}Timmy Time — Mission Control{% endblock %}</title>
  <link rel="preconnect" href="https://fonts.googleapis.com" />
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
  <link rel="preconnect" href="https://cdn.jsdelivr.net" crossorigin />
  <link href="https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet" />
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous" />
  <link rel="icon" href="/static/favicon.svg" type="image/svg+xml" />
  <link rel="stylesheet" href="/static/style.css?v=6" />
  <link rel="stylesheet" href="/static/css/mission-control.css?v=2" />
  {% block extra_styles %}{% endblock %}
  <script src="https://cdn.jsdelivr.net/npm/htmx.org@2.0.3/dist/htmx.min.js" crossorigin="anonymous"></script>
  <script>
    document.addEventListener('DOMContentLoaded', function() {
      var match = document.cookie.match(/csrf_token=([^;]+)/);
      if (match) {
        document.body.setAttribute('hx-headers', JSON.stringify({"X-CSRF-Token": match[1]}));
      }
    });
  </script>
  <script defer src="https://cdn.jsdelivr.net/npm/marked@15.0.7/marked.min.js"></script>
  <script defer src="https://cdn.jsdelivr.net/npm/dompurify@3.2.4/dist/purify.min.js"></script>
</head>
<body>
  <header class="mc-header">
    <div class="mc-header-left">
      <a href="/" class="mc-title">MISSION CONTROL</a>
      <span class="mc-subtitle">MISSION CONTROL</span>
      <span class="mc-conn-status" id="conn-status">
        <span class="mc-conn-dot amber" id="conn-dot"></span>
        <span id="conn-label">CONNECTING</span>
      </span>
    </div>

    <!-- Desktop nav — grouped dropdowns matching mobile sections -->
    <div class="mc-header-right mc-desktop-nav">
      <a href="/" class="mc-test-link">HOME</a>
      <div class="mc-nav-dropdown">
        <button class="mc-test-link mc-dropdown-toggle" aria-expanded="false">CORE &#x25BE;</button>
        <div class="mc-dropdown-menu">
          <a href="/calm" class="mc-test-link">CALM</a>
          <a href="/tasks" class="mc-test-link">TASKS</a>
          <a href="/briefing" class="mc-test-link">BRIEFING</a>
          <a href="/thinking" class="mc-test-link mc-link-thinking">THINKING</a>
          <a href="/swarm/mission-control" class="mc-test-link">MISSION CTRL</a>
          <a href="/swarm/live" class="mc-test-link">SWARM</a>
          <a href="/bugs" class="mc-test-link mc-link-bugs">BUGS</a>
        </div>
      </div>
      <div class="mc-nav-dropdown">
        <button class="mc-test-link mc-dropdown-toggle" aria-expanded="false">AGENTS &#x25BE;</button>
        <div class="mc-dropdown-menu">
          <a href="/hands" class="mc-test-link">HANDS</a>
          <a href="/work-orders/queue" class="mc-test-link">WORK ORDERS</a>
          <a href="/self-modify/queue" class="mc-test-link">UPGRADES</a>
          <a href="/self-coding" class="mc-test-link">SELF-CODING</a>
        </div>
      </div>
      <div class="mc-nav-dropdown">
        <button class="mc-test-link mc-dropdown-toggle" aria-expanded="false">INTEL &#x25BE;</button>
        <div class="mc-dropdown-menu">
          <a href="/spark/ui" class="mc-test-link">SPARK</a>
          <a href="/memory" class="mc-test-link">MEMORY</a>
          <a href="/marketplace/ui" class="mc-test-link">MARKET</a>
        </div>
      </div>
      <div class="mc-nav-dropdown">
        <button class="mc-test-link mc-dropdown-toggle" aria-expanded="false">SYSTEM &#x25BE;</button>
        <div class="mc-dropdown-menu">
          <a href="/tools" class="mc-test-link">TOOLS</a>
          <a href="/swarm/events" class="mc-test-link">EVENTS</a>
          <a href="/router/status" class="mc-test-link">ROUTER</a>
          <a href="/grok/status" class="mc-test-link mc-link-grok">GROK</a>
          <a href="/db-explorer" class="mc-test-link">DB EXPLORER</a>
        </div>
      </div>
      <div class="mc-nav-dropdown">
        <button class="mc-test-link mc-dropdown-toggle" aria-expanded="false">MORE &#x25BE;</button>
        <div class="mc-dropdown-menu">
          <a href="/lightning/ledger" class="mc-test-link">LEDGER</a>
          <a href="/creative/ui" class="mc-test-link">CREATIVE</a>
          <a href="/voice/button" class="mc-test-link">VOICE</a>
          <a href="/mobile" class="mc-test-link" title="Mobile-optimized view">MOBILE</a>
          <a href="/mobile/local" class="mc-test-link" title="Local AI on iPhone">LOCAL AI</a>
        </div>
      </div>
      <div class="mc-nav-dropdown" id="notif-dropdown">
        <button id="enable-notifications" class="mc-test-link mc-dropdown-toggle mc-notif-btn" title="Notifications" aria-expanded="false">&#x1F514;<span id="notif-badge" class="notif-badge"></span></button>
        <div class="mc-dropdown-menu mc-notif-menu">
          <div id="notif-list" class="mc-notif-list">
            <div class="mc-notif-empty">Loading...</div>
          </div>
        </div>
      </div>
      <span class="mc-time" id="clock"></span>
    </div>

    <!-- Mobile hamburger -->
    <button class="mc-hamburger" id="hamburger-btn" aria-label="Menu">
      <span></span><span></span><span></span>
    </button>
  </header>

  <!-- Mobile slide-out menu -->
  <div class="mc-mobile-overlay" id="mobile-overlay"></div>
  <nav class="mc-mobile-menu" id="mobile-menu">
    <div class="mc-mobile-menu-header">
      <span class="mc-mobile-menu-title">NAVIGATE</span>
      <span class="mc-time" id="clock-mobile"></span>
    </div>
    <a href="/" class="mc-mobile-link">HOME</a>
    <div class="mc-mobile-section-label">CORE</div>
    <a href="/calm" class="mc-mobile-link">CALM</a>
    <a href="/tasks" class="mc-mobile-link">TASKS</a>
    <a href="/briefing" class="mc-mobile-link">BRIEFING</a>
    <a href="/thinking" class="mc-mobile-link">THINKING</a>
    <a href="/swarm/mission-control" class="mc-mobile-link">MISSION CONTROL</a>
    <a href="/swarm/live" class="mc-mobile-link">SWARM</a>
    <a href="/bugs" class="mc-mobile-link">BUGS</a>
    <div class="mc-mobile-section-label">INTELLIGENCE</div>
    <a href="/spark/ui" class="mc-mobile-link">SPARK</a>
    <a href="/memory" class="mc-mobile-link">MEMORY</a>
    <a href="/marketplace/ui" class="mc-mobile-link">MARKET</a>
    <div class="mc-mobile-section-label">AGENTS</div>
    <a href="/hands" class="mc-mobile-link">HANDS</a>
    <a href="/work-orders/queue" class="mc-mobile-link">WORK ORDERS</a>
    <a href="/self-modify/queue" class="mc-mobile-link">UPGRADES</a>
    <a href="/self-coding" class="mc-mobile-link">SELF-CODING</a>
    <div class="mc-mobile-section-label">SYSTEM</div>
    <a href="/tools" class="mc-mobile-link">TOOLS</a>
    <a href="/swarm/events" class="mc-mobile-link">EVENTS</a>
    <a href="/router/status" class="mc-mobile-link">ROUTER</a>
    <a href="/grok/status" class="mc-mobile-link">GROK</a>
    <a href="/db-explorer" class="mc-mobile-link">DB EXPLORER</a>
    <div class="mc-mobile-section-label">COMMERCE</div>
    <a href="/lightning/ledger" class="mc-mobile-link">LEDGER</a>
    <a href="/creative/ui" class="mc-mobile-link">CREATIVE</a>
    <a href="/voice/button" class="mc-mobile-link">VOICE</a>
    <a href="/mobile" class="mc-mobile-link">MOBILE</a>
    <a href="/mobile/local" class="mc-mobile-link">LOCAL AI</a>
    <div class="mc-mobile-menu-footer">
      <button id="enable-notifications-mobile" class="mc-mobile-link mc-mobile-notif-btn">&#x1F514; NOTIFICATIONS</button>
    </div>
  </nav>

  <!-- Toast container -->
  <div class="mc-toast-container" id="toast-container"></div>

  <!-- Magical floating particles canvas -->
  <canvas id="magic-particles" aria-hidden="true"></canvas>

  <main class="mc-main">
    {% block content %}{% endblock %}
  </main>

  <script>
    // ── Magical floating particles ──
    (function() {
      var canvas = document.getElementById('magic-particles');
      if (!canvas) return;
      var ctx = canvas.getContext('2d');
      var particles = [];
      var PARTICLE_COUNT = 40;
      var raf;

      function resize() {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
      }
      resize();
      window.addEventListener('resize', resize);

      var colors = [
        { r: 168, g: 85, b: 247 },  // purple
        { r: 124, g: 58, b: 237 },  // violet
        { r: 192, g: 132, b: 252 }, // light purple
        { r: 249, g: 115, b: 22 },  // orange
        { r: 237, g: 224, b: 255 }, // white-purple
      ];

      function createParticle() {
        var c = colors[Math.floor(Math.random() * colors.length)];
        return {
          x: Math.random() * canvas.width,
          y: Math.random() * canvas.height,
          vx: (Math.random() - 0.5) * 0.3,
          vy: (Math.random() - 0.5) * 0.3,
          r: Math.random() * 2.2 + 0.5,
          alpha: Math.random() * 0.4 + 0.05,
          alphaDir: (Math.random() - 0.5) * 0.008,
          color: c,
          phase: Math.random() * Math.PI * 2,
          drift: Math.random() * 0.2 + 0.05
        };
      }

      for (var i = 0; i < PARTICLE_COUNT; i++) {
        particles.push(createParticle());
      }

      var time = 0;
      function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        time += 0.003;

        for (var i = 0; i < particles.length; i++) {
          var p = particles[i];
          p.x += p.vx + Math.sin(time + p.phase) * p.drift;
          p.y += p.vy + Math.cos(time + p.phase) * p.drift;
          p.alpha += p.alphaDir;

          if (p.alpha <= 0.02 || p.alpha >= 0.45) p.alphaDir *= -1;
          p.alpha = Math.max(0.02, Math.min(0.45, p.alpha));

          if (p.x < -20) p.x = canvas.width + 20;
          if (p.x > canvas.width + 20) p.x = -20;
          if (p.y < -20) p.y = canvas.height + 20;
          if (p.y > canvas.height + 20) p.y = -20;

          // Glow
          var grad = ctx.createRadialGradient(p.x, p.y, 0, p.x, p.y, p.r * 6);
          grad.addColorStop(0, 'rgba(' + p.color.r + ',' + p.color.g + ',' + p.color.b + ',' + (p.alpha * 0.6) + ')');
          grad.addColorStop(1, 'rgba(' + p.color.r + ',' + p.color.g + ',' + p.color.b + ',0)');
          ctx.fillStyle = grad;
          ctx.beginPath();
          ctx.arc(p.x, p.y, p.r * 6, 0, Math.PI * 2);
          ctx.fill();

          // Core
          ctx.fillStyle = 'rgba(' + p.color.r + ',' + p.color.g + ',' + p.color.b + ',' + p.alpha + ')';
          ctx.beginPath();
          ctx.arc(p.x, p.y, p.r, 0, Math.PI * 2);
          ctx.fill();
        }
        raf = requestAnimationFrame(draw);
      }

      // Only run when tab is visible
      function onVis() {
        if (document.hidden) {
          cancelAnimationFrame(raf);
        } else {
          draw();
        }
      }
      document.addEventListener('visibilitychange', onVis);
      draw();

      // Respect reduced motion preference
      if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
        cancelAnimationFrame(raf);
        canvas.style.display = 'none';
      }
    })();
  </script>
  <script>
    // Clock
    function updateClock() {
      const t = new Date().toLocaleTimeString('en-US', { hour12: false });
      const el = document.getElementById('clock');
      const el2 = document.getElementById('clock-mobile');
      if (el) el.textContent = t;
      if (el2) el2.textContent = t;
    }
    setInterval(updateClock, 1000);
    updateClock();

    // Mobile menu
    const hamburger = document.getElementById('hamburger-btn');
    const overlay = document.getElementById('mobile-overlay');
    const menu = document.getElementById('mobile-menu');
    function toggleMenu() {
      const open = menu.classList.toggle('open');
      overlay.classList.toggle('open', open);
      hamburger.classList.toggle('open', open);
      document.body.style.overflow = open ? 'hidden' : '';
    }
    hamburger.addEventListener('click', toggleMenu);
    overlay.addEventListener('click', toggleMenu);

    // Highlight current page in mobile menu and desktop dropdowns
    var currentPath = window.location.pathname;
    document.querySelectorAll('.mc-mobile-link, .mc-dropdown-menu .mc-test-link').forEach(function(a) {
      if (a.getAttribute('href') === currentPath) {
        a.classList.add('active');
      }
    });

    // Desktop dropdown toggles (More menu + Notification bell)
    document.querySelectorAll('.mc-dropdown-toggle').forEach(function(toggle) {
      toggle.addEventListener('click', function(e) {
        e.stopPropagation();
        var dd = this.closest('.mc-nav-dropdown');
        // Close other dropdowns first
        document.querySelectorAll('.mc-nav-dropdown.open').forEach(function(other) {
          if (other !== dd) {
            other.classList.remove('open');
            var btn = other.querySelector('.mc-dropdown-toggle');
            if (btn) btn.setAttribute('aria-expanded', 'false');
          }
        });
        var isOpen = dd.classList.toggle('open');
        this.setAttribute('aria-expanded', isOpen);
        // Load notifications when opening the bell
        if (isOpen && dd.id === 'notif-dropdown') { loadNotifications(); }
      });
    });
    document.addEventListener('click', function() {
      document.querySelectorAll('.mc-nav-dropdown.open').forEach(function(dd) {
        dd.classList.remove('open');
        var btn = dd.querySelector('.mc-dropdown-toggle');
        if (btn) btn.setAttribute('aria-expanded', 'false');
      });
    });

    // Notification loader
    function loadNotifications() {
      fetch('/api/notifications')
        .then(function(r) { return r.json(); })
        .then(function(data) {
          var list = document.getElementById('notif-list');
          if (!data.length) {
            list.innerHTML = '';
            var emptyDiv = document.createElement('div');
            emptyDiv.className = 'mc-notif-empty';
            emptyDiv.textContent = 'No recent notifications';
            list.appendChild(emptyDiv);
            return;
          }
          list.innerHTML = '';
          data.forEach(function(n) {
            var item = document.createElement('div');
            item.className = 'mc-notif-item';
            var title = document.createElement('div');
            title.className = 'mc-notif-title';
            title.textContent = n.title || n.event_type || 'Event';
            var ts = document.createElement('div');
            ts.className = 'mc-notif-ts';
            ts.textContent = n.timestamp || '';
            item.appendChild(title);
            item.appendChild(ts);
            list.appendChild(item);
          });
          var badge = document.getElementById('notif-badge');
          if (badge) { badge.classList.add('hidden'); }
        })
        .catch(function() {});
    }
  </script>
  <!-- Toast + connection status system -->
  <script>
    // ── Toast notifications ──
    window.McToast = {
      show: function(message, level) {
        level = level || 'info';
        var container = document.getElementById('toast-container');
        if (!container) return;
        var toast = document.createElement('div');
        toast.className = 'mc-toast ' + level;
        toast.textContent = message;
        container.appendChild(toast);
        requestAnimationFrame(function() {
          toast.classList.add('show');
        });
        setTimeout(function() {
          toast.classList.remove('show');
          setTimeout(function() { toast.remove(); }, 300);
        }, 4000);
      }
    };

    // ── Global connection status ──
    (function() {
      var dot = document.getElementById('conn-dot');
      var label = document.getElementById('conn-label');
      var wsConnected = false;
      var ollamaOk = null;   // null = unknown, true/false

      function updateIndicator() {
        if (!dot || !label) return;
        if (!wsConnected) {
          dot.className = 'mc-conn-dot red';
          label.textContent = 'OFFLINE';
        } else if (ollamaOk === false) {
          dot.className = 'mc-conn-dot amber';
          label.textContent = 'NO LLM';
        } else {
          dot.className = 'mc-conn-dot green';
          label.textContent = 'LIVE';
        }
      }

      function checkOllama() {
        fetch('/health')
          .then(function(r) { return r.json(); })
          .then(function(data) {
            var prev = ollamaOk;
            ollamaOk = data.services && data.services.ollama === 'up';
            updateIndicator();
            if (prev === false && ollamaOk) {
              McToast.show('Ollama reconnected', 'info');
            } else if (prev === true && !ollamaOk) {
              McToast.show('Ollama unreachable', 'warn');
            }
          })
          .catch(function() {
            ollamaOk = false;
            updateIndicator();
          });
      }

      var protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
      var reconnectDelay = 1000;

      function connectStatusWs() {
        var ws;
        try {
          ws = new WebSocket(protocol + '//' + window.location.host + '/swarm/live');
        } catch(e) { return; }

        ws.onopen = function() {
          wsConnected = true;
          reconnectDelay = 1000;
          updateIndicator();
          checkOllama();
        };
        ws.onclose = function() {
          if (wsConnected) {
            McToast.show('WebSocket disconnected', 'error');
          }
          wsConnected = false;
          updateIndicator();
          setTimeout(connectStatusWs, reconnectDelay);
          reconnectDelay = Math.min(reconnectDelay * 2, 30000);
        };
        ws.onerror = function() {};
      }

      connectStatusWs();
      // Poll Ollama health every 30s
      setInterval(checkOllama, 30000);
    })();
  </script>
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
  <script src="/static/notifications.js"></script>
</body>
</html>
