// [TSM.ID].[11031972] -- All Rights Reserved. Proprietary & Confidential.
// Phase 1: Tenant Monitor Dashboard — Live Monitoring + Intrusion Detection
import { useState, useEffect, useCallback } from 'react';

const API = '/xcu-api/v1/monitor';
const REFRESH_INTERVAL = 10000;

const SEVERITY_COLORS = {
  CRITICAL: '#ff003c',
  HIGH: '#ff6600',
  MEDIUM: '#ffea00',
  LOW: '#00ff88',
};

const SEVERITY_ICONS = {
  CRITICAL: '🔴',
  HIGH: '🟠',
  MEDIUM: '🟡',
  LOW: '🟢',
};

function formatBytes(bytes) {
  if (!bytes) return '0 B';
  const k = 1024;
  const sizes = ['B', 'KB', 'MB', 'GB'];
  const i = Math.floor(Math.log(bytes) / Math.log(k));
  return `${(bytes / Math.pow(k, i)).toFixed(1)} ${sizes[i]}`;
}

function formatUptime(startTs) {
  if (!startTs) return '-';
  const diff = Date.now() - startTs;
  const h = Math.floor(diff / 3600000);
  const m = Math.floor((diff % 3600000) / 60000);
  return h > 0 ? `${h}h ${m}m` : `${m}m`;
}

// Tenant-to-service mapping (auto-detected from PM2 service names)
const TENANT_SERVICE_MAP = {
  '__XCU__': { label: 'XCU INFRASTRUCTURE', prefix: 'xcu-', color: '#ff003c' },
  'JUMPA.ID': { label: 'JUMPA.ID', prefix: 'jumpa-', color: '#00f3ff' },
};

