← back to Designer Wallcoverings

DW-Agents/dw-agents/agent-monitor-dashboard/public/index.html

1331 lines

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>DW-Agents Crisis Monitor | Real-time Emergency Detection</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
      background: #0a0e27;
      color: #e4e4e7;
      line-height: 1.6;
      overflow-x: hidden;
    }

    /* CRISIS ALERT SYSTEM */
    .crisis-banner {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      background: linear-gradient(135deg, #ff0000 0%, #ff00ff 50%, #ff0000 100%);
      color: white;
      padding: 15px;
      text-align: center;
      font-size: 18px;
      font-weight: bold;
      z-index: 10000;
      display: none;
      animation: criticalFlash 1s infinite;
      box-shadow: 0 4px 20px rgba(255, 0, 0, 0.5);
    }

    @keyframes criticalFlash {
      0%, 100% { background: linear-gradient(135deg, #ff0000 0%, #ff00ff 50%, #ff0000 100%); }
      50% { background: linear-gradient(135deg, #ff00ff 0%, #ff0000 50%, #ff00ff 100%); }
    }

    .crisis-banner.active {
      display: block;
    }

    .crisis-banner button {
      background: rgba(0, 0, 0, 0.3);
      border: 2px solid white;
      color: white;
      padding: 8px 16px;
      margin: 0 8px;
      border-radius: 6px;
      font-weight: bold;
      cursor: pointer;
      transition: all 0.2s;
    }

    .crisis-banner button:hover {
      background: rgba(255, 255, 255, 0.2);
    }

    /* HEARTBEAT INDICATORS */
    .heartbeat {
      width: 12px;
      height: 12px;
      background: #00ff00;
      border-radius: 50%;
      display: inline-block;
      animation: heartbeat 1.5s infinite;
      margin-right: 8px;
    }

    .heartbeat.critical {
      background: #ff0000;
      animation: criticalPulse 0.5s infinite;
    }

    .heartbeat.warning {
      background: #ffaa00;
      animation: warningPulse 1s infinite;
    }

    @keyframes heartbeat {
      0%, 100% { transform: scale(1); opacity: 1; }
      50% { transform: scale(1.3); opacity: 0.7; }
    }

    @keyframes criticalPulse {
      0%, 100% { transform: scale(1); background: #ff0000; }
      50% { transform: scale(1.5); background: #ff4444; }
    }

    @keyframes warningPulse {
      0%, 100% { transform: scale(1); opacity: 1; }
      50% { transform: scale(1.2); opacity: 0.6; }
    }

    /* RESTART FREQUENCY GRAPH */
    .restart-graph {
      height: 30px;
      background: #1a1f3a;
      border-radius: 4px;
      margin: 8px 0;
      position: relative;
      overflow: hidden;
    }

    .restart-bar {
      height: 100%;
      background: linear-gradient(90deg, #00ff00 0%, #ffaa00 30%, #ff0000 60%, #ff00ff 100%);
      border-radius: 4px;
      transition: width 0.5s;
      position: relative;
    }

    .restart-label {
      position: absolute;
      right: 8px;
      top: 50%;
      transform: translateY(-50%);
      font-size: 11px;
      font-weight: bold;
      color: white;
      text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.8);
    }

    /* Header */
    .header {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      padding: 20px 30px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
      position: sticky;
      top: 0;
      z-index: 1000;
      transition: all 0.3s;
    }

    .header.crisis-mode {
      background: linear-gradient(135deg, #ff0000 0%, #ff00ff 100%);
      animation: headerFlash 2s infinite;
    }

    @keyframes headerFlash {
      0%, 100% { background: linear-gradient(135deg, #ff0000 0%, #ff00ff 100%); }
      50% { background: linear-gradient(135deg, #ff4444 0%, #ff44ff 100%); }
    }

    .header-content {
      max-width: 1400px;
      margin: 0 auto;
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
      gap: 20px;
    }

    .title {
      font-size: 28px;
      font-weight: bold;
      display: flex;
      align-items: center;
      gap: 15px;
    }

    .health-score {
      display: flex;
      align-items: center;
      gap: 20px;
      background: rgba(0, 0, 0, 0.2);
      padding: 10px 20px;
      border-radius: 30px;
    }

    .score-circle {
      width: 80px;
      height: 80px;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 24px;
      font-weight: bold;
      position: relative;
      background: conic-gradient(
        from 0deg,
        #10b981 0deg,
        #10b981 var(--score-deg),
        rgba(255, 255, 255, 0.1) var(--score-deg)
      );
    }

    .score-inner {
      width: 60px;
      height: 60px;
      background: #0a0e27;
      border-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    /* Controls */
    .controls {
      background: #1a1f3a;
      padding: 20px 30px;
      border-bottom: 1px solid #2a2f4a;
    }

    .controls-content {
      max-width: 1400px;
      margin: 0 auto;
      display: flex;
      justify-content: space-between;
      align-items: center;
      flex-wrap: wrap;
      gap: 15px;
    }

    .btn {
      padding: 10px 20px;
      border: none;
      border-radius: 8px;
      cursor: pointer;
      font-size: 14px;
      font-weight: 500;
      transition: all 0.3s;
      display: inline-flex;
      align-items: center;
      gap: 8px;
    }

    .btn-primary {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
      color: white;
    }

    .btn-danger {
      background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
      color: white;
    }

    .btn-success {
      background: linear-gradient(135deg, #10b981 0%, #059669 100%);
      color: white;
    }

    .btn-emergency {
      background: linear-gradient(135deg, #ff0000 0%, #ff00ff 100%);
      color: white;
      font-weight: bold;
      animation: emergencyPulse 1.5s infinite;
      border: 2px solid #fff;
    }

    .btn-warning {
      background: linear-gradient(135deg, #ffaa00 0%, #ff8800 100%);
      color: white;
    }

    @keyframes emergencyPulse {
      0%, 100% { transform: scale(1); }
      50% { transform: scale(1.05); box-shadow: 0 0 20px rgba(255, 0, 255, 0.7); }
    }

    .btn:hover {
      transform: translateY(-2px);
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
    }

    .btn-emergency:hover {
      animation: none;
      transform: translateY(-2px) scale(1.02);
      box-shadow: 0 8px 25px rgba(255, 0, 255, 0.5);
    }

    /* Stats Summary */
    .stats-summary {
      padding: 30px;
      background: #1a1f3a;
      margin: 20px 30px;
      border-radius: 12px;
      max-width: 1400px;
      margin-left: auto;
      margin-right: auto;
    }

    .stats-grid {
      display: grid;
      grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
      gap: 20px;
    }

    .stat-card {
      background: #0a0e27;
      padding: 15px;
      border-radius: 8px;
      text-align: center;
      border: 1px solid #2a2f4a;
    }

    .stat-value {
      font-size: 32px;
      font-weight: bold;
      margin-bottom: 5px;
    }

    .stat-label {
      font-size: 12px;
      color: #9ca3af;
      text-transform: uppercase;
    }

    /* Main Content */
    .main-content {
      max-width: 1400px;
      margin: 0 auto;
      padding: 20px 30px;
    }

    /* Agent Categories */
    .category {
      margin-bottom: 30px;
      background: #1a1f3a;
      border-radius: 12px;
      overflow: hidden;
    }

    .category-header {
      background: linear-gradient(135deg, #2a2f4a 0%, #1a1f3a 100%);
      padding: 15px 20px;
      font-size: 18px;
      font-weight: 600;
      border-bottom: 1px solid #2a2f4a;
      display: flex;
      align-items: center;
      gap: 10px;
    }

    .agents-grid {
      display: grid;
      grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
      gap: 20px;
      padding: 20px;
    }

    /* Agent Card */
    .agent-card {
      background: #0a0e27;
      border: 1px solid #2a2f4a;
      border-radius: 8px;
      padding: 15px;
      transition: all 0.3s;
      position: relative;
    }

    .agent-card.critical {
      border: 2px solid #ff0000;
      background: linear-gradient(135deg, #0a0e27 0%, #1a0505 100%);
      box-shadow: 0 0 15px rgba(255, 0, 0, 0.3);
      animation: criticalGlow 2s infinite;
    }

    .agent-card.warning {
      border: 2px solid #ffaa00;
      background: linear-gradient(135deg, #0a0e27 0%, #1a1505 100%);
      box-shadow: 0 0 10px rgba(255, 170, 0, 0.2);
    }

    .agent-card.healthy {
      border: 1px solid #00ff00;
      background: linear-gradient(135deg, #0a0e27 0%, #051a05 100%);
    }

    @keyframes criticalGlow {
      0%, 100% { box-shadow: 0 0 15px rgba(255, 0, 0, 0.3); }
      50% { box-shadow: 0 0 25px rgba(255, 0, 0, 0.6); }
    }

    .agent-card:hover {
      transform: translateY(-2px);
    }

    .agent-card.critical:hover {
      box-shadow: 0 4px 30px rgba(255, 0, 0, 0.5);
    }

    /* Memory Leak Indicator */
    .memory-leak-indicator {
      position: absolute;
      top: 10px;
      right: 10px;
      background: #ff00ff;
      color: white;
      padding: 4px 8px;
      border-radius: 12px;
      font-size: 10px;
      font-weight: bold;
      animation: memoryLeakPulse 1s infinite;
    }

    @keyframes memoryLeakPulse {
      0%, 100% { opacity: 1; transform: scale(1); }
      50% { opacity: 0.7; transform: scale(1.1); }
    }

    .agent-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 15px;
    }

    .agent-name {
      font-weight: 600;
      font-size: 16px;
    }

    .agent-status {
      padding: 4px 12px;
      border-radius: 20px;
      font-size: 12px;
      font-weight: 500;
    }

    .status-online {
      background: #10b981;
      color: white;
    }

    .status-stopped {
      background: #6b7280;
      color: white;
    }

    .status-errored {
      background: #ef4444;
      color: white;
      animation: pulse 2s infinite;
    }

    .status-launching {
      background: #f59e0b;
      color: white;
      animation: pulse 1s infinite;
    }

    @keyframes pulse {
      0%, 100% { opacity: 1; }
      50% { opacity: 0.6; }
    }

    /* Metrics */
    .agent-metrics {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 10px;
      margin-bottom: 15px;
    }

    .metric {
      display: flex;
      align-items: center;
      gap: 8px;
      font-size: 14px;
    }

    .metric-icon {
      width: 20px;
      height: 20px;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .metric-value {
      font-weight: 500;
    }

    .metric-warning {
      color: #f59e0b;
    }

    .metric-critical {
      color: #ef4444;
    }

    .metric-severe {
      color: #dc2626;
      font-weight: bold;
    }

    /* Progress Bars */
    .progress-bar {
      height: 4px;
      background: #2a2f4a;
      border-radius: 2px;
      overflow: hidden;
      margin-top: 5px;
    }

    .progress-fill {
      height: 100%;
      transition: width 0.3s;
    }

    .progress-cpu {
      background: linear-gradient(90deg, #10b981 0%, #f59e0b 50%, #ef4444 100%);
    }

    .progress-memory {
      background: linear-gradient(90deg, #3b82f6 0%, #8b5cf6 50%, #ef4444 100%);
    }

    /* Actions */
    .agent-actions {
      display: flex;
      gap: 8px;
      justify-content: flex-end;
      padding-top: 10px;
      border-top: 1px solid #2a2f4a;
    }

    .action-btn {
      padding: 6px 12px;
      border: none;
      border-radius: 6px;
      cursor: pointer;
      font-size: 12px;
      transition: all 0.2s;
      background: #2a2f4a;
      color: #e4e4e7;
    }

    .action-btn:hover {
      background: #3a3f5a;
    }

    /* Error Logs */
    .error-logs {
      margin-top: 10px;
      padding: 10px;
      background: rgba(239, 68, 68, 0.1);
      border: 1px solid rgba(239, 68, 68, 0.3);
      border-radius: 6px;
      font-size: 12px;
      font-family: monospace;
      max-height: 100px;
      overflow-y: auto;
    }

    /* Auto-refresh indicator */
    .refresh-indicator {
      display: inline-flex;
      align-items: center;
      gap: 8px;
      padding: 8px 16px;
      background: rgba(0, 0, 0, 0.2);
      border-radius: 20px;
      font-size: 14px;
    }

    .refresh-countdown {
      font-weight: bold;
      color: #10b981;
    }

    /* Loading overlay */
    .loading-overlay {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background: rgba(10, 14, 39, 0.9);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 9999;
      opacity: 0;
      pointer-events: none;
      transition: opacity 0.3s;
    }

    .loading-overlay.active {
      opacity: 1;
      pointer-events: all;
    }

    .loader {
      width: 50px;
      height: 50px;
      border: 4px solid #2a2f4a;
      border-top-color: #667eea;
      border-radius: 50%;
      animation: spin 1s linear infinite;
    }

    @keyframes spin {
      to { transform: rotate(360deg); }
    }

    /* Alerts */
    .alert {
      position: fixed;
      top: 100px;
      right: 30px;
      padding: 15px 20px;
      border-radius: 8px;
      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);
      display: none;
      animation: slideIn 0.3s;
      z-index: 2000;
    }

    @keyframes slideIn {
      from {
        transform: translateX(100%);
        opacity: 0;
      }
      to {
        transform: translateX(0);
        opacity: 1;
      }
    }

    .alert-success {
      background: #10b981;
      color: white;
    }

    .alert-error {
      background: #ef4444;
      color: white;
    }

    .alert-warning {
      background: #f59e0b;
      color: white;
    }
  </style>
</head>
<body>
  <!-- Loading Overlay -->
  <div class="loading-overlay" id="loadingOverlay">
    <div class="loader"></div>
  </div>

  <!-- Crisis Banner -->
  <div class="crisis-banner" id="crisisBanner">
    <span id="crisisMessage">🚨 SYSTEM CRISIS: Multiple agents failing! 🚨</span>
    <button onclick="emergencyStopAll()">EMERGENCY STOP ALL</button>
    <button onclick="autoFixCrisis()">AUTO-FIX CRISIS</button>
    <button onclick="dismissCrisis()">DISMISS</button>
  </div>

  <!-- Alert -->
  <div class="alert" id="alert"></div>

  <!-- Header -->
  <div class="header">
    <div class="header-content">
      <div class="title">
        <span>🎯</span>
        <span>DW-Agents Monitor Dashboard</span>
      </div>
      
      <div class="health-score">
        <div>
          <div style="font-size: 12px; color: rgba(255, 255, 255, 0.8);">System Health</div>
          <div style="font-size: 14px;">Overall Score</div>
        </div>
        <div class="score-circle" id="healthScore" style="--score-deg: 0deg">
          <div class="score-inner">
            <span id="scoreValue">0</span>
          </div>
        </div>
      </div>

      <div class="refresh-indicator">
        <span>🔄 Auto-refresh in</span>
        <span class="refresh-countdown" id="refreshCountdown">10</span>
        <span>seconds</span>
      </div>
    </div>
  </div>

  <!-- Controls -->
  <div class="controls">
    <div class="controls-content">
      <div>
        <button class="btn btn-primary" onclick="refreshData()">
          <span>🔄</span> Refresh Now
        </button>
        <button class="btn btn-emergency" onclick="emergencyStopAll()">
          <span>🛑</span> EMERGENCY STOP ALL
        </button>
        <button class="btn btn-warning" onclick="autoFixCommonIssues()">
          <span>🔧</span> Auto-Fix Issues
        </button>
        <button class="btn btn-danger" onclick="restartProblematic()">
          <span>⚠️</span> Restart Problematic
        </button>
        <button class="btn btn-success" onclick="exportReport()">
          <span>📊</span> Export Report
        </button>
      </div>
      <div style="display: flex; align-items: center; gap: 20px;">
        <div>
          <span style="font-size: 14px; color: #9ca3af;">System Status: </span>
          <span id="systemStatus" style="font-size: 14px; font-weight: bold;">MONITORING</span>
        </div>
        <div>
          <span style="font-size: 14px; color: #9ca3af;">Last update: </span>
          <span id="lastUpdate" style="font-size: 14px;">Never</span>
        </div>
        <div>
          <button class="btn btn-primary" onclick="toggleAudioAlerts()" id="audioToggle">
            <span>🔊</span> Audio: ON
          </button>
        </div>
      </div>
    </div>
  </div>

  <!-- Stats Summary -->
  <div class="stats-summary">
    <div class="stats-grid" id="statsGrid">
      <!-- Stats will be populated here -->
    </div>
  </div>

  <!-- Main Content -->
  <div class="main-content" id="mainContent">
    <!-- Agent categories will be populated here -->
  </div>

  <script>
    let refreshInterval = 10; // seconds
    let countdown = refreshInterval;
    let autoRefreshTimer;
    let countdownTimer;
    let audioEnabled = true;
    let crisisMode = false;
    let alertSound = null;

    // Initialize
    document.addEventListener('DOMContentLoaded', () => {
      // Initialize audio alert
      initializeAudioAlert();
      refreshData();
      startAutoRefresh();
    });

    // Initialize audio alert system
    function initializeAudioAlert() {
      // Create audio context for crisis alerts
      try {
        alertSound = new Audio('data:audio/wav;base64,UklGRnoGAABXQVZFZm10IBAAAAABAAEAQB8AAEAfAAABAAgAZGF0YQoGAACBhYqFbF1fdJivrJBhNjVgodDbq2EcBj+a2/LDciUFLIHO8tiJNwgZaLvt559NEAxQp+PwtmMcBjiR1/LMeSwFJHfH8N2QQAoUXrTp66hVFApGn+DyvmwhCjqL1O7AfCsDJHbJ9N+UQwkSXLLp6qdVFgpGnuDzv2whCzuL1O/AfCsDJHbJ9N+UQgkSXLLq66hWEwlFnePzv2whCzqL1O7AfSsDJHfJ9d+UQQoUXrPp66hWEwlEn+DyvmwhCjqL1O7AfCsDJHfH8N2QQAoUXrTp66hVFApGnuDyvmwcBjiQ1/LNeSsFJIHO8tiINwgZaLvt559NEwxVqOPwtmMcBjiR1/LNeSsFJHfH8N2QQAoUXrTp66hVFApGnuDyvmwcBjiQ1/LNeSsFJIHO8tiINwgZaLvt559NEwxVqOPwtmMcBjiR1/LNeSsFJHfH8N2QQAoUXrTp66hVFApGnuDyvmwcBjiQ1/LNeSsFJIHO8tiINwgZaLvt559NEwxVqOPwtmMcBjiR1/LNeSsFJHfH8N2QQAoUXrTp66hVFApGnuDyvmwcBjiQ1/LNeSsFJIHO8tiINwgZaLvt55');
      } catch (e) {
        console.warn('Audio alerts not supported in this browser');
        audioEnabled = false;
      }
    }

    // Start auto-refresh
    function startAutoRefresh() {
      countdownTimer = setInterval(() => {
        countdown--;
        document.getElementById('refreshCountdown').textContent = countdown;
        if (countdown <= 0) {
          countdown = refreshInterval;
          refreshData();
        }
      }, 1000);
    }

    // Refresh data
    async function refreshData() {
      showLoading(true);
      try {
        const response = await fetch('/api/stats');
        const result = await response.json();
        
        if (result.success) {
          updateDashboard(result.data);
          showAlert('Dashboard updated', 'success');
        } else {
          showAlert('Failed to fetch data', 'error');
        }
      } catch (error) {
        showAlert('Error: ' + error.message, 'error');
      } finally {
        showLoading(false);
        document.getElementById('lastUpdate').textContent = new Date().toLocaleTimeString();
      }
    }

    // Update dashboard
    function updateDashboard(data) {
      // Check for crisis conditions FIRST
      checkCrisisConditions(data);

      // Update health score
      const score = data.healthScore;
      const scoreDeg = (score / 100) * 360;
      const scoreElement = document.getElementById('healthScore');
      scoreElement.style.setProperty('--score-deg', scoreDeg + 'deg');
      document.getElementById('scoreValue').textContent = score;

      // Update system status
      updateSystemStatus(data);

      // Update stats summary
      updateStatsSummary(data.summary);

      // Update agent categories
      updateAgentCategories(data.categorized);
    }

    // Crisis detection system
    function checkCrisisConditions(data) {
      const criticalAgents = [];
      
      // Check all agents for crisis conditions
      Object.values(data.categorized).forEach(category => {
        category.forEach(agent => {
          if (agent.restarts > 50 || 
              (agent.restarts > 20 && agent.status === 'errored') ||
              agent.memory > 800 ||
              agent.cpu > 95) {
            criticalAgents.push(agent);
          }
        });
      });

      const wasInCrisis = crisisMode;
      crisisMode = criticalAgents.length > 2; // Crisis if 3+ agents critical

      if (crisisMode && !wasInCrisis) {
        // Entering crisis mode
        activateCrisisMode(criticalAgents);
      } else if (!crisisMode && wasInCrisis) {
        // Exiting crisis mode
        deactivateCrisisMode();
      }

      // Update crisis banner content if still in crisis
      if (crisisMode) {
        updateCrisisBanner(criticalAgents);
      }
    }

    // Activate crisis mode
    function activateCrisisMode(criticalAgents) {
      console.log('🚨 CRISIS MODE ACTIVATED', criticalAgents);
      
      // Show crisis banner
      const crisisBanner = document.getElementById('crisisBanner');
      crisisBanner.classList.add('active');
      
      // Change header to crisis mode
      const header = document.querySelector('.header');
      header.classList.add('crisis-mode');
      
      // Update system status
      document.getElementById('systemStatus').textContent = '🚨 CRISIS';
      document.getElementById('systemStatus').style.color = '#ff0000';
      
      // Play audio alert
      if (audioEnabled && alertSound) {
        try {
          alertSound.play();
        } catch (e) {
          console.warn('Could not play audio alert');
        }
      }
      
      // Update page title
      document.title = '🚨 CRISIS: DW-Agents Emergency';
    }

    // Deactivate crisis mode
    function deactivateCrisisMode() {
      console.log('✅ Crisis resolved');
      
      // Hide crisis banner
      const crisisBanner = document.getElementById('crisisBanner');
      crisisBanner.classList.remove('active');
      
      // Remove crisis header mode
      const header = document.querySelector('.header');
      header.classList.remove('crisis-mode');
      
      // Reset system status
      document.getElementById('systemStatus').textContent = 'MONITORING';
      document.getElementById('systemStatus').style.color = '#00ff00';
      
      // Reset page title
      document.title = 'DW-Agents Crisis Monitor | Real-time Emergency Detection';
    }

    // Update crisis banner
    function updateCrisisBanner(criticalAgents) {
      const message = `🚨 CRISIS: ${criticalAgents.length} agents failing! ` +
                     `Worst: ${criticalAgents[0].name} (${criticalAgents[0].restarts} restarts)`;
      document.getElementById('crisisMessage').textContent = message;
    }

    // Update system status
    function updateSystemStatus(data) {
      if (crisisMode) return; // Don't override crisis status
      
      const statusElement = document.getElementById('systemStatus');
      const totalAgents = data.summary.total;
      const onlineAgents = data.summary.online;
      const erroredAgents = data.summary.errored;
      
      if (erroredAgents > totalAgents * 0.3) {
        statusElement.textContent = '⚠️ DEGRADED';
        statusElement.style.color = '#ffaa00';
      } else if (erroredAgents > 0) {
        statusElement.textContent = '⚠️ WARNING';
        statusElement.style.color = '#ffaa00';
      } else {
        statusElement.textContent = '✅ HEALTHY';
        statusElement.style.color = '#00ff00';
      }
    }

    // Update stats summary
    function updateStatsSummary(summary) {
      const statsGrid = document.getElementById('statsGrid');
      statsGrid.innerHTML = `
        <div class="stat-card">
          <div class="stat-value" style="color: #10b981">${summary.online}</div>
          <div class="stat-label">Online</div>
        </div>
        <div class="stat-card">
          <div class="stat-value" style="color: #ef4444">${summary.errored}</div>
          <div class="stat-label">Errored</div>
        </div>
        <div class="stat-card">
          <div class="stat-value" style="color: #6b7280">${summary.stopped}</div>
          <div class="stat-label">Stopped</div>
        </div>
        <div class="stat-card">
          <div class="stat-value" style="color: #f59e0b">${summary.launching}</div>
          <div class="stat-label">Launching</div>
        </div>
        <div class="stat-card">
          <div class="stat-value" style="color: #dc2626">${summary.criticalRestarts}</div>
          <div class="stat-label">Critical Restarts</div>
        </div>
        <div class="stat-card">
          <div class="stat-value" style="color: #8b5cf6">${summary.highMemory}</div>
          <div class="stat-label">High Memory</div>
        </div>
        <div class="stat-card">
          <div class="stat-value" style="color: #f59e0b">${summary.highCpu}</div>
          <div class="stat-label">High CPU</div>
        </div>
        <div class="stat-card">
          <div class="stat-value">${summary.total}</div>
          <div class="stat-label">Total Agents</div>
        </div>
      `;
    }

    // Update agent categories
    function updateAgentCategories(categorized) {
      const mainContent = document.getElementById('mainContent');
      mainContent.innerHTML = '';

      for (const [category, agents] of Object.entries(categorized)) {
        if (agents.length === 0) continue;

        const categoryDiv = document.createElement('div');
        categoryDiv.className = 'category';
        
        const categoryIcon = getCategoryIcon(category);
        
        categoryDiv.innerHTML = `
          <div class="category-header">
            <span>${categoryIcon}</span>
            <span>${category} (${agents.length})</span>
          </div>
          <div class="agents-grid">
            ${agents.map(agent => createAgentCard(agent)).join('')}
          </div>
        `;
        
        mainContent.appendChild(categoryDiv);
      }
    }

    // Get category icon
    function getCategoryIcon(category) {
      const icons = {
        'Executive': '👔',
        'Operations': '⚙️',
        'Customer Service': '🤝',
        'Business Intelligence': '📊',
        'Infrastructure': '🏗️',
        'Support': '💼',
        'Other': '📦'
      };
      return icons[category] || '📦';
    }

    // Create agent card
    function createAgentCard(agent) {
      const statusClass = `status-${agent.status}`;
      const restartClass = agent.restarts > 50 ? 'metric-severe' : 
                           agent.restarts > 20 ? 'metric-critical' : 
                           agent.restarts > 10 ? 'metric-warning' : '';
      
      const memoryClass = agent.memory > 400 ? 'metric-critical' : 
                          agent.memory > 200 ? 'metric-warning' : '';
      
      const cpuClass = agent.cpu > 80 ? 'metric-critical' : 
                       agent.cpu > 50 ? 'metric-warning' : '';

      // Determine agent health class
      let agentHealthClass = 'healthy';
      if (agent.restarts > 50 || agent.memory > 800 || agent.cpu > 95) {
        agentHealthClass = 'critical';
      } else if (agent.restarts > 20 || agent.memory > 400 || agent.cpu > 80) {
        agentHealthClass = 'warning';
      }

      // Heartbeat indicator
      let heartbeatClass = '';
      if (agentHealthClass === 'critical') {
        heartbeatClass = 'critical';
      } else if (agentHealthClass === 'warning') {
        heartbeatClass = 'warning';
      }

      // Memory leak indicator
      const memoryLeak = agent.memory > 600 ? 
        `<div class="memory-leak-indicator">MEMORY LEAK</div>` : '';

      // Restart frequency graph
      const restartPercentage = Math.min(100, (agent.restarts / 100) * 100);

      const errorLogs = agent.errorLogs && agent.errorLogs.length > 0 ? 
        `<div class="error-logs">${agent.errorLogs.join('<br>')}</div>` : '';

      return `
        <div class="agent-card ${agentHealthClass}">
          ${memoryLeak}
          <div class="agent-header">
            <div class="agent-name">
              <span class="heartbeat ${heartbeatClass}"></span>
              ${agent.name}
            </div>
            <div class="agent-status ${statusClass}">${agent.status.toUpperCase()}</div>
          </div>
          
          <div class="agent-metrics">
            <div class="metric">
              <span class="metric-icon">🔄</span>
              <span class="metric-value ${restartClass}">Restarts: ${agent.restarts}</span>
            </div>
            <div class="metric">
              <span class="metric-icon">⏱️</span>
              <span class="metric-value">Uptime: ${agent.uptimeFormatted}</span>
            </div>
            <div class="metric">
              <span class="metric-icon">💾</span>
              <span class="metric-value ${memoryClass}">Memory: ${agent.memory}MB</span>
            </div>
            <div class="metric">
              <span class="metric-icon">⚡</span>
              <span class="metric-value ${cpuClass}">CPU: ${agent.cpu}%</span>
            </div>
          </div>

          <!-- Restart Frequency Graph -->
          <div class="restart-graph">
            <div class="restart-bar" style="width: ${restartPercentage}%">
              <div class="restart-label">${agent.restarts} restarts</div>
            </div>
          </div>

          <div class="progress-bar">
            <div class="progress-fill progress-cpu" style="width: ${Math.min(100, agent.cpu)}%"></div>
          </div>
          
          <div class="progress-bar" style="margin-top: 8px;">
            <div class="progress-fill progress-memory" style="width: ${Math.min(100, agent.memory / 5)}%"></div>
          </div>

          ${errorLogs}

          <div class="agent-actions">
            <button class="action-btn" onclick="resetAndRestart('${agent.name}')">Reset & Restart</button>
            <button class="action-btn" onclick="viewLastErrors('${agent.name}')">Last 10 Errors</button>
            <button class="action-btn" onclick="restartAgent('${agent.name}')">Restart</button>
            <button class="action-btn" onclick="stopAgent('${agent.name}')">Stop</button>
            <button class="action-btn" onclick="viewLogs('${agent.name}')">Logs</button>
          </div>
        </div>
      `;
    }

    // Agent actions
    async function restartAgent(name) {
      if (!confirm(`Restart agent ${name}?`)) return;
      
      showLoading(true);
      try {
        const response = await fetch(`/api/restart/${name}`, { method: 'POST' });
        const result = await response.json();
        
        if (result.success) {
          showAlert(`Agent ${name} restarted`, 'success');
          setTimeout(refreshData, 2000);
        } else {
          showAlert(`Failed to restart ${name}`, 'error');
        }
      } catch (error) {
        showAlert('Error: ' + error.message, 'error');
      } finally {
        showLoading(false);
      }
    }

    async function stopAgent(name) {
      if (!confirm(`Stop agent ${name}?`)) return;
      
      showLoading(true);
      try {
        const response = await fetch(`/api/stop/${name}`, { method: 'POST' });
        const result = await response.json();
        
        if (result.success) {
          showAlert(`Agent ${name} stopped`, 'success');
          setTimeout(refreshData, 2000);
        } else {
          showAlert(`Failed to stop ${name}`, 'error');
        }
      } catch (error) {
        showAlert('Error: ' + error.message, 'error');
      } finally {
        showLoading(false);
      }
    }

    async function viewLogs(name) {
      window.open(`/api/logs/${name}`, '_blank');
    }

    // Restart problematic agents
    async function restartProblematic() {
      if (!confirm('Restart all problematic agents?')) return;
      
      showLoading(true);
      try {
        const response = await fetch('/api/restart-problematic', { method: 'POST' });
        const result = await response.json();
        
        if (result.success) {
          const restarted = result.restarted.filter(r => r.success).length;
          showAlert(`Restarted ${restarted} problematic agents`, 'success');
          setTimeout(refreshData, 3000);
        } else {
          showAlert('Failed to restart problematic agents', 'error');
        }
      } catch (error) {
        showAlert('Error: ' + error.message, 'error');
      } finally {
        showLoading(false);
      }
    }

    // Export report
    function exportReport() {
      window.location.href = '/api/export';
    }

    // EMERGENCY ACTIONS
    
    // Emergency stop all problematic agents
    async function emergencyStopAll() {
      if (!confirm('⚠️ EMERGENCY STOP ALL problematic agents? This will stop all agents with >20 restarts!')) return;
      
      showLoading(true);
      try {
        const response = await fetch('/api/emergency-stop-all', { method: 'POST' });
        const result = await response.json();
        
        if (result.success) {
          showAlert(`Emergency stop completed: ${result.stopped} agents stopped`, 'warning');
          setTimeout(refreshData, 2000);
        } else {
          showAlert('Emergency stop failed', 'error');
        }
      } catch (error) {
        showAlert('Emergency stop error: ' + error.message, 'error');
      } finally {
        showLoading(false);
      }
    }

    // Auto-fix crisis (stop problematic agents, clear logs, restart clean ones)
    async function autoFixCrisis() {
      if (!confirm('🔧 Auto-fix crisis mode? This will stop problematic agents and clear their logs.')) return;
      
      showLoading(true);
      try {
        const response = await fetch('/api/auto-fix-crisis', { method: 'POST' });
        const result = await response.json();
        
        if (result.success) {
          showAlert(`Crisis auto-fix completed: ${result.message}`, 'success');
          setTimeout(refreshData, 3000);
        } else {
          showAlert('Auto-fix failed', 'error');
        }
      } catch (error) {
        showAlert('Auto-fix error: ' + error.message, 'error');
      } finally {
        showLoading(false);
      }
    }

    // Auto-fix common issues
    async function autoFixCommonIssues() {
      if (!confirm('🔧 Auto-fix common issues? This will clear logs, restart errored agents, and free memory.')) return;
      
      showLoading(true);
      try {
        const response = await fetch('/api/auto-fix-common', { method: 'POST' });
        const result = await response.json();
        
        if (result.success) {
          showAlert(`Auto-fix completed: ${result.message}`, 'success');
          setTimeout(refreshData, 2000);
        } else {
          showAlert('Auto-fix failed', 'error');
        }
      } catch (error) {
        showAlert('Auto-fix error: ' + error.message, 'error');
      } finally {
        showLoading(false);
      }
    }

    // Reset and restart agent (clear logs first)
    async function resetAndRestart(name) {
      if (!confirm(`Reset and restart ${name}? This will clear logs and restart clean.`)) return;
      
      showLoading(true);
      try {
        const response = await fetch(`/api/reset-restart/${name}`, { method: 'POST' });
        const result = await response.json();
        
        if (result.success) {
          showAlert(`${name} reset and restarted`, 'success');
          setTimeout(refreshData, 2000);
        } else {
          showAlert(`Failed to reset ${name}`, 'error');
        }
      } catch (error) {
        showAlert('Reset error: ' + error.message, 'error');
      } finally {
        showLoading(false);
      }
    }

    // View last 10 errors in modal
    async function viewLastErrors(name) {
      try {
        const response = await fetch(`/api/last-errors/${name}`);
        const result = await response.json();
        
        if (result.success) {
          const errors = result.errors.join('\\n');
          alert(`Last 10 errors for ${name}:\\n\\n${errors}`);
        } else {
          showAlert('No recent errors found', 'warning');
        }
      } catch (error) {
        showAlert('Error fetching logs: ' + error.message, 'error');
      }
    }

    // Dismiss crisis banner
    function dismissCrisis() {
      document.getElementById('crisisBanner').classList.remove('active');
      const header = document.querySelector('.header');
      header.classList.remove('crisis-mode');
      crisisMode = false; // Temporarily dismiss
      showAlert('Crisis alert dismissed (will reactivate if conditions persist)', 'warning');
    }

    // Toggle audio alerts
    function toggleAudioAlerts() {
      audioEnabled = !audioEnabled;
      const button = document.getElementById('audioToggle');
      const icon = audioEnabled ? '🔊' : '🔇';
      const text = audioEnabled ? 'ON' : 'OFF';
      button.innerHTML = `<span>${icon}</span> Audio: ${text}`;
      
      showAlert(`Audio alerts ${text}`, 'success');
    }

    // Show loading
    function showLoading(show) {
      document.getElementById('loadingOverlay').classList.toggle('active', show);
    }

    // Show alert
    function showAlert(message, type) {
      const alert = document.getElementById('alert');
      alert.textContent = message;
      alert.className = `alert alert-${type}`;
      alert.style.display = 'block';
      
      setTimeout(() => {
        alert.style.display = 'none';
      }, 3000);
    }
  </script>
</body>
</html>