export default function TenantMonitor() {
  const [selectedTenant, setSelectedTenant] = useState(null);
  const [tenants, setTenants] = useState([]);
  const [activePanel, setActivePanel] = useState('health');
  const [health, setHealth] = useState(null);
  const [traffic, setTraffic] = useState(null);
  const [logs, setLogs] = useState(null);
  const [intrusions, setIntrusions] = useState(null);
  const [selectedService, setSelectedService] = useState('');
  const [blocked, setBlocked] = useState(null);
  const [hideBlocked, setHideBlocked] = useState(true);
  const [searchQuery, setSearchQuery] = useState('');
  const [lastRefresh, setLastRefresh] = useState(null);
  const [isLoading, setIsLoading] = useState(false);
  const [alertCount, setAlertCount] = useState(0);

  // Fetch tenant list on mount
  useEffect(() => {
    fetch('/xcu-api/v1/tenants').then(r => r.json()).then(data => {
      const list = (Array.isArray(data) ? data : []).map(t => ({
        key: t.tenant_key || t.tenant_name,
        name: t.tenant_name,
        status: t.status || 'active'
      }));
      setTenants(list);
    }).catch(() => {});
  }, []);

  // Filter services based on selected tenant
  const getFilteredServices = (services) => {
    if (!selectedTenant || selectedTenant === '__ALL__') return services;
    const mapping = TENANT_SERVICE_MAP[selectedTenant];
    if (mapping) return services.filter(s => s.name.startsWith(mapping.prefix));
    // For dynamic tenants, try matching by tenant key prefix
    return services.filter(s => s.name.toLowerCase().includes(selectedTenant.toLowerCase().split('.')[0].split(' ')[0]));
  };

  const fetchData = useCallback(async (panel) => {
    setIsLoading(true);
    try {
      const target = panel || activePanel;
      if (target === 'health') {
        const r = await fetch(`${API}/health`);
        const d = await r.json();
        setHealth(d);
        const downCount = (d.services || []).filter(s => s.status !== 'online').length;
        setAlertCount(prev => Math.max(prev, downCount));
      } else if (target === 'traffic') {
        const q = searchQuery ? `?q=${encodeURIComponent(searchQuery)}` : '';
        const r = await fetch(`${API}/traffic${q}`);
        setTraffic(await r.json());
      } else if (target === 'logs') {
        const q = searchQuery ? `&q=${encodeURIComponent(searchQuery)}` : '';
        const r = await fetch(`${API}/logs/${selectedService}?lines=10${q}`);
        setLogs(await r.json());
      } else if (target === 'intrusions') {
        const [r, rb] = await Promise.all([fetch(`${API}/intrusions`), fetch(`${API}/blocked`)]);
        const d = await r.json();
        setIntrusions(d);
        setAlertCount(d.total || 0);
        setBlocked(await rb.json());
      } else if (target === 'blocked') {
        const r = await fetch(`${API}/blocked`);
        setBlocked(await r.json());
      }
      setLastRefresh(new Date());
    } catch (e) {
      console.error('[MONITOR]', e);
    }
    setIsLoading(false);
  }, [activePanel, searchQuery, selectedService]);

  useEffect(() => {
    fetchData();
    const interval = setInterval(() => fetchData(), REFRESH_INTERVAL);
    return () => clearInterval(interval);
  }, [fetchData]);

  const handleBlockIP = async (ip, action) => {
    if (!confirm(`${action === 'block' ? 'BLOCK' : 'UNBLOCK'} IP ${ip}?`)) return;
    await fetch(`${API}/block-ip`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ ip, action }),
    });
    fetchData('intrusions');
    if (activePanel === 'blocked') fetchData('blocked');
  };

  const panels = [
    { id: 'health', label: '🏥 Service Health', icon: '🏥' },
    { id: 'traffic', label: '📊 Live Traffic', icon: '📊' },
    { id: 'logs', label: '📋 Log Viewer', icon: '📋' },
    { id: 'intrusions', label: `🚨 Intrusions${alertCount > 0 ? ` (${alertCount})` : ''}`, icon: '🚨' },
    { id: 'blocked', label: `🛡 Blocked IPs${blocked?.total > 0 ? ` (${blocked.total})` : ''}`, icon: '🛡' },
  ];

  // If no tenant selected, show tenant picker
  if (!selectedTenant) {
    return (
      <div className="glass-panel" style={{ padding: '30px', borderColor: 'var(--accent-cyan)' }}>
        <h2 style={{ color: 'var(--accent-cyan)', textTransform: 'uppercase', letterSpacing: '2px', marginBottom: '10px' }}>
          📡 Tenant Monitor
        </h2>
        <p style={{ color: 'var(--text-muted)', fontSize: '0.85rem', marginBottom: '25px' }}>
          Pilih tenant untuk memantau infrastruktur:
        </p>
        <div style={{ display: 'flex', flexWrap: 'wrap', gap: '15px' }}>
          {/* XCU Infrastructure */}
          <button
            onClick={() => setSelectedTenant('__ALL__')}
            style={{
              flex: '1 1 200px', padding: '25px 20px', background: 'rgba(255,255,255,0.03)',
              border: '1px solid var(--table-border)', borderRadius: '10px', cursor: 'pointer',
              textAlign: 'left', transition: 'all 0.2s'
            }}
            onMouseEnter={e => { e.currentTarget.style.borderColor = '#00f3ff'; e.currentTarget.style.background = 'rgba(0,243,255,0.05)'; }}
            onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--table-border)'; e.currentTarget.style.background = 'rgba(255,255,255,0.03)'; }}
          >
            <div style={{ fontSize: '1.5rem', marginBottom: '8px' }}>🌐</div>
            <div style={{ color: '#00f3ff', fontWeight: 'bold', fontFamily: 'monospace', fontSize: '0.95rem' }}>ALL INFRASTRUCTURE</div>
            <div style={{ color: 'var(--text-muted)', fontSize: '0.75rem', marginTop: '5px' }}>XCU + Semua Tenant</div>
          </button>
          <button
            onClick={() => setSelectedTenant('__XCU__')}
            style={{
              flex: '1 1 200px', padding: '25px 20px', background: 'rgba(255,255,255,0.03)',
              border: '1px solid var(--table-border)', borderRadius: '10px', cursor: 'pointer',
              textAlign: 'left', transition: 'all 0.2s'
            }}
            onMouseEnter={e => { e.currentTarget.style.borderColor = '#ff003c'; e.currentTarget.style.background = 'rgba(255,0,60,0.05)'; }}
            onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--table-border)'; e.currentTarget.style.background = 'rgba(255,255,255,0.03)'; }}
          >
            <div style={{ fontSize: '1.5rem', marginBottom: '8px' }}>⬡</div>
            <div style={{ color: '#ff003c', fontWeight: 'bold', fontFamily: 'monospace', fontSize: '0.95rem' }}>XCU ENGINE</div>
            <div style={{ color: 'var(--text-muted)', fontSize: '0.75rem', marginTop: '5px' }}>Gatekeeper, Omni-Relay, Core</div>
          </button>
          {/* JUMPA.ID (hardcoded known tenant) */}
          <button
            onClick={() => setSelectedTenant('JUMPA.ID')}
            style={{
              flex: '1 1 200px', padding: '25px 20px', background: 'rgba(255,255,255,0.03)',
              border: '1px solid var(--table-border)', borderRadius: '10px', cursor: 'pointer',
              textAlign: 'left', transition: 'all 0.2s'
            }}
            onMouseEnter={e => { e.currentTarget.style.borderColor = '#00f3ff'; e.currentTarget.style.background = 'rgba(0,243,255,0.05)'; }}
            onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--table-border)'; e.currentTarget.style.background = 'rgba(255,255,255,0.03)'; }}
          >
            <div style={{ fontSize: '1.5rem', marginBottom: '8px' }}>🏢</div>
            <div style={{ color: '#00f3ff', fontWeight: 'bold', fontFamily: 'monospace', fontSize: '0.95rem' }}>JUMPA.ID</div>
            <div style={{ color: 'var(--text-muted)', fontSize: '0.75rem', marginTop: '5px' }}>IAM, VC, Chat</div>
          </button>
          {/* Dynamic tenants from DB */}
          {tenants.filter(t => t.name !== 'JUMPA.ID ENTERPRISE').map(t => (
            <button
              key={t.key}
              onClick={() => setSelectedTenant(t.key)}
              style={{
                flex: '1 1 200px', padding: '25px 20px', background: 'rgba(255,255,255,0.03)',
                border: '1px solid var(--table-border)', borderRadius: '10px', cursor: 'pointer',
                textAlign: 'left', transition: 'all 0.2s'
              }}
              onMouseEnter={e => { e.currentTarget.style.borderColor = 'var(--accent-purple)'; e.currentTarget.style.background = 'rgba(168,85,247,0.05)'; }}
              onMouseLeave={e => { e.currentTarget.style.borderColor = 'var(--table-border)'; e.currentTarget.style.background = 'rgba(255,255,255,0.03)'; }}
            >
              <div style={{ fontSize: '1.5rem', marginBottom: '8px' }}>🏢</div>
              <div style={{ color: 'var(--accent-purple)', fontWeight: 'bold', fontFamily: 'monospace', fontSize: '0.95rem' }}>{t.name}</div>
              <div style={{ color: 'var(--text-muted)', fontSize: '0.75rem', marginTop: '5px' }}>{t.key}</div>
            </button>
          ))}
        </div>
      </div>
    );
  }

  const tenantLabel = selectedTenant === '__ALL__' ? 'ALL INFRASTRUCTURE' 
    : selectedTenant === '__XCU__' ? 'XCU ENGINE'
    : TENANT_SERVICE_MAP[selectedTenant]?.label || selectedTenant;

  return (
    <div className="glass-panel" style={{ padding: '30px', borderColor: 'var(--accent-cyan)' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '15px' }}>
          <button
            onClick={() => setSelectedTenant(null)}
            style={{
              padding: '6px 12px', background: 'rgba(255,255,255,0.05)',
              color: 'var(--text-muted)', border: '1px solid var(--table-border)',
              borderRadius: '4px', cursor: 'pointer', fontFamily: 'monospace', fontSize: '0.8rem'
            }}
          >
            ← BACK
          </button>
          <div>
            <h2 style={{ color: 'var(--accent-cyan)', textTransform: 'uppercase', letterSpacing: '2px', margin: 0 }}>
              📡 {tenantLabel}
            </h2>
            <p style={{ color: 'var(--text-muted)', fontSize: '0.8rem', margin: '5px 0 0' }}>
              Live monitoring — {tenantLabel}
            </p>
          </div>
        </div>
        <div style={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
          {lastRefresh && (
            <span style={{ color: 'var(--text-muted)', fontSize: '0.7rem', fontFamily: 'monospace' }}>
              {lastRefresh.toLocaleTimeString()}
            </span>
          )}
          <button
            onClick={() => fetchData()}
            disabled={isLoading}
            style={{
              padding: '8px 15px', background: 'rgba(0, 243, 255, 0.1)',
              color: 'var(--accent-cyan)', border: '1px solid var(--accent-cyan)',
              borderRadius: '4px', cursor: 'pointer', fontFamily: 'monospace',
              opacity: isLoading ? 0.5 : 1
            }}
          >
            {isLoading ? '⏳' : '🔄'} REFRESH
          </button>
        </div>
      </div>

      {/* Panel Tabs */}
      <div style={{ display: 'flex', gap: '5px', marginBottom: '20px', flexWrap: 'wrap' }}>
        {panels.map(p => (
          <button
            key={p.id}
            onClick={() => { setActivePanel(p.id); setSearchQuery(''); }}
            style={{
              padding: '10px 18px',
              background: activePanel === p.id ? 'rgba(0, 243, 255, 0.15)' : 'rgba(255,255,255,0.03)',
              color: activePanel === p.id ? 'var(--accent-cyan)' : 'var(--text-muted)',
              border: `1px solid ${activePanel === p.id ? 'var(--accent-cyan)' : 'var(--table-border)'}`,
              borderRadius: '6px', cursor: 'pointer', fontFamily: 'monospace', fontSize: '0.85rem',
              transition: 'all 0.2s',
            }}
          >
            {p.label}
          </button>
        ))}
      </div>

      {/* Search Bar */}
      {(activePanel === 'traffic' || activePanel === 'logs') && (
        <div style={{ display: 'flex', gap: '10px', marginBottom: '15px' }}>
          <input
            type="text"
            placeholder="🔍 Search logs..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            onKeyDown={(e) => e.key === 'Enter' && fetchData()}
            style={{
              flex: 1, padding: '10px 15px', background: 'rgba(255,255,255,0.03)',
              color: 'var(--text-main)', border: '1px solid var(--table-border)',
              borderRadius: '6px', fontFamily: 'monospace', fontSize: '0.85rem',
              outline: 'none'
            }}
          />
          {activePanel === 'logs' && (
            <select
              value={selectedService}
              onChange={(e) => setSelectedService(e.target.value)}
              style={{
                padding: '10px', background: 'var(--panel-bg)', color: 'var(--text-main)',
                border: '1px solid var(--table-border)', borderRadius: '6px',
                fontFamily: 'monospace', cursor: 'pointer'
              }}
            >
              {(health?.services || []).map(s => (
                <option key={s.name} value={s.name}>{s.name}</option>
              ))}
              {(!health?.services || health.services.length === 0) && (
                <>
                  <option value="jumpa-iam">jumpa-iam</option>
                  <option value="jumpa-vc">jumpa-vc</option>
                  <option value="jumpa-chat">jumpa-chat</option>
                  <option value="xcu-gatekeeper">xcu-gatekeeper</option>
                  <option value="xcu-omni-relay">xcu-omni-relay</option>
                </>
              )}
            </select>
          )}
        </div>
      )}

      {/* ═══ PANEL: SERVICE HEALTH ═══ */}
      {activePanel === 'health' && (
        <div>
          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead>
              <tr style={{ borderBottom: '1px solid var(--table-border)' }}>
                <th style={{ padding: '12px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'left' }}>SERVICE</th>
                <th style={{ padding: '12px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>STATUS</th>
                <th style={{ padding: '12px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>PID</th>
                <th style={{ padding: '12px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>UPTIME</th>
                <th style={{ padding: '12px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>MEMORY</th>
                <th style={{ padding: '12px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>CPU</th>
                <th style={{ padding: '12px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>RESTARTS</th>
              </tr>
            </thead>
            <tbody>
              {getFilteredServices(health?.services || []).map(s => (
                <tr key={s.name} style={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>
                  <td style={{ padding: '12px' }}>
                    <span style={{ color: 'var(--text-main)', fontWeight: 'bold', fontFamily: 'monospace' }}>{s.name}</span>
                  </td>
                  <td style={{ padding: '12px', textAlign: 'center' }}>
                    <span style={{
                      padding: '4px 12px', borderRadius: '20px', fontSize: '0.75rem', fontWeight: 'bold',
                      background: s.status === 'online' ? 'rgba(0,255,136,0.1)' : 'rgba(255,0,60,0.1)',
                      color: s.status === 'online' ? '#00ff88' : '#ff003c',
                      border: `1px solid ${s.status === 'online' ? '#00ff88' : '#ff003c'}`
                    }}>
                      {s.status === 'online' ? '🟢 ONLINE' : '🔴 DOWN'}
                    </span>
                  </td>
                  <td style={{ padding: '12px', textAlign: 'center', color: 'var(--text-muted)', fontFamily: 'monospace', fontSize: '0.8rem' }}>{s.pid}</td>
                  <td style={{ padding: '12px', textAlign: 'center', color: 'var(--accent-cyan)', fontFamily: 'monospace', fontSize: '0.8rem' }}>{formatUptime(s.uptime)}</td>
                  <td style={{ padding: '12px', textAlign: 'center', color: 'var(--accent-purple)', fontFamily: 'monospace', fontSize: '0.8rem' }}>{formatBytes(s.memory)}</td>
                  <td style={{ padding: '12px', textAlign: 'center', color: 'var(--text-muted)', fontFamily: 'monospace', fontSize: '0.8rem' }}>{s.cpu}%</td>
                  <td style={{ padding: '12px', textAlign: 'center' }}>
                    <span style={{ color: s.restarts > 5 ? '#ff003c' : s.restarts > 0 ? '#ffea00' : '#00ff88', fontFamily: 'monospace' }}>
                      {s.restarts}
                    </span>
                  </td>
                </tr>
              ))}
              {(!health?.services || health.services.length === 0) && (
                <tr><td colSpan={7} style={{ padding: '30px', textAlign: 'center', color: 'var(--text-muted)' }}>Loading...</td></tr>
              )}
            </tbody>
          </table>
        </div>
      )}

      {/* ═══ PANEL: LIVE TRAFFIC ═══ */}
      {activePanel === 'traffic' && (
        <div>
          {traffic?.stats && (
            <div style={{ display: 'flex', gap: '15px', marginBottom: '15px', flexWrap: 'wrap' }}>
              {Object.entries(traffic.stats).map(([k, v]) => (
                <div key={k} style={{
                  padding: '12px 20px', background: 'rgba(255,255,255,0.03)',
                  border: '1px solid var(--table-border)', borderRadius: '8px', textAlign: 'center'
                }}>
                  <div style={{ color: 'var(--text-muted)', fontSize: '0.7rem', marginBottom: '5px' }}>{k.toUpperCase()}</div>
                  <div style={{
                    fontSize: '1.4rem', fontWeight: 'bold', fontFamily: 'monospace',
                    color: k === '5xx' ? '#ff003c' : k === '4xx' ? '#ffea00' : k === '2xx' ? '#00ff88' : 'var(--text-main)'
                  }}>{v}</div>
                </div>
              ))}
            </div>
          )}
          <div style={{
            background: 'rgba(0,0,0,0.3)', borderRadius: '8px', padding: '15px',
            fontFamily: 'monospace', fontSize: '0.75rem', maxHeight: '400px', overflow: 'auto'
          }}>
            {(traffic?.entries || []).map((entry, i) => {
              const is4xx = entry.includes('" 4');
              const is5xx = entry.includes('" 5');
              return (
                <div key={i} style={{
                  padding: '4px 0', borderBottom: '1px solid rgba(255,255,255,0.03)',
                  color: is5xx ? '#ff003c' : is4xx ? '#ffea00' : 'var(--text-muted)',
                  wordBreak: 'break-all'
                }}>
                  {entry}
                </div>
              );
            })}
            {(!traffic?.entries || traffic.entries.length === 0) && (
              <div style={{ color: 'var(--text-muted)', textAlign: 'center', padding: '20px' }}>Loading...</div>
            )}
          </div>
        </div>
      )}

      {/* ═══ PANEL: LOG VIEWER ═══ */}
      {activePanel === 'logs' && (
        <div style={{
          background: 'rgba(0,0,0,0.3)', borderRadius: '8px', padding: '15px',
          fontFamily: 'monospace', fontSize: '0.75rem', maxHeight: '500px', overflow: 'auto'
        }}>
          <div style={{ color: 'var(--accent-cyan)', marginBottom: '10px', fontSize: '0.8rem' }}>
            📋 {selectedService} — Last 10 lines
          </div>
          {(logs?.logs || []).map((line, i) => {
            const isError = line.toLowerCase().includes('error') || line.toLowerCase().includes('fail');
            const isWarn = line.toLowerCase().includes('warn');
            return (
              <div key={i} style={{
                padding: '3px 0', borderBottom: '1px solid rgba(255,255,255,0.03)',
                color: isError ? '#ff003c' : isWarn ? '#ffea00' : 'var(--text-muted)',
                wordBreak: 'break-all'
              }}>
                {line}
              </div>
            );
          })}
          {(!logs?.logs || logs.logs.length === 0) && (
            <div style={{ color: 'var(--text-muted)', textAlign: 'center', padding: '20px' }}>
              {logs?.error || 'Loading...'}
            </div>
          )}
        </div>
      )}

      {/* ═══ PANEL: INTRUSION DETECTION ═══ */}
      {activePanel === 'intrusions' && (
        <div>
          <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: '10px' }}>
            <button
              onClick={() => setHideBlocked(!hideBlocked)}
              style={{
                padding: '5px 12px', borderRadius: '4px', cursor: 'pointer', fontSize: '0.7rem', fontFamily: 'monospace',
                background: hideBlocked ? 'rgba(0,255,136,0.1)' : 'rgba(255,0,60,0.1)',
                color: hideBlocked ? '#00ff88' : '#ff003c',
                border: `1px solid ${hideBlocked ? 'rgba(0,255,136,0.3)' : 'rgba(255,0,60,0.3)'}`
              }}
            >
              {hideBlocked ? '👁 Show blocked IPs' : '🚫 Hide blocked IPs'}
            </button>
          </div>
          {intrusions?.bruteForceIPs?.length > 0 && (
            <div style={{
              padding: '12px 15px', background: 'rgba(255, 0, 60, 0.1)', border: '1px solid #ff003c',
              borderRadius: '6px', marginBottom: '15px'
            }}>
              <span style={{ color: '#ff003c', fontWeight: 'bold' }}>⚠ BRUTE FORCE DETECTED: </span>
              {intrusions.bruteForceIPs.map(ip => (
                <span key={ip} style={{ fontFamily: 'monospace', color: '#ff003c', marginRight: '10px' }}>
                  {ip}
                  <button
                    onClick={() => handleBlockIP(ip, 'block')}
                    style={{
                      marginLeft: '5px', padding: '2px 8px', background: 'rgba(255,0,60,0.2)',
                      color: '#ff003c', border: '1px solid #ff003c', borderRadius: '3px',
                      cursor: 'pointer', fontSize: '0.7rem', fontFamily: 'monospace'
                    }}
                  >
                    BLOCK
                  </button>
                </span>
              ))}
            </div>
          )}

          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead>
              <tr style={{ borderBottom: '1px solid var(--table-border)' }}>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>SEV</th>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'left' }}>TYPE</th>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'left' }}>IP</th>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'left' }}>TARGET</th>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>ACTION</th>
              </tr>
            </thead>
            <tbody>
              {(() => {
                // Group intrusions by IP
                const grouped = {};
                (intrusions?.intrusions || []).forEach(item => {
                  const key = item.ip || 'unknown';
                  if (!grouped[key]) {
                    grouped[key] = { ...item, count: 1, types: new Set([item.type]) };
                  } else {
                    grouped[key].count++;
                    grouped[key].types.add(item.type);
                    // Keep highest severity
                    const sevOrder = { CRITICAL: 4, HIGH: 3, MEDIUM: 2, LOW: 1 };
                    if ((sevOrder[item.severity] || 0) > (sevOrder[grouped[key].severity] || 0)) {
                      grouped[key].severity = item.severity;
                    }
                  }
                });
                const blockedIPs = new Set((blocked?.blocked || []).map(b => b.ip));
                return Object.values(grouped)
                  .filter(item => !hideBlocked || !blockedIPs.has(item.ip))
                  .sort((a, b) => b.count - a.count).map((item, i) => (
                <tr key={i} style={{ borderBottom: '1px solid rgba(255,255,255,0.03)' }}>
                  <td style={{ padding: '10px', textAlign: 'center' }}>
                    {SEVERITY_ICONS[item.severity] || '⚪'}
                  </td>
                  <td style={{ padding: '10px' }}>
                    {[...item.types].map(t => (
                      <span key={t} style={{
                        padding: '3px 6px', borderRadius: '3px', fontSize: '0.65rem', fontFamily: 'monospace',
                        background: `${SEVERITY_COLORS[item.severity]}15`,
                        color: SEVERITY_COLORS[item.severity],
                        border: `1px solid ${SEVERITY_COLORS[item.severity]}40`,
                        marginRight: '4px'
                      }}>
                        {t}
                      </span>
                    ))}
                  </td>
                  <td style={{ padding: '10px', fontFamily: 'monospace', fontSize: '0.8rem', color: 'var(--text-muted)' }}>
                    {item.ip || '-'}
                    {item.count > 1 && (
                      <span style={{
                        marginLeft: '6px', padding: '2px 6px', borderRadius: '10px', fontSize: '0.65rem',
                        background: 'rgba(255,234,0,0.15)', color: '#ffea00', border: '1px solid rgba(255,234,0,0.3)'
                      }}>
                        ×{item.count}
                      </span>
                    )}
                  </td>
                  <td style={{ padding: '10px', fontFamily: 'monospace', fontSize: '0.75rem', color: 'var(--text-muted)', maxWidth: '300px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                    {item.target || item.raw?.substring(0, 80) || '-'}
                  </td>
                  <td style={{ padding: '10px', textAlign: 'center' }}>
                    {item.ip && item.ip !== 'unknown' && (() => {
                      const isBlocked = (blocked?.blocked || []).some(b => b.ip === item.ip);
                      return isBlocked ? (
                        <div style={{ display: 'flex', gap: '4px', justifyContent: 'center', alignItems: 'center' }}>
                          <span style={{
                            padding: '4px 8px', background: 'rgba(255,0,60,0.15)',
                            color: '#ff003c', border: '1px solid rgba(255,0,60,0.4)',
                            borderRadius: '3px', fontSize: '0.65rem', fontFamily: 'monospace', fontWeight: 'bold'
                          }}>
                            🛡 BLOCKED
                          </span>
                          <button
                            onClick={() => handleBlockIP(item.ip, 'unblock')}
                            style={{
                              padding: '4px 8px', background: 'rgba(0,255,136,0.1)',
                              color: '#00ff88', border: '1px solid rgba(0,255,136,0.3)',
                              borderRadius: '3px', cursor: 'pointer', fontSize: '0.65rem', fontFamily: 'monospace'
                            }}
                          >
                            🔓 UNBLOCK
                          </button>
                        </div>
                      ) : (
                        <button
                          onClick={() => handleBlockIP(item.ip, 'block')}
                          style={{
                            padding: '4px 8px', background: 'rgba(255,0,60,0.1)',
                            color: '#ff003c', border: '1px solid rgba(255,0,60,0.3)',
                            borderRadius: '3px', cursor: 'pointer', fontSize: '0.65rem', fontFamily: 'monospace'
                          }}
                        >
                          🛡 BLOCK
                        </button>
                      );
                    })()}
                  </td>
                </tr>
              ));
              })()}
              {(!intrusions?.intrusions || intrusions.intrusions.length === 0) && (
                <tr>
                  <td colSpan={5} style={{ padding: '30px', textAlign: 'center', color: '#00ff88' }}>
                    ✅ Tidak ada intrusi terdeteksi
                  </td>
                </tr>
              )}
            </tbody>
          </table>
          <div style={{ marginTop: '10px', color: 'var(--text-muted)', fontSize: '0.7rem', fontFamily: 'monospace' }}>
            Total events: {intrusions?.total || 0} | Auto-refresh: {REFRESH_INTERVAL / 1000}s
          </div>
        </div>
      )}

      {/* ═══ PANEL: BLOCKED IPs ═══ */}
      {activePanel === 'blocked' && (
        <div>
          <div style={{ marginBottom: '15px', color: 'var(--text-muted)', fontSize: '0.85rem' }}>
            IP yang saat ini di-block via <code style={{ color: 'var(--accent-cyan)' }}>iptables</code> pada node ini.
          </div>
          <table style={{ width: '100%', borderCollapse: 'collapse' }}>
            <thead>
              <tr style={{ borderBottom: '1px solid var(--table-border)' }}>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>#</th>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'left' }}>IP ADDRESS</th>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>RULE</th>
                <th style={{ padding: '10px', color: 'var(--text-muted)', fontSize: '0.75rem', textAlign: 'center' }}>ACTION</th>
              </tr>
            </thead>
            <tbody>
              {(blocked?.blocked || []).map((b, i) => (
                <tr key={i} style={{ borderBottom: '1px solid rgba(255,255,255,0.05)' }}>
                  <td style={{ padding: '10px', textAlign: 'center', color: 'var(--text-muted)', fontFamily: 'monospace', fontSize: '0.8rem' }}>{b.num}</td>
                  <td style={{ padding: '10px' }}>
                    <span style={{ color: '#ff003c', fontWeight: 'bold', fontFamily: 'monospace' }}>{b.ip}</span>
                  </td>
                  <td style={{ padding: '10px', textAlign: 'center' }}>
                    <span style={{ padding: '3px 8px', borderRadius: '3px', fontSize: '0.7rem', fontFamily: 'monospace', background: 'rgba(255,0,60,0.1)', color: '#ff003c', border: '1px solid rgba(255,0,60,0.3)' }}>
                      DROP
                    </span>
                  </td>
                  <td style={{ padding: '10px', textAlign: 'center' }}>
                    <button
                      onClick={() => handleBlockIP(b.ip, 'unblock')}
                      style={{
                        padding: '5px 12px', background: 'rgba(0,255,136,0.1)',
                        color: '#00ff88', border: '1px solid rgba(0,255,136,0.3)',
                        borderRadius: '3px', cursor: 'pointer', fontSize: '0.7rem', fontFamily: 'monospace'
                      }}
                    >
                      🔓 UNBLOCK
                    </button>
                  </td>
                </tr>
              ))}
              {(!blocked?.blocked || blocked.blocked.length === 0) && (
                <tr>
                  <td colSpan={4} style={{ padding: '30px', textAlign: 'center', color: '#00ff88' }}>
                    ✅ Tidak ada IP yang di-block
                  </td>
                </tr>
              )}
            </tbody>
          </table>
          <div style={{ marginTop: '10px', color: 'var(--text-muted)', fontSize: '0.7rem', fontFamily: 'monospace' }}>
            Total blocked: {blocked?.total || 0} | Node: {window.location.hostname}
          </div>
        </div>
      )}
    </div>
  );
}
