import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Link } from 'react-router-dom';
import networkMonitorService from '../services/networkMonitorService';
import monitoringService from '../services/monitoringService';
import unifiService from '../services/unifiService';
import externalAlertService from '../services/externalAlertService';
import LoadingSpinner from '../components/common/LoadingSpinner';
import { toast } from 'react-toastify';

// ─── Constants ────────────────────────────────────────────────────────────────
const TYPE_META = {
    host:    { label: 'Host',        icon: '🖥' },
    switch:  { label: 'Switch',      icon: '🔀' },
    ap:      { label: 'Access Point',icon: '📶' },
    router:  { label: 'Router',      icon: '🌐' },
    printer: { label: 'Drucker',     icon: '🖨' },
    nas:     { label: 'NAS',         icon: '💾' },
    service: { label: 'Service',     icon: '⚙' },
};
const CHECK_TYPES = ['icmp', 'http', 'https', 'tcp', 'snmp'];
const INTERVALS = [
    { value: 15, label: '15 Sek' }, { value: 30, label: '30 Sek' },
    { value: 60, label: '1 Min' },  { value: 300, label: '5 Min' },
    { value: 600, label: '10 Min' },
];
const REFRESH_INTERVAL = 30;
const MAX_TS_POINTS = 60;

// State colors – IT Nexus palette (nicht Checkmk!)
const SC = { ok: '#34d399', warn: '#f59e0b', crit: '#ef4444', unknown: '#6b7280' };

// ─── Helpers ──────────────────────────────────────────────────────────────────
const timeAgo = (iso) => {
    if (!iso) return '–';
    const m = Math.floor((Date.now() - new Date(iso).getTime()) / 60000);
    if (m < 1) return 'gerade eben';
    if (m < 60) return `vor ${m} Min`;
    if (m < 1440) return `vor ${Math.floor(m / 60)} Std`;
    return `vor ${Math.floor(m / 1440)} Tagen`;
};
const duration = (iso) => {
    if (!iso) return '–';
    const m = Math.floor((Date.now() - new Date(iso).getTime()) / 60000);
    if (m < 60) return `${m} Min`;
    const h = Math.floor(m / 60), rm = m % 60;
    if (h < 24) return `${h}h ${rm}min`;
    return `${Math.floor(h / 24)}d ${h % 24}h`;
};
const pct    = (val, total) => (total > 0 ? Math.min(100, Math.round((val / total) * 100)) : 0);
const uptimeStr = (h) => { if (!h) return '–'; if (h < 24) return `${Math.floor(h)}h`; return `${Math.floor(h / 24)}d ${Math.floor(h % 24)}h`; };
const netColor  = (s) => s === 'up' ? SC.ok : s === 'down' ? SC.crit : SC.unknown;
const netLabel  = (s) => s === 'up' ? 'UP' : s === 'down' ? 'DOWN' : 'UNBEKANNT';
const fmtTime   = (d) => d instanceof Date ? d.toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit' }) : '–';

const warnings = (a) => {
    const w = [];
    if (a.cpu_usage_percent > 90)       w.push({ type: 'error', msg: `CPU ${a.cpu_usage_percent?.toFixed(0)}%` });
    else if (a.cpu_usage_percent > 80)  w.push({ type: 'warn',  msg: `CPU ${a.cpu_usage_percent?.toFixed(0)}%` });
    if (a.disk_free_gb != null && a.disk_free_gb < 5)   w.push({ type: 'error', msg: `Disk ${a.disk_free_gb?.toFixed(1)}GB` });
    else if (a.disk_free_gb != null && a.disk_free_gb < 15) w.push({ type: 'warn', msg: `Disk ${a.disk_free_gb?.toFixed(0)}GB` });
    if (a.ram_total_gb > 0 && pct(a.ram_used_gb, a.ram_total_gb) > 90) w.push({ type: 'warn', msg: 'RAM voll' });
    if (a.windows_updates_pending > 20) w.push({ type: 'error', msg: `${a.windows_updates_pending} Updates` });
    else if (a.windows_updates_pending > 5) w.push({ type: 'warn', msg: `${a.windows_updates_pending} Updates` });
    if (a.bitlocker_status === 'off') w.push({ type: 'warn', msg: 'BitLocker aus' });
    if (a.defender_enabled === 0) w.push({ type: 'error', msg: 'Defender inaktiv' });
    else if (a.defender_signatures_age > 7) w.push({ type: 'warn', msg: `Defender ${a.defender_signatures_age}d alt` });
    return w;
};

const agentServices = (a) => [
    { name: 'Agent Verbindung', status: a.status === 'online' ? 'ok' : 'crit',
      value: a.status === 'online' ? 'Online' : 'Offline', detail: `Checkin: ${timeAgo(a.last_checkin)}`, perf: null },
    { name: 'CPU Auslastung', status: a.cpu_usage_percent > 90 ? 'crit' : a.cpu_usage_percent > 80 ? 'warn' : 'ok',
      value: a.cpu_usage_percent != null ? `${a.cpu_usage_percent.toFixed(1)}%` : '–',
      detail: a.cpu_model?.replace(/\(R\)|\(TM\)/g, '') || '',
      perf: a.cpu_usage_percent != null ? { val: a.cpu_usage_percent, max: 100, warn: 80, crit: 90, unit: '%' } : null },
    { name: 'RAM Auslastung', status: pct(a.ram_used_gb, a.ram_total_gb) > 95 ? 'crit' : pct(a.ram_used_gb, a.ram_total_gb) > 85 ? 'warn' : 'ok',
      value: a.ram_used_gb != null ? `${a.ram_used_gb.toFixed(1)} / ${a.ram_total_gb?.toFixed(0)} GB` : '–',
      detail: `${pct(a.ram_used_gb, a.ram_total_gb)}% belegt`,
      perf: a.ram_total_gb > 0 ? { val: a.ram_used_gb, max: a.ram_total_gb, warn: 85, crit: 95, unit: '%' } : null },
    { name: 'Festplatte C:', status: (a.disk_free_gb ?? 99) < 5 ? 'crit' : (a.disk_free_gb ?? 99) < 15 ? 'warn' : 'ok',
      value: a.disk_free_gb != null ? `${a.disk_free_gb.toFixed(0)} GB frei` : '–',
      detail: `von ${a.disk_total_gb?.toFixed(0) ?? '–'} GB`,
      perf: a.disk_total_gb > 0 ? { val: a.disk_total_gb - a.disk_free_gb, max: a.disk_total_gb, warn: 75, crit: 90, unit: '%', labelVal: `${a.disk_free_gb?.toFixed(0)} GB frei` } : null },
    { name: 'Windows Updates', status: (a.windows_updates_pending ?? 0) > 20 ? 'crit' : (a.windows_updates_pending ?? 0) > 5 ? 'warn' : 'ok',
      value: `${a.windows_updates_pending ?? 0} ausstehend`, detail: '', perf: null },
];

const netDeviceServices = (d, uptimeStat) => {
    const rtt = d.last_rtt_ms;
    const up = uptimeStat?.pct ?? null;
    return [
        { name: 'ICMP / Ping', status: d.last_status === 'up' ? 'ok' : d.last_status === 'down' ? 'crit' : 'unknown',
          value: d.last_status === 'up' ? 'UP' : d.last_status === 'down' ? 'DOWN' : 'UNBEKANNT',
          detail: rtt != null ? `${Math.round(rtt)} ms` : '', perf: null },
        { name: 'Antwortzeit', status: rtt == null ? 'unknown' : rtt > 1000 ? 'crit' : rtt > 200 ? 'warn' : 'ok',
          value: rtt != null ? `${Math.round(rtt)} ms` : '–', detail: '',
          perf: rtt != null ? { val: rtt, max: 1000, warn: 200, crit: 500, unit: 'ms', labelVal: `${Math.round(rtt)}ms` } : null },
        ...(up != null ? [{ name: 'Uptime (24h)', status: up >= 99 ? 'ok' : up >= 90 ? 'warn' : 'crit',
          value: `${up}%`, detail: '', perf: { val: 100 - up, max: 100, warn: 10, crit: 20, unit: '%', labelVal: `${up}% up` } }] : []),
    ];
};

const proxmoxServices = (px) => {
    if (!px?.node) return [];
    const { node, vms = [], lxcs = [], storage = [] } = px;
    const cpuPct = (node.cpu || 0) * 100;
    const ramPct = node.memory?.total > 0 ? (node.memory.used / node.memory.total) * 100 : 0;
    const fsPct  = node.rootfs?.total > 0 ? (node.rootfs.used / node.rootfs.total) * 100 : 0;
    const load   = node.loadavg?.[0] || 0;
    const cpus   = node.cpuinfo?.cpus || 1;
    const runVMs = vms.filter(v => v.status === 'running').length;
    const runCTs = lxcs.filter(c => c.status === 'running').length;
    const svcs = [
        { name: 'CPU Auslastung', status: cpuPct >= 90 ? 'crit' : cpuPct >= 70 ? 'warn' : 'ok',
          value: `${cpuPct.toFixed(1)}%`, detail: `${node.cpuinfo?.cpus || '?'} CPUs`,
          perf: { val: cpuPct, max: 100, warn: 70, crit: 90, unit: '%' } },
        { name: 'RAM Auslastung', status: ramPct >= 90 ? 'crit' : ramPct >= 80 ? 'warn' : 'ok',
          value: `${ramPct.toFixed(1)}%`, detail: `${(node.memory?.used/1073741824).toFixed(1)} / ${(node.memory?.total/1073741824).toFixed(1)} GB`,
          perf: { val: ramPct, max: 100, warn: 80, crit: 90, unit: '%' } },
        { name: 'Root Filesystem', status: fsPct >= 90 ? 'crit' : fsPct >= 80 ? 'warn' : 'ok',
          value: `${fsPct.toFixed(1)}%`, detail: `${(node.rootfs?.avail/1073741824).toFixed(1)} GB frei`,
          perf: { val: fsPct, max: 100, warn: 80, crit: 90, unit: '%' } },
        { name: 'Load Average', status: load > cpus * 0.9 ? 'crit' : load > cpus * 0.7 ? 'warn' : 'ok',
          value: load.toFixed(2), detail: `${node.loadavg?.map(l => l.toFixed(2)).join(' / ') || ''}`,
          perf: { val: load, max: cpus, warn: cpus * 0.7, crit: cpus * 0.9, unit: '', labelVal: load.toFixed(2) } },
        { name: 'VMs', status: 'ok', value: `${runVMs}/${vms.length} laufend`, detail: '', perf: null },
        { name: 'Container', status: 'ok', value: `${runCTs}/${lxcs.length} laufend`, detail: '', perf: null },
        ...storage.filter(s => s.active && s.total > 0).map(s => {
            const p = (s.used / s.total) * 100;
            return { name: `Storage: ${s.storage}`, status: p >= 90 ? 'crit' : p >= 80 ? 'warn' : 'ok',
              value: `${p.toFixed(1)}%`, detail: `${(s.avail/1073741824).toFixed(1)} GB frei`,
              perf: { val: p, max: 100, warn: 80, crit: 90, unit: '%' } };
        }),
    ];
    return svcs;
};

// ─── UI Primitives ─────────────────────────────────────────────────────────────

// Checkmk-style State-Square: kleines farbiges Label mit Zustandstext
const StateSquare = ({ state, text, size = 'sm' }) => {
    const color = SC[state] || SC.unknown;
    const label = text || state?.toUpperCase() || '?';
    return (
        <span style={{
            display: 'inline-block', background: `${color}22`, color,
            border: `1px solid ${color}60`, borderRadius: 3,
            padding: size === 'lg' ? '3px 10px' : '1px 6px',
            fontSize: size === 'lg' ? 12 : 10,
            fontWeight: 700, letterSpacing: .3, whiteSpace: 'nowrap',
            fontFamily: 'monospace',
        }}>{label}</span>
    );
};

// Checkmk-style Perf-O-Meter mit WARN/CRIT Schwelllinien
const PerfBar = ({ val, max, warn = 80, crit = 90, unit = '%', labelVal = null }) => {
    if (val == null || max == null || max === 0) return <span style={{ color: 'var(--text-muted)', fontSize: 11 }}>–</span>;
    const fillPct  = Math.min((val / max) * 100, 100);
    const warnPct  = warn;
    const critPct  = crit;
    const color    = fillPct >= critPct ? SC.crit : fillPct >= warnPct ? SC.warn : SC.ok;
    const display  = labelVal ?? `${fillPct.toFixed(0)}${unit}`;
    return (
        <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 140 }}>
            <div style={{ flex: 1, position: 'relative', height: 8, background: 'rgba(255,255,255,0.07)', borderRadius: 2, overflow: 'visible' }}>
                {/* Fill */}
                <div style={{ position: 'absolute', left: 0, top: 0, height: '100%', width: `${fillPct}%`, background: color, borderRadius: 2, transition: 'width .5s', maxWidth: '100%' }} />
                {/* WARN threshold line */}
                {warnPct < 100 && (
                    <div style={{ position: 'absolute', left: `${warnPct}%`, top: -2, bottom: -2, width: 1.5, background: `${SC.warn}bb`, borderRadius: 1 }} />
                )}
                {/* CRIT threshold line */}
                {critPct < 100 && (
                    <div style={{ position: 'absolute', left: `${critPct}%`, top: -2, bottom: -2, width: 1.5, background: `${SC.crit}bb`, borderRadius: 1 }} />
                )}
            </div>
            <span style={{ fontSize: 11, fontWeight: 700, color, minWidth: 42, textAlign: 'right', fontFamily: 'monospace' }}>{display}</span>
        </div>
    );
};

// Uptime %-Anzeige (für Netzwerkgeräte)
const UptimePill = ({ pct: p }) => {
    if (p == null) return <span style={{ color: 'var(--text-muted)', fontSize: 11 }}>–</span>;
    const color = p >= 99 ? SC.ok : p >= 90 ? SC.warn : SC.crit;
    return <span style={{ fontSize: 11, fontWeight: 700, color, fontFamily: 'monospace' }}>{p}%</span>;
};

const NetDot = ({ status, size = 10 }) => (
    <span style={{ display: 'inline-block', width: size, height: size, borderRadius: '50%', background: netColor(status), boxShadow: status === 'up' ? `0 0 6px ${netColor(status)}` : 'none', animation: status === 'up' ? 'nmPulse 2s infinite' : 'none', flexShrink: 0 }} />
);

const UptimeSparkline = ({ checks }) => {
    if (!checks || checks.length === 0) return <div style={{ color: 'var(--text-muted)', fontSize: 11 }}>Keine Daten</div>;
    const seg = checks.slice(-80);
    const w = 240, h = 28, sw = w / seg.length;
    return (
        <svg width={w} height={h} style={{ borderRadius: 4, overflow: 'hidden' }}>
            {seg.map((c, i) => <rect key={i} x={i * sw} y={0} width={Math.max(sw - 0.5, 1)} height={h} fill={c.status === 'up' ? SC.ok : SC.crit} opacity={0.85} />)}
        </svg>
    );
};

const RttSparkline = ({ checks }) => {
    const vals = checks.filter(c => c.rtt_ms != null).map(c => c.rtt_ms);
    if (vals.length < 2) return <div style={{ color: 'var(--text-muted)', fontSize: 11 }}>–</div>;
    const max = Math.max(...vals);
    const w = 240, h = 40;
    const pts = vals.slice(-60).map((v, i) => { const x = (i / (vals.slice(-60).length - 1)) * w; const y = h - (v / max) * (h - 4) - 2; return `${x},${y}`; }).join(' ');
    return <svg width={w} height={h}><polyline points={pts} fill="none" stroke="var(--accent)" strokeWidth="1.5" /></svg>;
};

const WarnBadge = ({ w }) => (
    <span style={{ fontSize: 10, fontWeight: 700, padding: '2px 6px', borderRadius: 4, background: w.type === 'error' ? `${SC.crit}22` : `${SC.warn}22`, color: w.type === 'error' ? SC.crit : SC.warn, border: `1px solid ${w.type === 'error' ? SC.crit : SC.warn}44` }}>{w.msg}</span>
);

const TimeSeriesChart = ({ data, key1, key2, height = 110 }) => {
    const vbW = 400, vbH = height;
    if (!data || data.length < 2) return <div style={{ height, display: 'flex', alignItems: 'center', justifyContent: 'center', color: 'var(--text-muted)', fontSize: 12 }}>Daten werden gesammelt...</div>;
    const v1 = data.map(d => d[key1] || 0), v2 = data.map(d => d[key2] || 0);
    const maxV = Math.max(...v1, ...v2, 1);
    const pad = { top: 8, right: 8, bottom: 24, left: 24 };
    const cw = vbW - pad.left - pad.right, ch = vbH - pad.top - pad.bottom;
    const toX = (i) => pad.left + (i / (data.length - 1)) * cw;
    const toY = (v) => pad.top + ch - (v / maxV) * ch;
    const path = (vals) => vals.map((v, i) => `${i === 0 ? 'M' : 'L'}${toX(i)},${toY(v)}`).join(' ');
    const area = (vals) => { const l = vals.map((v, i) => `${i === 0 ? 'M' : 'L'}${toX(i)},${toY(v)}`).join(' '); const n = vals.length - 1; return `${l} L${toX(n)},${toY(0)} L${toX(0)},${toY(0)} Z`; };
    const xl = data.length > 1 ? [0, Math.floor(data.length / 2), data.length - 1].map(i => ({ i, t: fmtTime(data[i].time) })) : [];
    return (
        <svg viewBox={`0 0 ${vbW} ${vbH}`} style={{ width: '100%', height }}>
            {[0, Math.ceil(maxV / 2), maxV].map(v => <line key={v} x1={pad.left} y1={toY(v)} x2={pad.left + cw} y2={toY(v)} stroke="var(--border-color)" strokeWidth="0.7" />)}
            <path d={area(v1)} fill={`${SC.crit}18`} />
            <path d={area(v2)} fill={`${SC.warn}18`} />
            <path d={path(v1)} fill="none" stroke={SC.crit} strokeWidth="1.8" />
            <path d={path(v2)} fill="none" stroke={SC.warn} strokeWidth="1.8" />
            {[0, Math.ceil(maxV / 2), maxV].map(v => <text key={v} x={pad.left - 4} y={toY(v) + 4} textAnchor="end" fontSize="9" fill={SC.unknown}>{v}</text>)}
            {xl.map(({ i, t }) => <text key={i} x={toX(i)} y={vbH - 4} textAnchor="middle" fontSize="9" fill={SC.unknown}>{t}</text>)}
        </svg>
    );
};

// ─── Tactical Overview — New KPI Card Design ─────────────────────────────────
const TacticalOverview = ({ devices, agents, problems, acknowledged, countdown, lastUpdated, onTabChange, extAlerts = [] }) => {
    const openP = problems.filter(p => !acknowledged.has(p.id));
    const critN = openP.filter(p => p.severity <= 1).length;
    const warnN = openP.filter(p => p.severity === 2).length;

    const hostUp    = devices.filter(d => d.last_status === 'up').length;
    const hostDown  = devices.filter(d => d.last_status === 'down').length;
    const hostUnk   = devices.filter(d => !d.last_status || d.last_status === 'unknown').length;
    const agOnline  = agents.filter(a => a.status === 'online').length;
    const agOffline = agents.filter(a => a.status === 'offline').length;
    const agWarn    = agents.filter(a => warnings(a).some(w => w.type === 'warn') && a.status === 'online').length;
    const pxAlerts  = extAlerts.filter(a => a.source === 'proxmox' && !a.acknowledged);
    const pxCrit    = pxAlerts.filter(a => a.severity === 'CRIT').length;
    const pxWarn    = pxAlerts.filter(a => a.severity === 'WARN').length;

    const KpiCard = ({ icon, name, accent, num, den, breaks, bar, onClick }) => (
        <div className="mon-kpi" onClick={onClick} style={{ cursor: onClick ? 'pointer' : 'default' }}>
            <div className="mon-kpi-head">
                <div className="mon-kpi-ic" style={{ color: accent }}>{icon}</div>
                <div className="mon-kpi-name">{name}</div>
            </div>
            <div className="mon-kpi-row">
                <div style={{ display: 'flex', alignItems: 'baseline', gap: 6 }}>
                    <span className="mon-kpi-num" style={{ color: accent }}>{num}</span>
                    {den && <span className="mon-kpi-den">/ {den}</span>}
                </div>
                <div className="mon-kpi-breaks">
                    {breaks.map((b, i) => (
                        <div key={i} className="mon-kpi-break">
                            <div className="mon-kpi-break-num" style={{ color: b[2] }}>{b[0]}</div>
                            <div className="mon-kpi-break-lbl">{b[1]}</div>
                        </div>
                    ))}
                </div>
            </div>
            <div className="mon-kpi-bar">
                {bar.map((s, i) => <span key={i} style={{ width: `${s[0]}%`, background: s[1], height: '100%' }} />)}
            </div>
        </div>
    );

    const total = hostUp + hostDown + hostUnk || 1;
    const agTotal = agents.length || 1;

    return (
        <div className="mon-kpis">
            <KpiCard
                icon="🖥️" name="Gesamtzustand" accent="#e8eef6"
                num={hostUp + agOnline - agWarn} den={null}
                breaks={[[critN, 'Krit', SC.crit], [warnN, 'Warn', SC.warn], [hostUp + agOnline - agWarn - critN, 'OK', SC.ok]]}
                bar={[[Math.round(critN / (devices.length + agTotal) * 100), SC.crit], [Math.round(warnN / (devices.length + agTotal) * 100), SC.warn], [Math.max(0, 100 - Math.round((critN + warnN) / (devices.length + agTotal) * 100)), SC.ok]]}
                onClick={critN > 0 || warnN > 0 ? () => onTabChange('problems') : null}
            />
            <KpiCard
                icon="🌐" name="Netzwerk-Geräte" accent={SC.ok}
                num={hostUp} den={devices.length}
                breaks={[[hostDown, 'Down', SC.crit], [hostUnk, '?', SC.unknown]]}
                bar={[[Math.round(hostDown / total * 100), SC.crit], [Math.round(hostUnk / total * 100), SC.unknown], [Math.round(hostUp / total * 100), SC.ok]]}
                onClick={hostDown > 0 ? () => onTabChange('network') : null}
            />
            <KpiCard
                icon="⚡" name="Windows Agents" accent={SC.ok}
                num={agOnline} den={agents.length}
                breaks={[[agOffline, 'Off', SC.crit], [agWarn, 'Warn', SC.warn]]}
                bar={[[Math.round(agOffline / agTotal * 100), SC.crit], [Math.round(agWarn / agTotal * 100), SC.warn], [Math.max(0, 100 - Math.round((agOffline + agWarn) / agTotal * 100)), SC.ok]]}
                onClick={agOffline > 0 || agWarn > 0 ? () => onTabChange('agents') : null}
            />
            <KpiCard
                icon="🔧" name="Proxmox" accent={pxCrit > 0 ? SC.crit : pxWarn > 0 ? SC.warn : SC.ok}
                num={pxCrit > 0 ? pxCrit : pxWarn > 0 ? pxWarn : 1} den={null}
                breaks={[[pxCrit, 'Krit', SC.crit], [pxWarn, 'Warn', SC.warn], [countdown + 's', 'Refresh', 'var(--text-muted)']]}
                bar={[[pxCrit > 0 ? 100 : pxWarn > 0 ? 60 : 0, pxCrit > 0 ? SC.crit : SC.warn], [pxCrit > 0 ? 0 : 100, SC.ok]]}
                onClick={pxCrit > 0 || pxWarn > 0 ? () => onTabChange('overview') : null}
            />
        </div>
    );
};

// ─── Modals (unverändert) ─────────────────────────────────────────────────────
const DiscoverModal = ({ onClose, onAdd }) => {
    const [subnet, setSubnet] = useState('192.168.0');
    const [scanning, setScanning] = useState(false);
    const [progress, setProgress] = useState(0);
    const [results, setResults] = useState(null);
    const [selected, setSelected] = useState({});
    const [typeOverrides, setTypeOverrides] = useState({});
    const [adding, setAdding] = useState(false);
    const progressRef = useRef(null);
    const startScan = async () => {
        setScanning(true); setResults(null); setSelected({}); setProgress(0);
        let p = 0;
        progressRef.current = setInterval(() => { p = Math.min(p + 1.2, 90); setProgress(p); }, 500);
        try {
            const res = await networkMonitorService.discover(subnet);
            clearInterval(progressRef.current); setProgress(100);
            setResults(res.data || []);
            const sel = {}; (res.data || []).forEach(d => sel[d.ip] = true); setSelected(sel);
        } catch { clearInterval(progressRef.current); toast.error('Scan fehlgeschlagen'); }
        finally { setScanning(false); }
    };
    const addSelected = async () => {
        const toAdd = (results || []).filter(d => selected[d.ip]); if (!toAdd.length) return;
        setAdding(true); let added = 0;
        for (const d of toAdd) { try { const type = typeOverrides[d.ip] || d.type; const device = await networkMonitorService.create({ name: d.hostname || d.ip, type, host: d.ip, check_type: d.check_type, interval_sec: 60, timeout_sec: 5, enabled: 1 }); onAdd(device); added++; } catch {} }
        toast.success(`${added} Gerät${added !== 1 ? 'e' : ''} hinzugefügt`); setAdding(false); onClose();
    };
    const toggleAll = (val) => { const sel = {}; (results || []).forEach(d => sel[d.ip] = val); setSelected(sel); };
    const inp = { padding: '8px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'var(--bg-secondary)', color: 'var(--text-primary)', fontSize: 13 };
    return (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.65)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center' }} onClick={e => e.target === e.currentTarget && !scanning && onClose()}>
            <div style={{ background: 'var(--bg-primary)', borderRadius: 12, width: '100%', maxWidth: 600, maxHeight: '90vh', overflow: 'hidden', display: 'flex', flexDirection: 'column', border: '1px solid var(--border-color)' }}>
                <div style={{ padding: '16px 20px', borderBottom: '1px solid var(--border-color)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <h2 style={{ fontSize: 16, fontWeight: 700 }}>📡 Netzwerk scannen</h2>
                    {!scanning && <button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--text-muted)', fontSize: 22, cursor: 'pointer' }}>×</button>}
                </div>
                <div style={{ padding: 20, overflowY: 'auto', flex: 1 }}>
                    <div style={{ display: 'flex', gap: 10, marginBottom: 16, alignItems: 'flex-end' }}>
                        <div style={{ flex: 1 }}>
                            <label style={{ fontSize: 11, color: 'var(--text-muted)', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '.4px', display: 'block', marginBottom: 6 }}>Subnetz (erste 3 Oktette)</label>
                            <input style={{ ...inp, width: '100%', boxSizing: 'border-box' }} value={subnet} onChange={e => setSubnet(e.target.value)} disabled={scanning} />
                        </div>
                        <button onClick={startScan} disabled={scanning || !subnet} style={{ padding: '9px 20px', borderRadius: 7, border: 'none', background: 'var(--accent)', color: '#fff', cursor: scanning ? 'not-allowed' : 'pointer', fontWeight: 700, fontSize: 13 }}>{scanning ? 'Scanne...' : '▶ Scan starten'}</button>
                    </div>
                    {(scanning || results !== null) && (
                        <div style={{ marginBottom: 16 }}>
                            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, color: 'var(--text-muted)', marginBottom: 6 }}>
                                <span>{scanning ? `Scanne ${subnet}.1–${subnet}.254...` : `${results?.length || 0} Geräte gefunden`}</span>
                                <span>{Math.round(progress)}%</span>
                            </div>
                            <div style={{ background: 'var(--border-color)', borderRadius: 4, height: 6, overflow: 'hidden' }}>
                                <div style={{ height: '100%', width: `${progress}%`, background: progress === 100 ? SC.ok : 'var(--accent)', borderRadius: 4, transition: 'width .4s' }} />
                            </div>
                        </div>
                    )}
                    {results !== null && results.length === 0 && <div style={{ textAlign: 'center', color: 'var(--text-muted)', padding: 30 }}>Keine neuen Geräte im Subnetz {subnet}.x</div>}
                    {results && results.length > 0 && (
                        <>
                            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
                                <span style={{ fontSize: 13, fontWeight: 600 }}>{Object.values(selected).filter(Boolean).length} / {results.length} ausgewählt</span>
                                <div style={{ display: 'flex', gap: 8 }}>
                                    <button onClick={() => toggleAll(true)} style={{ fontSize: 11, padding: '3px 10px', borderRadius: 5, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', cursor: 'pointer' }}>Alle</button>
                                    <button onClick={() => toggleAll(false)} style={{ fontSize: 11, padding: '3px 10px', borderRadius: 5, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', cursor: 'pointer' }}>Keine</button>
                                </div>
                            </div>
                            <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
                                {results.map(d => (
                                    <div key={d.ip} onClick={() => setSelected(s => ({ ...s, [d.ip]: !s[d.ip] }))} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '10px 12px', borderRadius: 8, background: selected[d.ip] ? `${SC.ok}10` : 'var(--bg-secondary)', border: `1px solid ${selected[d.ip] ? SC.ok + '50' : 'var(--border-color)'}`, cursor: 'pointer' }}>
                                        <input type="checkbox" checked={!!selected[d.ip]} onChange={() => {}} style={{ accentColor: 'var(--accent)' }} />
                                        <span style={{ fontSize: 18 }}>{TYPE_META[typeOverrides[d.ip] || d.type]?.icon || '🖥'}</span>
                                        <div style={{ flex: 1, minWidth: 0 }}>
                                            <div style={{ fontWeight: 600, fontSize: 13 }}>{d.ip}</div>
                                            {d.hostname && <div style={{ fontSize: 11, color: 'var(--text-muted)', overflow: 'hidden', textOverflow: 'ellipsis' }}>{d.hostname}</div>}
                                            {d.open_ports?.length > 0 && <div style={{ fontSize: 10, color: 'var(--text-muted)' }}>Ports: {d.open_ports.join(', ')}</div>}
                                        </div>
                                        <select value={typeOverrides[d.ip] || d.type} onChange={e => { e.stopPropagation(); setTypeOverrides(t => ({ ...t, [d.ip]: e.target.value })); }} onClick={e => e.stopPropagation()} style={{ fontSize: 11, padding: '3px 6px', borderRadius: 5, border: '1px solid var(--border-color)', background: 'var(--bg-primary)', color: 'var(--text-primary)', cursor: 'pointer' }}>
                                            {Object.entries(TYPE_META).map(([k, v]) => <option key={k} value={k}>{v.icon} {v.label}</option>)}
                                        </select>
                                    </div>
                                ))}
                            </div>
                        </>
                    )}
                </div>
                {results && results.length > 0 && (
                    <div style={{ padding: '14px 20px', borderTop: '1px solid var(--border-color)', display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
                        <button onClick={onClose} disabled={adding} style={{ padding: '8px 16px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-primary)', cursor: 'pointer', fontSize: 13 }}>Abbrechen</button>
                        <button onClick={addSelected} disabled={adding || !Object.values(selected).some(Boolean)} style={{ padding: '8px 18px', borderRadius: 7, border: 'none', background: 'var(--accent)', color: '#fff', cursor: 'pointer', fontWeight: 700, fontSize: 13 }}>{adding ? 'Lädt...' : `${Object.values(selected).filter(Boolean).length} hinzufügen`}</button>
                    </div>
                )}
            </div>
        </div>
    );
};

const DeviceFormModal = ({ device, onSave, onClose }) => {
    const [form, setForm] = useState({ name: '', type: 'host', host: '', check_type: 'icmp', port: '', http_path: '/', http_keyword: '', snmp_community: 'public', snmp_version: '2c', interval_sec: 60, timeout_sec: 5, enabled: 1, notify_email: '', location: '', ...(device || {}) });
    const [saving, setSaving] = useState(false);
    const set = (k, v) => setForm(f => ({ ...f, [k]: v }));
    const save = async () => {
        if (!form.name || !form.host) return toast.error('Name und Host sind Pflichtfelder');
        setSaving(true);
        try { const r = device ? await networkMonitorService.update(device.id, form) : await networkMonitorService.create(form); onSave(r); onClose(); toast.success(device ? 'Aktualisiert' : 'Hinzugefügt'); }
        catch { toast.error('Fehler beim Speichern'); } finally { setSaving(false); }
    };
    const inp = { width: '100%', padding: '8px 10px', borderRadius: 6, border: '1px solid var(--border-color)', background: 'var(--bg-primary)', color: 'var(--text-primary)', fontSize: 13, boxSizing: 'border-box' };
    const lbl = { fontSize: 11, color: 'var(--text-muted)', fontWeight: 700, marginBottom: 4, display: 'block', textTransform: 'uppercase', letterSpacing: '.4px' };
    return (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.6)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center' }} onClick={e => e.target === e.currentTarget && onClose()}>
            <div style={{ background: 'var(--bg-primary)', borderRadius: 12, width: '100%', maxWidth: 540, maxHeight: '90vh', overflow: 'auto', border: '1px solid var(--border-color)' }}>
                <div style={{ padding: '18px 20px', borderBottom: '1px solid var(--border-color)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <h2 style={{ fontSize: 16, fontWeight: 700 }}>{device ? 'Gerät bearbeiten' : 'Neues Gerät'}</h2>
                    <button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--text-muted)', fontSize: 20, cursor: 'pointer' }}>×</button>
                </div>
                <div style={{ padding: 20, display: 'grid', gap: 14 }}>
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                        <div><label style={lbl}>Name *</label><input style={inp} value={form.name} onChange={e => set('name', e.target.value)} /></div>
                        <div><label style={lbl}>Typ</label><select style={inp} value={form.type} onChange={e => set('type', e.target.value)}>{Object.entries(TYPE_META).map(([k, v]) => <option key={k} value={k}>{v.icon} {v.label}</option>)}</select></div>
                    </div>
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                        <div><label style={lbl}>Host / IP *</label><input style={inp} value={form.host} onChange={e => set('host', e.target.value)} /></div>
                        <div><label style={lbl}>Standort</label><input style={inp} value={form.location || ''} onChange={e => set('location', e.target.value)} /></div>
                    </div>
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
                        <div><label style={lbl}>Check-Typ</label><select style={inp} value={form.check_type} onChange={e => set('check_type', e.target.value)}>{CHECK_TYPES.map(t => <option key={t} value={t}>{t.toUpperCase()}</option>)}</select></div>
                        {['tcp','http','https'].includes(form.check_type) && <div><label style={lbl}>Port</label><input style={inp} type="number" value={form.port || ''} onChange={e => set('port', e.target.value)} /></div>}
                        <div><label style={lbl}>Intervall</label><select style={inp} value={form.interval_sec} onChange={e => set('interval_sec', parseInt(e.target.value))}>{INTERVALS.map(i => <option key={i.value} value={i.value}>{i.label}</option>)}</select></div>
                    </div>
                    {['http','https'].includes(form.check_type) && (
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                            <div><label style={lbl}>Pfad</label><input style={inp} value={form.http_path || '/'} onChange={e => set('http_path', e.target.value)} /></div>
                            <div><label style={lbl}>Keyword (opt.)</label><input style={inp} value={form.http_keyword || ''} onChange={e => set('http_keyword', e.target.value)} /></div>
                        </div>
                    )}
                    {form.check_type === 'snmp' && (
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                            <div><label style={lbl}>Community</label><input style={inp} value={form.snmp_community || 'public'} onChange={e => set('snmp_community', e.target.value)} placeholder="public" /></div>
                            <div><label style={lbl}>Version</label><select style={inp} value={form.snmp_version || '2c'} onChange={e => set('snmp_version', e.target.value)}><option value="2c">v2c</option><option value="1">v1</option></select></div>
                        </div>
                    )}
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                        <div><label style={lbl}>Timeout (s)</label><input style={inp} type="number" min="1" max="30" value={form.timeout_sec} onChange={e => set('timeout_sec', parseInt(e.target.value))} /></div>
                        <div><label style={lbl}>Alert E-Mail</label><input style={inp} value={form.notify_email || ''} onChange={e => set('notify_email', e.target.value)} /></div>
                    </div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                        <input type="checkbox" id="devEnabled" checked={!!form.enabled} onChange={e => set('enabled', e.target.checked ? 1 : 0)} />
                        <label htmlFor="devEnabled" style={{ fontSize: 13, cursor: 'pointer' }}>Monitoring aktiv</label>
                    </div>
                </div>
                <div style={{ padding: '14px 20px', borderTop: '1px solid var(--border-color)', display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
                    <button onClick={onClose} style={{ padding: '8px 18px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-primary)', cursor: 'pointer', fontSize: 13 }}>Abbrechen</button>
                    <button onClick={save} disabled={saving} style={{ padding: '8px 18px', borderRadius: 7, border: 'none', background: 'var(--accent)', color: '#fff', cursor: 'pointer', fontSize: 13, fontWeight: 600 }}>{saving ? '...' : 'Speichern'}</button>
                </div>
            </div>
        </div>
    );
};

const NetworkDetailModal = ({ device, onClose, onEdit, onDelete, onCheckNow }) => {
    const [checksData, setChecksData] = useState(null);
    const [timeRange, setTimeRange] = useState(24);
    const [checking, setChecking] = useState(false);
    useEffect(() => { networkMonitorService.getChecks(device.id, timeRange).then(setChecksData).catch(() => {}); }, [device.id, timeRange]);
    const doCheckNow = async () => { setChecking(true); try { await onCheckNow(device.id); toast.success('Check ausgeführt'); const d = await networkMonitorService.getChecks(device.id, timeRange); setChecksData(d); } catch { toast.error('Fehlgeschlagen'); } finally { setChecking(false); } };
    const meta = TYPE_META[device.type] || TYPE_META.host;
    const uptime = checksData?.uptime, checks = checksData?.checks || [];
    return (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.6)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center' }} onClick={e => e.target === e.currentTarget && onClose()}>
            <div style={{ background: 'var(--bg-primary)', borderRadius: 12, width: '100%', maxWidth: 660, maxHeight: '90vh', overflow: 'auto', border: `1px solid var(--border-color)`, borderTop: `3px solid ${netColor(device.last_status)}` }}>
                <div style={{ padding: '16px 20px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderBottom: '1px solid var(--border-color)' }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                        <span style={{ fontSize: 24 }}>{meta.icon}</span>
                        <div><div style={{ fontWeight: 700, fontSize: 16 }}>{device.name}</div><div style={{ color: 'var(--text-muted)', fontSize: 12 }}>{device.host} · {meta.label}</div></div>
                    </div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
                        <StateSquare state={device.last_status === 'up' ? 'ok' : device.last_status === 'down' ? 'crit' : 'unknown'} text={netLabel(device.last_status)} size="lg" />
                        <button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--text-muted)', fontSize: 22, cursor: 'pointer' }}>×</button>
                    </div>
                </div>
                <div style={{ padding: 20 }}>
                    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 10, marginBottom: 20 }}>
                        {[{ label: 'Letzter Check', value: timeAgo(device.last_checked) }, { label: 'Antwortzeit', value: device.last_rtt_ms != null ? `${Math.round(device.last_rtt_ms)} ms` : '–' }, { label: `Uptime ${timeRange}h`, value: uptime?.total > 0 ? `${uptime.pct}%` : '–', color: uptime?.pct >= 99 ? SC.ok : uptime?.pct >= 90 ? SC.warn : SC.crit }].map(m => (
                            <div key={m.label} style={{ background: 'var(--bg-secondary)', borderRadius: 8, padding: '10px 14px' }}>
                                <div style={{ fontSize: 11, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '.4px', marginBottom: 4 }}>{m.label}</div>
                                <div style={{ fontSize: 18, fontWeight: 700, color: m.color || 'var(--text-primary)', fontFamily: 'monospace' }}>{m.value}</div>
                            </div>
                        ))}
                    </div>
                    <div style={{ marginBottom: 16 }}>
                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 8 }}>
                            <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '.4px' }}>Uptime-Verlauf</div>
                            <div style={{ display: 'flex', gap: 4 }}>{[24, 48, 168].map(h => <button key={h} onClick={() => setTimeRange(h)} style={{ padding: '3px 10px', borderRadius: 5, fontSize: 11, fontWeight: 600, cursor: 'pointer', border: `1px solid ${timeRange === h ? 'var(--accent)' : 'var(--border-color)'}`, background: timeRange === h ? 'var(--accent)' : 'var(--bg-secondary)', color: timeRange === h ? '#fff' : 'var(--text-muted)' }}>{h === 168 ? '7d' : `${h}h`}</button>)}</div>
                        </div>
                        <div style={{ background: 'var(--bg-secondary)', borderRadius: 8, padding: 10 }}>
                            <UptimeSparkline checks={checks} />
                            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 10, color: 'var(--text-muted)', marginTop: 4 }}>
                                <span>Grün = Online · Rot = Offline</span><span>{uptime?.up ?? 0}/{uptime?.total ?? 0} OK</span>
                            </div>
                        </div>
                    </div>
                    {checks.some(c => c.rtt_ms != null) && (
                        <div style={{ marginBottom: 16 }}>
                            <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '.4px', marginBottom: 8 }}>Antwortzeit (ms)</div>
                            <div style={{ background: 'var(--bg-secondary)', borderRadius: 8, padding: 10 }}><RttSparkline checks={checks} /></div>
                        </div>
                    )}
                    <div style={{ background: 'var(--bg-secondary)', borderRadius: 8, padding: '12px 14px', marginBottom: 16 }}>
                        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '.4px', marginBottom: 8 }}>Konfiguration</div>
                        <div style={{ display: 'grid', gridTemplateColumns: '130px 1fr', gap: '5px 12px', fontSize: 13, lineHeight: 1.7 }}>
                            {[['Check-Typ', device.check_type?.toUpperCase()], ['Intervall', `${device.interval_sec}s`], ['Timeout', `${device.timeout_sec}s`], device.port && ['Port', device.port], device.location && ['Standort', device.location], device.notify_email && ['Alert E-Mail', device.notify_email]].filter(Boolean).map(([k, v]) => (
                                <React.Fragment key={k}><span style={{ color: 'var(--text-muted)' }}>{k}</span><span style={{ fontWeight: 600 }}>{v}</span></React.Fragment>
                            ))}
                        </div>
                    </div>
                    {[...checks].reverse().slice(0, 15).length > 0 && (
                        <div>
                            <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '.4px', marginBottom: 8 }}>Letzte Checks</div>
                            <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                                <tbody>{[...checks].reverse().slice(0, 15).map((c, i) => (
                                    <tr key={i} style={{ borderBottom: '1px solid var(--border-color)' }}>
                                        <td style={{ padding: '5px 8px' }}><StateSquare state={c.status === 'up' ? 'ok' : 'crit'} text={c.status === 'up' ? 'UP' : 'DOWN'} /></td>
                                        <td style={{ padding: '5px 8px', color: 'var(--text-muted)', fontFamily: 'monospace' }}>{c.rtt_ms != null ? `${Math.round(c.rtt_ms)} ms` : '–'}</td>
                                        <td style={{ padding: '5px 8px', color: 'var(--text-muted)', textAlign: 'right', fontFamily: 'monospace', fontSize: 11 }}>{new Date(c.checked_at).toLocaleString('de-DE', { day: '2-digit', month: '2-digit', hour: '2-digit', minute: '2-digit' })}</td>
                                        {c.error_msg && <td style={{ padding: '5px 8px', color: SC.crit, fontSize: 11 }}>{c.error_msg}</td>}
                                    </tr>
                                ))}</tbody>
                            </table>
                        </div>
                    )}
                </div>
                <div style={{ padding: '14px 20px', borderTop: '1px solid var(--border-color)', display: 'flex', gap: 8 }}>
                    <button onClick={doCheckNow} disabled={checking} style={{ padding: '7px 14px', borderRadius: 7, border: '1px solid var(--accent)', background: 'none', color: 'var(--accent)', cursor: 'pointer', fontSize: 13, fontWeight: 600 }}>{checking ? '...' : '▶ Jetzt prüfen'}</button>
                    <button onClick={() => { onEdit(device); onClose(); }} style={{ padding: '7px 14px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-primary)', cursor: 'pointer', fontSize: 13 }}>Bearbeiten</button>
                    <div style={{ flex: 1 }} />
                    <button onClick={() => onDelete(device)} style={{ padding: '7px 14px', borderRadius: 7, border: `1px solid ${SC.crit}`, background: 'none', color: SC.crit, cursor: 'pointer', fontSize: 13 }}>Löschen</button>
                </div>
            </div>
        </div>
    );
};

const AgentDetailModal = ({ agent, onClose, onDelete }) => {
    const [swSearch, setSwSearch] = useState('');
    const w = warnings(agent);
    const sw = (agent.installed_software || []).filter(s => !swSearch || s.toLowerCase().includes(swSearch.toLowerCase()));
    return (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.6)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20 }} onClick={onClose}>
            <div style={{ background: 'var(--bg-primary)', border: '1px solid var(--border-color)', borderRadius: 14, width: '100%', maxWidth: 720, maxHeight: '90vh', overflow: 'hidden', display: 'flex', flexDirection: 'column' }} onClick={e => e.stopPropagation()}>
                <div style={{ padding: '20px 24px', borderBottom: '1px solid var(--border-color)', display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start' }}>
                    <div>
                        <div style={{ display: 'flex', alignItems: 'center', gap: 10, marginBottom: 4 }}>
                            <span style={{ fontSize: 20, fontWeight: 700, fontFamily: 'monospace' }}>{agent.hostname}</span>
                            <StateSquare state={agent.status === 'online' ? 'ok' : 'crit'} text={agent.status === 'online' ? 'ONLINE' : 'OFFLINE'} size="lg" />
                        </div>
                        <div style={{ fontSize: 13, color: 'var(--text-muted)' }}>{agent.os_name} {agent.os_version}</div>
                        {w.length > 0 && <div style={{ display: 'flex', gap: 5, marginTop: 8, flexWrap: 'wrap' }}>{w.map((x, i) => <WarnBadge key={i} w={x} />)}</div>}
                    </div>
                    <button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--text-muted)', fontSize: 20, cursor: 'pointer' }}>✕</button>
                </div>
                <div style={{ overflowY: 'auto', flex: 1 }}>
                    <div style={{ padding: '16px 24px', display: 'grid', gridTemplateColumns: 'repeat(3,1fr)', gap: 12, borderBottom: '1px solid var(--border-color)' }}>
                        {[{ label: 'CPU', val: `${agent.cpu_usage_percent?.toFixed(0) ?? '–'}%`, sub: agent.cpu_model?.replace(/\(R\)|\(TM\)/g, '') || '–' }, { label: 'RAM', val: `${agent.ram_used_gb?.toFixed(1) ?? '–'} / ${agent.ram_total_gb?.toFixed(0) ?? '–'} GB`, sub: `${pct(agent.ram_used_gb, agent.ram_total_gb)}% belegt` }, { label: 'Disk C:', val: `${agent.disk_free_gb?.toFixed(0) ?? '–'} GB frei`, sub: `von ${agent.disk_total_gb?.toFixed(0) ?? '–'} GB` }].map(m => (
                            <div key={m.label} style={{ background: 'var(--bg-secondary)', borderRadius: 8, padding: '12px 14px' }}>
                                <div style={{ fontSize: 11, color: 'var(--text-muted)', fontWeight: 700, textTransform: 'uppercase', letterSpacing: '.5px', marginBottom: 4 }}>{m.label}</div>
                                <div style={{ fontSize: 18, fontWeight: 700, fontFamily: 'monospace' }}>{m.val}</div>
                                <div style={{ fontSize: 11, color: 'var(--text-muted)', marginTop: 2, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{m.sub}</div>
                            </div>
                        ))}
                    </div>
                    <div style={{ padding: '16px 24px', borderBottom: '1px solid var(--border-color)' }}>
                        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '.5px', marginBottom: 10 }}>Systeminfos</div>
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 4 }}>
                            {[['IP-Adresse', agent.ip_address || '–'], ['MAC-Adresse', agent.mac_address || '–'], ['Domain', agent.domain || '–'], ['Letzter Benutzer', agent.last_user || '–'], ['Uptime', uptimeStr(agent.uptime_hours)], ['CPU-Kerne', agent.cpu_cores || '–'], ['Windows Updates', `${agent.windows_updates_pending ?? 0} ausstehend`], ['Agent Version', `v${agent.agent_version || '?'}`], ['Letzter Checkin', timeAgo(agent.last_checkin)], ['Registriert', new Date(agent.created_at).toLocaleDateString('de-DE')]].map(([k, v]) => (
                                <div key={k} style={{ display: 'flex', justifyContent: 'space-between', padding: '6px 0', borderBottom: '1px solid var(--border-color)', fontSize: 13 }}>
                                    <span style={{ color: 'var(--text-muted)' }}>{k}</span><span style={{ fontWeight: 500 }}>{v}</span>
                                </div>
                            ))}
                        </div>
                    </div>
                    <div style={{ padding: '16px 24px', borderBottom: '1px solid var(--border-color)' }}>
                        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '.5px', marginBottom: 10 }}>Sicherheit</div>
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 4 }}>
                            {[
                                ['BitLocker', (() => {
                                    const s = agent.bitlocker_status;
                                    if (s === 'encrypted') return { label: '✓ Verschlüsselt', color: '#22c55e' };
                                    if (s === 'off') return { label: '✗ Nicht aktiv', color: '#ef4444' };
                                    return { label: '? Unbekannt', color: 'var(--text-muted)' };
                                })()],
                                ['Microsoft Defender', (() => {
                                    if (agent.defender_enabled == null) return { label: '? Unbekannt', color: 'var(--text-muted)' };
                                    if (!agent.defender_enabled) return { label: '✗ Inaktiv', color: '#ef4444' };
                                    const age = agent.defender_signatures_age;
                                    if (age == null || age < 0) return { label: '✓ Aktiv', color: '#22c55e' };
                                    if (age <= 3) return { label: '✓ Aktiv · Signaturen aktuell', color: '#22c55e' };
                                    return { label: `⚠ Aktiv · Signaturen ${age}d alt`, color: '#f59e0b' };
                                })()],
                                ['Seriennummer', { label: agent.hardware_serial || '–', color: agent.hardware_serial ? 'var(--text-primary)' : 'var(--text-muted)' }],
                                ['TPM', { label: agent.tpm_v2 ? '✓ TPM 2.0' : agent.tpm_present ? `TPM ${agent.tpm_version || '?'}` : '✗ Nicht vorhanden', color: agent.tpm_v2 ? '#22c55e' : agent.tpm_present ? '#f59e0b' : '#ef4444' }],
                                ['Secure Boot', { label: agent.secure_boot ? '✓ Aktiv' : '✗ Inaktiv', color: agent.secure_boot ? '#22c55e' : '#ef4444' }],
                                ['Win 11 Ready', { label: agent.win11_ready ? '✓ Ja' : '✗ Nein', color: agent.win11_ready ? '#22c55e' : 'var(--text-muted)' }],
                            ].map(([k, v]) => (
                                <div key={k} style={{ display: 'flex', justifyContent: 'space-between', padding: '6px 0', borderBottom: '1px solid var(--border-color)', fontSize: 13 }}>
                                    <span style={{ color: 'var(--text-muted)' }}>{k}</span>
                                    <span style={{ fontWeight: 600, color: v.color }}>{v.label}</span>
                                </div>
                            ))}
                        </div>
                    </div>
                    {agent.installed_software?.length > 0 && (
                        <div style={{ padding: '16px 24px' }}>
                            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 10 }}>
                                <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: '.5px' }}>Software ({agent.installed_software.length})</div>
                                <input placeholder="Suchen..." value={swSearch} onChange={e => setSwSearch(e.target.value)} style={{ padding: '4px 10px', borderRadius: 6, border: '1px solid var(--border-color)', background: 'var(--bg-secondary)', color: 'var(--text-primary)', fontSize: 12, width: 160 }} />
                            </div>
                            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 4, maxHeight: 180, overflowY: 'auto' }}>
                                {sw.map((s, i) => <div key={i} style={{ fontSize: 12, color: 'var(--text-muted)', padding: '4px 8px', background: 'var(--bg-secondary)', borderRadius: 4, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }} title={s}>{s}</div>)}
                            </div>
                        </div>
                    )}
                </div>
                <div style={{ padding: '14px 24px', borderTop: '1px solid var(--border-color)', display: 'flex', justifyContent: 'flex-end' }}>
                    <button onClick={() => onDelete(agent.id, agent.hostname)} style={{ padding: '7px 16px', background: `${SC.crit}18`, color: SC.crit, border: `1px solid ${SC.crit}44`, borderRadius: 7, cursor: 'pointer', fontSize: 13 }}>Agent entfernen</button>
                </div>
            </div>
        </div>
    );
};

// ─── Unifi Config Modal (top-level so React doesn't remount on every render) ──
const UnifiConfigModal = ({ unifiConfig, onSave, onClose }) => {
    const [form, setForm] = useState({
        controller_url: '', username: '', password: '', site: 'default', poll_interval_min: 5,
        ...(unifiConfig || {}), enabled: !!unifiConfig?.enabled,
    });
    const [saving, setSaving] = useState(false);
    const setF = (k, v) => setForm(f => ({ ...f, [k]: v }));
    const inp = { width: '100%', padding: '8px 10px', borderRadius: 6, border: '1px solid var(--border-color)', background: 'var(--bg-primary)', color: 'var(--text-primary)', fontSize: 13, boxSizing: 'border-box' };
    const lbl = { fontSize: 11, color: 'var(--text-muted)', fontWeight: 700, marginBottom: 4, display: 'block', textTransform: 'uppercase', letterSpacing: '.4px' };
    const save = async () => {
        setSaving(true);
        try { const c = await unifiService.saveConfig(form); onSave(c); onClose(); }
        catch (e) { alert(e.message || 'Fehler'); } finally { setSaving(false); }
    };
    return (
        <div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,.6)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center' }} onClick={e => e.target === e.currentTarget && onClose()}>
            <div style={{ background: 'var(--bg-primary)', borderRadius: 12, width: '100%', maxWidth: 480, border: '1px solid var(--border-color)' }}>
                <div style={{ padding: '18px 20px', borderBottom: '1px solid var(--border-color)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                    <h2 style={{ fontSize: 16, fontWeight: 700 }}>📶 Unifi Controller</h2>
                    <button onClick={onClose} style={{ background: 'none', border: 'none', color: 'var(--text-muted)', fontSize: 20, cursor: 'pointer' }}>×</button>
                </div>
                <div style={{ padding: 20, display: 'grid', gap: 12 }}>
                    <div><label style={lbl}>Controller URL</label><input style={inp} value={form.controller_url} onChange={e => setF('controller_url', e.target.value)} placeholder="https://192.168.0.1:8443" /></div>
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                        <div><label style={lbl}>Benutzername</label><input style={inp} value={form.username} onChange={e => setF('username', e.target.value)} /></div>
                        <div><label style={lbl}>Passwort</label><input style={inp} type="password" value={form.password} onChange={e => setF('password', e.target.value)} placeholder="leer = unverändert" /></div>
                    </div>
                    <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 12 }}>
                        <div><label style={lbl}>Site</label><input style={inp} value={form.site} onChange={e => setF('site', e.target.value)} placeholder="default" /></div>
                        <div><label style={lbl}>Poll-Intervall (Min)</label><input style={inp} type="number" min="1" max="60" value={form.poll_interval_min} onChange={e => setF('poll_interval_min', parseInt(e.target.value))} /></div>
                    </div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
                        <input type="checkbox" id="unifiEnabled" checked={!!form.enabled} onChange={e => setF('enabled', e.target.checked)} />
                        <label htmlFor="unifiEnabled" style={{ fontSize: 13, cursor: 'pointer' }}>Unifi-Polling aktiviert</label>
                    </div>
                </div>
                <div style={{ padding: '14px 20px', borderTop: '1px solid var(--border-color)', display: 'flex', justifyContent: 'flex-end', gap: 10 }}>
                    <button onClick={onClose} style={{ padding: '8px 18px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-primary)', cursor: 'pointer', fontSize: 13 }}>Abbrechen</button>
                    <button onClick={save} disabled={saving} style={{ padding: '8px 18px', borderRadius: 7, border: 'none', background: 'var(--accent)', color: '#fff', cursor: 'pointer', fontSize: 13, fontWeight: 600 }}>{saving ? '...' : 'Speichern'}</button>
                </div>
            </div>
        </div>
    );
};

// ─── Main Page ────────────────────────────────────────────────────────────────
const MonitoringPage = () => {
    const [devices,        setDevices]        = useState([]);
    const [agents,         setAgents]         = useState([]);
    const [loading,        setLoading]        = useState(true);
    const [timeSeriesData, setTimeSeriesData] = useState([]);
    const [recentChecks,   setRecentChecks]   = useState([]);
    const [selectedDevice, setSelectedDevice] = useState(null);
    const [selectedAgent,  setSelectedAgent]  = useState(null);
    const [showDeviceForm, setShowDeviceForm] = useState(false);
    const [editDevice,     setEditDevice]     = useState(null);
    const [showDiscover,   setShowDiscover]   = useState(false);
    const [showDeploy,     setShowDeploy]     = useState(false);
    const [countdown,      setCountdown]      = useState(REFRESH_INTERVAL);
    const [activeTab,      setActiveTab]      = useState('overview');
    const [netSearch,      setNetSearch]      = useState('');
    const [netFilter,      setNetFilter]      = useState('all');
    const [agentSearch,    setAgentSearch]    = useState('');
    const [agentFilter,    setAgentFilter]    = useState('all');
    const [expandedAgents, setExpandedAgents] = useState(new Set());
    const [expandedHosts,  setExpandedHosts]  = useState(new Set());
    const [ovSelectedId,   setOvSelectedId]   = useState(null);
    const [agentSort,      setAgentSort]      = useState('cpu');
    const [hostFilter,     setHostFilter]     = useState('all');
    const [hostSearch,     setHostSearch]     = useState('');
    const [proxmoxData,    setProxmoxData]    = useState(null);
    const [acknowledged,   setAcknowledged]   = useState(new Set());
    const [showAcked,      setShowAcked]      = useState(false);
    const [uptimeStats,    setUptimeStats]    = useState({});
    const [collapsedGroups,setCollapsedGroups]= useState(new Set());
    const [unifiDevices,   setUnifiDevices]   = useState([]);
    const [unifiConfig,    setUnifiConfig]    = useState(null);
    const [showUnifiCfg,   setShowUnifiCfg]   = useState(false);

    const [extAlerts,      setExtAlerts]      = useState([]);
    const [expandedAlerts,   setExpandedAlerts]   = useState({});
    const [hideAcknowledged, setHideAcknowledged] = useState(true);

    const esRef = useRef(null), countRef = useRef(REFRESH_INTERVAL), agentsRef = useRef([]), devicesRef = useRef([]);
    agentsRef.current = agents; devicesRef.current = devices;

    const pushSnapshot = useCallback((devs, agts) => {
        setTimeSeriesData(prev => [...prev.slice(-(MAX_TS_POINTS - 1)), { time: new Date(), devDown: devs.filter(d => d.last_status === 'down').length, devWarn: 0, agentOffline: agts.filter(a => a.status === 'offline').length, agentWarn: agts.filter(a => warnings(a).some(w => w.type === 'warn')).length }]);
    }, []);

    const loadRecentChecks = useCallback(async (devs) => {
        if (!devs?.length) return;
        const results = [];
        await Promise.allSettled(devs.slice(0, 8).map(async d => {
            try { const data = await networkMonitorService.getChecks(d.id, 1); (data?.checks || []).slice(-3).forEach(c => results.push({ deviceName: d.name, status: c.status, checked_at: c.checked_at, rtt_ms: c.rtt_ms })); } catch {}
        }));
        results.sort((a, b) => new Date(b.checked_at) - new Date(a.checked_at));
        setRecentChecks(results.slice(0, 12));
    }, []);

    useEffect(() => {
        let pollTimer = null, sseConnected = false;
        const loadViaApi = () => networkMonitorService.getAll().then(d => { setDevices(d); setLoading(false); pushSnapshot(d, agentsRef.current); }).catch(() => setLoading(false));
        const startPolling = () => { if (pollTimer) return; loadViaApi(); pollTimer = setInterval(loadViaApi, 15000); };
        let es;
        try {
            es = networkMonitorService.createSSE(); esRef.current = es;
            const to = setTimeout(() => { if (!sseConnected) { es.close(); startPolling(); } }, 4000);
            es.addEventListener('initial_state', e => { sseConnected = true; clearTimeout(to); const d = JSON.parse(e.data); setDevices(d); setLoading(false); pushSnapshot(d, agentsRef.current); });
            es.addEventListener('device_update', e => { const u = JSON.parse(e.data); setDevices(prev => { const ex = prev.find(d => d.id === u.id); const n = ex ? prev.map(d => d.id === u.id ? u : d) : [...prev, u]; pushSnapshot(n, agentsRef.current); return n; }); setSelectedDevice(prev => prev?.id === u.id ? u : prev); });
            es.addEventListener('device_deleted', e => { const { id } = JSON.parse(e.data); setDevices(prev => prev.filter(d => d.id !== id)); });
            es.onerror = () => { clearTimeout(to); if (!sseConnected) { es.close(); startPolling(); } };
        } catch { startPolling(); }
        return () => { es?.close(); if (pollTimer) clearInterval(pollTimer); };
    }, [pushSnapshot]);

    const loadAgents = useCallback(async (silent = false) => {
        try { const d = await monitoringService.getAll(); setAgents(d); countRef.current = REFRESH_INTERVAL; setCountdown(REFRESH_INTERVAL); pushSnapshot(devicesRef.current, d); if (!silent) setLoading(false); }
        catch { if (!silent) { toast.error('Fehler beim Laden'); setLoading(false); } }
    }, [pushSnapshot]);

    useEffect(() => {
        loadAgents();
        const r = setInterval(() => loadAgents(true), REFRESH_INTERVAL * 1000);
        const t = setInterval(() => { countRef.current = Math.max(0, countRef.current - 1); setCountdown(countRef.current); }, 1000);
        return () => { clearInterval(r); clearInterval(t); };
    }, [loadAgents]);

    useEffect(() => { if (devices.length > 0) loadRecentChecks(devices); }, [devices, loadRecentChecks]);
    useEffect(() => { if (devices.length > 0) networkMonitorService.getUptimeStats().then(setUptimeStats).catch(() => {}); }, [devices.length]);

    const loadUnifi = useCallback(async () => {
        try {
            const [devs, cfg] = await Promise.all([unifiService.getDevices(), unifiService.getConfig()]);
            setUnifiDevices(devs);
            setUnifiConfig(cfg);
        } catch {}
    }, []);
    useEffect(() => { loadUnifi(); }, [loadUnifi]);

    const loadExtAlerts = useCallback(async () => {
        try { const d = await externalAlertService.getAll(); setExtAlerts(d); } catch {}
    }, []);
    useEffect(() => { loadExtAlerts(); const r = setInterval(loadExtAlerts, 60000); return () => clearInterval(r); }, [loadExtAlerts]);

    const loadProxmox = useCallback(async () => {
        try {
            const { default: api } = await import('../services/api');
            const r = await api.get('/proxmox/overview');
            setProxmoxData(r.data);
        } catch {}
    }, []);
    useEffect(() => { loadProxmox(); const r = setInterval(loadProxmox, 30000); return () => clearInterval(r); }, [loadProxmox]);

    const handleExtAcknowledge = async (id) => {
        try { await externalAlertService.acknowledge(id); loadExtAlerts(); toast.success('Quittiert'); } catch { toast.error('Fehler'); }
    };
    const handleExtCreateTicket = async (id) => {
        try { await externalAlertService.createTicket(id); loadExtAlerts(); toast.success('Ticket erstellt'); } catch { toast.error('Fehler beim Erstellen'); }
    };
    const handleExtRemove = async (id) => {
        if (!window.confirm('Alert wirklich löschen?')) return;
        try { await externalAlertService.remove(id); loadExtAlerts(); toast.success('Gelöscht'); } catch { toast.error('Fehler'); }
    };

    const handleAgentDelete = async (id, hostname) => {
        if (!window.confirm(`Agent "${hostname}" wirklich entfernen?`)) return;
        try { await monitoringService.delete(id); toast.success('Entfernt'); setSelectedAgent(null); loadAgents(true); } catch { toast.error('Fehler'); }
    };
    const handleNetDelete = async (d) => {
        if (!window.confirm(`${d.name} wirklich löschen?`)) return;
        try { await networkMonitorService.delete(d.id); setSelectedDevice(null); toast.success('Gelöscht'); } catch { toast.error('Fehler'); }
    };
    const handleNetSave = (d) => setDevices(prev => { const ex = prev.find(x => x.id === d.id); return ex ? prev.map(x => x.id === d.id ? d : x) : [...prev, d]; });
    const toggleAgent = id => setExpandedAgents(prev => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n; });
    const toggleGroup = g => setCollapsedGroups(prev => { const n = new Set(prev); n.has(g) ? n.delete(g) : n.add(g); return n; });

    // Derived
    const problems = [
        ...devices.filter(d => d.last_status !== 'up').map(d => ({ id: `dev-${d.id}`, severity: d.last_status === 'down' ? 0 : 2, statusColor: netColor(d.last_status), statusLabel: netLabel(d.last_status), name: d.name, service: TYPE_META[d.type]?.label || d.type, typeIcon: TYPE_META[d.type]?.icon || '🖥', lastCheck: d.last_checked, isDevice: true, raw: d })),
        ...agents.filter(a => a.status !== 'online' || warnings(a).length > 0).map(a => { const w = warnings(a); const hasErr = w.some(x => x.type === 'error'); const isOffline = a.status === 'offline'; return { id: `agt-${a.id}`, severity: isOffline ? 3 : hasErr ? 1 : 2, statusColor: isOffline ? SC.unknown : hasErr ? SC.crit : SC.warn, statusLabel: isOffline ? 'OFFLINE' : hasErr ? 'CRIT' : 'WARN', name: a.hostname, service: 'Windows Agent', typeIcon: '🖥', lastCheck: a.last_checkin, isDevice: false, raw: a }; }),
    ].sort((a, b) => a.severity - b.severity);

    const INACTIVE_DAYS = 7;
    const isLongInactive = (p) => {
        if (!p.lastCheck) return false;
        const days = (Date.now() - new Date(p.lastCheck).getTime()) / 86400000;
        return days >= INACTIVE_DAYS;
    };
    const openProblems   = problems.filter(p => !acknowledged.has(p.id));
    const activeProblems = openProblems.filter(p => !isLongInactive(p));
    const inactiveProblems = openProblems.filter(p => isLongInactive(p));
    const lastUpdated  = new Date().toLocaleTimeString('de-DE', { hour: '2-digit', minute: '2-digit', second: '2-digit' });

    if (loading) return <LoadingSpinner />;

    // ── Row background helper (Checkmk-style) ──
    const rowBg = (state) => state === 'crit' || state === 'down' ? `${SC.crit}0a` : state === 'warn' ? `${SC.warn}08` : 'transparent';
    const rowBorder = (state) => state === 'crit' || state === 'down' ? SC.crit : state === 'warn' ? SC.warn : 'transparent';

    // ── View toolbar helper ──
    const pill = (active, onClick, label) => (
        <button onClick={onClick} style={{ padding: '4px 12px', borderRadius: 20, border: `1px solid ${active ? 'var(--accent)' : 'var(--border-color)'}`, background: active ? 'var(--accent)' : 'none', color: active ? '#fff' : 'var(--text-muted)', fontSize: 12, cursor: 'pointer', fontWeight: active ? 600 : 400, transition: 'all .15s' }}>{label}</button>
    );

    const card = (ex = {}) => ({ background: 'var(--bg-secondary)', borderRadius: 10, border: '1px solid var(--border-color)', ...ex });

    // ─── Tab: Übersicht — Master-Detail Layout ────────────────────────────────
    const renderOverview = () => {
        const pxState = proxmoxData?.node ? (() => {
            const cpu = (proxmoxData.node.cpu || 0) * 100;
            const ram = proxmoxData.node.memory?.total > 0 ? (proxmoxData.node.memory.used / proxmoxData.node.memory.total) * 100 : 0;
            const load = proxmoxData.node.loadavg?.[0] || 0;
            const cpus = proxmoxData.node.cpuinfo?.cpus || 1;
            if (cpu >= 90 || ram >= 90 || load > cpus * 0.9) return 'crit';
            if (cpu >= 70 || ram >= 80 || load > cpus * 0.7) return 'warn';
            return 'ok';
        })() : 'unknown';

        const allHosts = [
            ...(proxmoxData ? [{ id: 'px-hve01', name: proxmoxData.node_name || 'hve-01', ip: '192.168.0.184', icon: '🖥️', sub: 'Proxmox VE Node', state: pxState, services: proxmoxServices(proxmoxData), last: proxmoxData.fetched_at }] : []),
            ...devices.map(d => ({ id: `net-${d.id}`, name: d.name, ip: d.host, icon: TYPE_META[d.type]?.icon || '🌐', sub: TYPE_META[d.type]?.label || 'Netzwerkgerät', state: d.last_status === 'up' ? 'ok' : d.last_status === 'down' ? 'crit' : 'unknown', services: netDeviceServices(d, uptimeStats[d.id]), last: d.last_checked, raw: d })),
            ...agents.map(a => { const w = warnings(a); const hasErr = w.some(x => x.type === 'error'); const state = a.status === 'offline' ? 'crit' : hasErr ? 'crit' : w.length ? 'warn' : 'ok'; return { id: `ag-${a.id}`, name: a.hostname, ip: a.ip_address, icon: '💻', sub: 'Windows Agent', state, services: agentServices(a), last: a.last_checkin, raw: a }; }),
        ].sort((a, b) => { const o = { crit: 0, warn: 1, unknown: 2, ok: 3 }; return (o[a.state] ?? 3) - (o[b.state] ?? 3) || a.name.localeCompare(b.name); });

        const filtered = allHosts.filter(h => (hostFilter === 'all' || h.state !== 'ok') && (!hostSearch || h.name.toLowerCase().includes(hostSearch.toLowerCase()) || (h.ip || '').includes(hostSearch)));
        const selId = ovSelectedId ?? filtered[0]?.id;
        const selHost = filtered.find(h => h.id === selId) || filtered[0];
        const C = { ok: SC.ok, warn: SC.warn, crit: SC.crit, unknown: SC.unknown };

        return (
        <>
            <div style={{ display: 'flex', gap: 8, marginBottom: 16, alignItems: 'center' }}>
                <div style={{ display: 'flex', padding: 3, borderRadius: 11, background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)', gap: 2 }}>
                    {[['all', `Alle · ${allHosts.length}`], ['problems', `Nur Probleme · ${allHosts.filter(h => h.state !== 'ok').length}`]].map(([v, l]) => (
                        <button key={v} onClick={() => setHostFilter(v)} style={{ padding: '6px 14px', borderRadius: 8, border: 'none', background: hostFilter === v ? '#0d9488' : 'none', color: hostFilter === v ? '#fff' : 'var(--text-muted)', fontSize: 12.5, fontWeight: hostFilter === v ? 650 : 500, cursor: 'pointer', transition: '.14s' }}>{l}</button>
                    ))}
                </div>
                <input value={hostSearch} onChange={e => setHostSearch(e.target.value)} placeholder="🔍 Host suchen..." style={{ marginLeft: 'auto', padding: '8px 12px', borderRadius: 10, border: '1px solid rgba(255,255,255,.08)', background: 'rgba(255,255,255,.04)', color: 'var(--text-primary)', fontSize: 13, width: 220 }} />
            </div>

            <div style={{ display: 'grid', gridTemplateColumns: 'minmax(0,1.15fr) minmax(0,1fr)', gap: 18, alignItems: 'start' }}>
                {/* HOST LIST */}
                <div style={{ background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)', borderRadius: 14, overflow: 'hidden', backdropFilter: 'blur(10px)' }}>
                    <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '14px 16px', borderBottom: '1px solid rgba(255,255,255,.08)' }}>
                        <span style={{ fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: .6, color: 'var(--text-muted)' }}>Hosts</span>
                        <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>{filtered.length} von {allHosts.length}</span>
                    </div>
                    <div style={{ maxHeight: 'calc(100vh - 420px)', overflowY: 'auto' }}>
                        {filtered.length === 0 && <div style={{ padding: 40, textAlign: 'center', color: SC.ok }}>✅ Alle Services in Ordnung</div>}
                        {filtered.map(h => {
                            const okC = h.services.filter(s => s.status === 'ok').length;
                            const wC  = h.services.filter(s => s.status === 'warn').length;
                            const cC  = h.services.filter(s => s.status === 'crit').length;
                            const sel = h.id === selId;
                            return (
                                <div key={h.id} onClick={() => setOvSelectedId(h.id)} style={{ display: 'grid', gridTemplateColumns: '34px 1fr auto', gap: 12, alignItems: 'center', padding: '13px 16px', borderBottom: '1px solid rgba(255,255,255,.06)', cursor: 'pointer', borderLeft: `3px solid ${sel ? '#14b8a6' : C[h.state]}`, background: sel ? 'linear-gradient(90deg,rgba(13,148,136,.14),transparent)' : 'transparent', transition: 'background .12s' }}>
                                    <div style={{ width: 34, height: 34, borderRadius: 10, display: 'grid', placeItems: 'center', background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.08)', color: C[h.state], fontSize: 16 }}>{h.icon}</div>
                                    <div>
                                        <div style={{ fontWeight: 650, fontSize: 13.5 }}>{h.name}</div>
                                        <div style={{ fontSize: 11, color: 'var(--text-muted)', fontFamily: 'monospace', marginTop: 1 }}>{h.ip} · {h.sub}</div>
                                    </div>
                                    <div style={{ display: 'flex', gap: 5 }}>
                                        {[okC, wC, cC].map((n, i) => { const col = [SC.ok, SC.warn, SC.crit][i]; return <span key={i} style={{ fontFamily: 'monospace', fontSize: 11, fontWeight: 700, padding: '2px 7px', borderRadius: 6, background: n > 0 ? `${col}22` : 'rgba(255,255,255,.04)', color: n > 0 ? col : 'var(--text-muted)', border: `1px solid ${n > 0 ? col + '44' : 'rgba(255,255,255,.06)'}`, minWidth: 24, textAlign: 'center' }}>{n}</span>; })}
                                    </div>
                                </div>
                            );
                        })}
                    </div>
                </div>

                {/* SERVICE DETAIL */}
                {selHost ? (
                    <div style={{ background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)', borderRadius: 14, overflow: 'hidden', backdropFilter: 'blur(10px)', position: 'sticky', top: 0 }}>
                        <div style={{ padding: 20, borderBottom: '1px solid rgba(255,255,255,.08)', background: 'linear-gradient(180deg,rgba(255,255,255,.06),transparent)' }}>
                            <div style={{ display: 'flex', alignItems: 'center', gap: 13 }}>
                                <div style={{ width: 46, height: 46, borderRadius: 13, display: 'grid', placeItems: 'center', background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.08)', color: C[selHost.state], fontSize: 22 }}>{selHost.icon}</div>
                                <div style={{ flex: 1 }}>
                                    <div style={{ fontSize: 18, fontWeight: 730, letterSpacing: -.3 }}>{selHost.name}</div>
                                    <div style={{ fontFamily: 'monospace', fontSize: 12, color: 'var(--text-muted)', marginTop: 2 }}>{selHost.ip}</div>
                                </div>
                                <span className={`mon-chip ${selHost.state} lg`}>{selHost.state.toUpperCase()}</span>
                            </div>
                            <div style={{ display: 'flex', gap: 8, marginTop: 14, flexWrap: 'wrap' }}>
                                <span style={{ fontSize: 11, color: 'var(--text-muted)', padding: '3px 9px', borderRadius: 7, background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.08)' }}>{selHost.sub}</span>
                                <span style={{ fontSize: 11, color: 'var(--text-muted)', padding: '3px 9px', borderRadius: 7, background: 'rgba(255,255,255,.06)', border: '1px solid rgba(255,255,255,.08)' }}>Check {timeAgo(selHost.last)}</span>
                            </div>
                        </div>
                        <div style={{ maxHeight: 'calc(100vh - 520px)', overflowY: 'auto' }}>
                            {selHost.services.map((svc, i) => {
                                const sc = C[svc.status] || SC.unknown;
                                const p = svc.perf ? Math.min(svc.perf.val / svc.perf.max * 100, 100) : 0;
                                const pSt = svc.perf ? (p >= svc.perf.crit ? 'crit' : p >= svc.perf.warn ? 'warn' : 'ok') : 'ok';
                                return (
                                    <div key={i} style={{ padding: '14px 20px', borderBottom: '1px solid rgba(255,255,255,.06)' }}>
                                        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 12, marginBottom: svc.perf ? 8 : 0 }}>
                                            <div>
                                                <div style={{ fontSize: 13, fontWeight: 600 }}>{svc.name}</div>
                                                {svc.detail && <div style={{ fontSize: 11, color: 'var(--text-muted)', fontFamily: 'monospace', marginTop: 1 }}>{svc.detail}</div>}
                                            </div>
                                            <span className={`mon-chip ${svc.status}`}>{(svc.status || 'ok').toUpperCase()}</span>
                                        </div>
                                        {svc.perf ? (
                                            <div className="mon-perf">
                                                <div className="mon-perf-track"><div className={`mon-perf-fill ${pSt}`} style={{ width: `${p}%` }} /></div>
                                                <span className="mon-perf-val" style={{ color: sc }}>{svc.perf.labelVal ?? `${p.toFixed(0)}%`}</span>
                                            </div>
                                        ) : (
                                            <div style={{ fontSize: 13, fontWeight: 600, color: sc, fontFamily: 'monospace' }}>{svc.value}</div>
                                        )}
                                    </div>
                                );
                            })}
                        </div>
                    </div>
                ) : (
                    <div style={{ background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)', borderRadius: 14, padding: 60, textAlign: 'center', color: 'var(--text-muted)' }}>Host aus der Liste wählen</div>
                )}
            </div>
        </>
        );
    };

    // ─── Tab: Netzwerk ────────────────────────────────────────────────────────
    const renderNetwork = () => {
        const filtered = devices.filter(d => {
            if (netSearch && !d.name.toLowerCase().includes(netSearch.toLowerCase()) && !d.host.includes(netSearch)) return false;
            if (netFilter === 'up' && d.last_status !== 'up') return false;
            if (netFilter === 'down' && d.last_status !== 'down') return false;
            if (netFilter === 'unknown' && d.last_status === 'up') return false;
            return true;
        });
        const grouped = {};
        filtered.forEach(d => { const g = d.type || 'host'; if (!grouped[g]) grouped[g] = []; grouped[g].push(d); });

        return (
            <>
                {/* Toolbar */}
                <div style={{ display: 'flex', gap: 10, marginBottom: 16, flexWrap: 'wrap', alignItems: 'center' }}>
                    <input value={netSearch} onChange={e => setNetSearch(e.target.value)} placeholder="Suchen..." style={{ padding: '7px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'var(--bg-secondary)', color: 'var(--text-primary)', fontSize: 13, width: 200 }} />
                    <div style={{ display: 'flex', gap: 5 }}>
                        {pill(netFilter === 'all', () => setNetFilter('all'), 'Alle')}
                        {pill(netFilter === 'up', () => setNetFilter('up'), 'UP')}
                        {pill(netFilter === 'down', () => setNetFilter('down'), 'DOWN')}
                        {pill(netFilter === 'unknown', () => setNetFilter('unknown'), 'UNBEKANNT')}
                    </div>
                    <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>{filtered.length} Einträge</span>
                    <div style={{ marginLeft: 'auto', display: 'flex', gap: 8 }}>
                        <button onClick={() => setShowDiscover(true)} style={{ padding: '7px 14px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'var(--bg-secondary)', color: 'var(--text-primary)', cursor: 'pointer', fontSize: 13, fontWeight: 600 }}>📡 Discovery</button>
                        <button onClick={() => { setEditDevice(null); setShowDeviceForm(true); }} style={{ padding: '7px 14px', borderRadius: 7, border: 'none', background: 'var(--accent)', color: '#fff', cursor: 'pointer', fontSize: 13, fontWeight: 600 }}>+ Gerät</button>
                        <button onClick={() => setShowDeploy(v => !v)} style={{ padding: '7px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: showDeploy ? 'var(--bg-secondary)' : 'none', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 13 }}>Agent {showDeploy ? '▴' : '▾'}</button>
                        <button onClick={() => setShowUnifiCfg(true)} title="Unifi Controller konfigurieren" style={{ padding: '7px 12px', borderRadius: 7, border: `1px solid ${unifiConfig?.enabled ? SC.ok + '66' : 'var(--border-color)'}`, background: 'none', color: unifiConfig?.enabled ? SC.ok : 'var(--text-muted)', cursor: 'pointer', fontSize: 13 }}>📶 Unifi</button>
                    </div>
                </div>

                {/* Deploy panel */}
                {showDeploy && (
                    <div style={card({ marginBottom: 16, padding: 16 })}>
                        <div style={{ fontSize: 12, fontWeight: 700, borderLeft: '3px solid var(--accent)', paddingLeft: 8, marginBottom: 12 }}>Agent bereitstellen</div>
                        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10, marginBottom: 10 }}>
                            {[{ href: '/downloads/IT-Nexus-Agent-Setup-v1.0.0.exe', icon: '⬇', title: 'Installer (.exe)', sub: 'Manuelle Installation' }, { href: '/downloads/IT-Nexus-Agent-Setup-v1.0.0.intunewin', icon: '📦', title: 'Intune (.intunewin)', sub: 'Microsoft Intune' }].map(({ href, icon, title, sub }) => (
                                <a key={href} href={href} download style={{ textDecoration: 'none', color: 'inherit' }}>
                                    <div style={{ background: 'var(--bg-primary)', border: '1px solid var(--border-color)', borderRadius: 8, padding: '12px 14px', display: 'flex', alignItems: 'center', gap: 12, transition: 'border-color .15s' }} onMouseEnter={e => e.currentTarget.style.borderColor = 'var(--accent)'} onMouseLeave={e => e.currentTarget.style.borderColor = 'var(--border-color)'}>
                                        <span style={{ fontSize: 22 }}>{icon}</span>
                                        <div><div style={{ fontWeight: 700, fontSize: 13 }}>{title}</div><div style={{ color: 'var(--text-muted)', fontSize: 11 }}>{sub}</div></div>
                                    </div>
                                </a>
                            ))}
                        </div>
                        <div style={{ background: 'var(--bg-primary)', borderRadius: 7, padding: '10px 12px', fontSize: 11 }}>
                            <div style={{ display: 'grid', gridTemplateColumns: '130px 1fr', gap: '4px 10px' }}>
                                {[['Install', 'IT-Nexus-Agent-Setup-v1.0.0.exe /VERYSILENT /NORESTART'], ['Uninstall', '{app}\\unins000.exe /VERYSILENT'], ['Detect', 'C:\\ProgramData\\IT Nexus Agent\\it-nexus-agent.ps1']].map(([k, v]) => (
                                    <React.Fragment key={k}><span style={{ color: 'var(--text-muted)' }}>{k}</span><code style={{ background: 'rgba(0,0,0,.3)', padding: '1px 7px', borderRadius: 3, fontFamily: 'monospace' }}>{v}</code></React.Fragment>
                                ))}
                            </div>
                        </div>
                    </div>
                )}

                {/* Grouped device tables – Checkmk-style */}
                {Object.keys(grouped).length === 0
                    ? <div style={{ textAlign: 'center', padding: 40, color: 'var(--text-muted)' }}>Keine Geräte gefunden</div>
                    : Object.entries(grouped).map(([type, devList]) => {
                        const meta = TYPE_META[type] || TYPE_META.host;
                        const collapsed = collapsedGroups.has(type);
                        const downCount = devList.filter(d => d.last_status === 'down').length;
                        return (
                            <div key={type} style={card({ marginBottom: 10, padding: 0, overflow: 'hidden' })}>
                                {/* Group header */}
                                <div onClick={() => toggleGroup(type)} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '10px 16px', cursor: 'pointer', borderBottom: collapsed ? 'none' : '1px solid var(--border-color)', background: 'var(--bg-primary)', userSelect: 'none' }}>
                                    <span style={{ fontSize: 15 }}>{meta.icon}</span>
                                    <span style={{ fontWeight: 700, fontSize: 13 }}>{meta.label}</span>
                                    <span style={{ fontSize: 11, color: 'var(--text-muted)', background: 'var(--bg-secondary)', padding: '1px 7px', borderRadius: 10, border: '1px solid var(--border-color)' }}>{devList.length}</span>
                                    {downCount > 0 && <StateSquare state="crit" text={`${downCount} DOWN`} />}
                                    <span style={{ marginLeft: 'auto', color: 'var(--text-muted)', fontSize: 12 }}>{collapsed ? '▸' : '▾'}</span>
                                </div>
                                {!collapsed && (
                                    <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                                        <thead>
                                            <tr style={{ borderBottom: '1px solid var(--border-color)', background: 'rgba(255,255,255,0.02)' }}>
                                                {['Status', 'Host', 'IP-Adresse', 'Standort', '24h Uptime', 'RTT', 'Letzter Check', 'Aktionen'].map(h => (
                                                    <th key={h} style={{ padding: '6px 12px', textAlign: 'left', fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: .4, whiteSpace: 'nowrap' }}>{h}</th>
                                                ))}
                                            </tr>
                                        </thead>
                                        <tbody>
                                            {devList.map(d => {
                                                const state = d.last_status === 'up' ? 'ok' : d.last_status === 'down' ? 'crit' : 'unknown';
                                                const ut = uptimeStats[d.id];
                                                return (
                                                    <tr key={d.id} onClick={() => setSelectedDevice(d)} style={{ borderBottom: '1px solid var(--border-color)', background: rowBg(state), borderLeft: `3px solid ${rowBorder(state)}`, cursor: 'pointer', transition: 'filter .1s' }}
                                                        onMouseEnter={e => e.currentTarget.style.filter = 'brightness(1.1)'}
                                                        onMouseLeave={e => e.currentTarget.style.filter = ''}>
                                                        <td style={{ padding: '8px 12px', whiteSpace: 'nowrap' }}><StateSquare state={state} text={netLabel(d.last_status)} /></td>
                                                        <td style={{ padding: '8px 12px', fontWeight: 600 }}>{d.name}</td>
                                                        <td style={{ padding: '8px 12px', fontFamily: 'monospace', color: 'var(--text-muted)', fontSize: 11 }}>{d.host}</td>
                                                        <td style={{ padding: '8px 12px', color: 'var(--text-muted)' }}>{d.location || '–'}</td>
                                                        <td style={{ padding: '8px 12px', minWidth: 100 }}>
                                                            {ut?.total > 0 ? <PerfBar val={ut.total - ut.up} max={ut.total} warn={10} crit={20} labelVal={`${ut.pct}%`} /> : <span style={{ color: 'var(--text-muted)' }}>–</span>}
                                                        </td>
                                                        <td style={{ padding: '8px 12px', fontFamily: 'monospace', color: 'var(--text-muted)', whiteSpace: 'nowrap' }}>{d.last_rtt_ms != null ? `${Math.round(d.last_rtt_ms)} ms` : '–'}</td>
                                                        <td style={{ padding: '8px 12px', color: 'var(--text-muted)', whiteSpace: 'nowrap' }}>{timeAgo(d.last_checked)}</td>
                                                        <td style={{ padding: '8px 12px' }} onClick={e => e.stopPropagation()}>
                                                            <div style={{ display: 'flex', gap: 5 }}>
                                                                <button onClick={() => networkMonitorService.checkNow(d.id).then(() => toast.success('OK')).catch(() => {})} style={{ padding: '2px 8px', borderRadius: 4, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 11 }}>▶</button>
                                                                <button onClick={() => { setEditDevice(d); setShowDeviceForm(true); }} style={{ padding: '2px 8px', borderRadius: 4, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 11 }}>✎</button>
                                                                <button onClick={() => handleNetDelete(d)} style={{ padding: '2px 8px', borderRadius: 4, border: `1px solid ${SC.crit}44`, background: 'none', color: SC.crit, cursor: 'pointer', fontSize: 11 }}>✕</button>
                                                            </div>
                                                        </td>
                                                    </tr>
                                                );
                                            })}
                                        </tbody>
                                    </table>
                                )}
                            </div>
                        );
                    })
                }

                {/* ── Unifi-Geräte ─────────────────────────────────────────── */}
                {unifiConfig?.enabled && unifiDevices.length > 0 && (() => {
                    const upStr = (s) => { if (!s) return '–'; const h = Math.floor(s / 3600); return h < 24 ? `${h}h` : `${Math.floor(h / 24)}d`; };
                    const groups = [
                        { key: 'uap', label: 'Unifi Access Points', icon: '📶', items: unifiDevices.filter(d => d.type === 'uap') },
                        { key: 'usw', label: 'Unifi Switches',      icon: '🔀', items: unifiDevices.filter(d => d.type === 'usw') },
                        { key: 'other', label: 'Unifi Sonstige',    icon: '🔌', items: unifiDevices.filter(d => d.type !== 'uap' && d.type !== 'usw') },
                    ].filter(g => g.items.length > 0);
                    return groups.map(({ key, label, icon, items }) => {
                        const collapsed = collapsedGroups.has('unifi_' + key);
                        const downCount = items.filter(d => d.state !== 1).length;
                        const hasClients = items.some(d => d.num_sta > 0);
                        return (
                            <div key={key} style={card({ marginBottom: 10, padding: 0, overflow: 'hidden' })}>
                                <div onClick={() => toggleGroup('unifi_' + key)} style={{ display: 'flex', alignItems: 'center', gap: 8, padding: '10px 16px', cursor: 'pointer', borderBottom: collapsed ? 'none' : '1px solid var(--border-color)', background: 'var(--bg-primary)', userSelect: 'none' }}>
                                    <span style={{ fontSize: 15 }}>{icon}</span>
                                    <span style={{ fontWeight: 700, fontSize: 13 }}>{label}</span>
                                    <span style={{ fontSize: 11, color: 'var(--text-muted)', background: 'var(--bg-secondary)', padding: '1px 7px', borderRadius: 10, border: '1px solid var(--border-color)' }}>{items.length}</span>
                                    {downCount > 0 && <StateSquare state="crit" text={`${downCount} OFFLINE`} />}
                                    <span style={{ marginLeft: 'auto', fontSize: 10, color: 'var(--text-muted)', fontStyle: 'italic' }}>via Unifi Controller</span>
                                    <span style={{ color: 'var(--text-muted)', fontSize: 12, marginLeft: 6 }}>{collapsed ? '▸' : '▾'}</span>
                                </div>
                                {!collapsed && (
                                    <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12 }}>
                                        <thead>
                                            <tr style={{ borderBottom: '1px solid var(--border-color)', background: 'rgba(255,255,255,0.02)' }}>
                                                {['Status','Name','IP','Modell','Uptime', hasClients && 'Clients','CPU','RAM'].filter(Boolean).map(h => (
                                                    <th key={h} style={{ padding: '6px 12px', textAlign: 'left', fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: .4, whiteSpace: 'nowrap' }}>{h}</th>
                                                ))}
                                            </tr>
                                        </thead>
                                        <tbody>
                                            {items.map(d => (
                                                <tr key={d.unifi_id} style={{ borderBottom: '1px solid var(--border-color)', background: d.state === 1 ? 'transparent' : `${SC.crit}0a`, borderLeft: `3px solid ${d.state === 1 ? 'transparent' : SC.crit}` }}>
                                                    <td style={{ padding: '8px 12px' }}><StateSquare state={d.state === 1 ? 'ok' : 'crit'} text={d.state === 1 ? 'ONLINE' : 'OFFLINE'} /></td>
                                                    <td style={{ padding: '8px 12px', fontWeight: 600 }}>{d.name || d.mac}</td>
                                                    <td style={{ padding: '8px 12px', fontFamily: 'monospace', color: 'var(--text-muted)', fontSize: 11 }}>{d.ip || '–'}</td>
                                                    <td style={{ padding: '8px 12px', color: 'var(--text-muted)' }}>{d.model || '–'}</td>
                                                    <td style={{ padding: '8px 12px', fontFamily: 'monospace', fontSize: 11 }}>{upStr(d.uptime)}</td>
                                                    {hasClients && <td style={{ padding: '8px 12px', textAlign: 'center' }}>
                                                        {d.num_sta > 0 ? <span style={{ background: `${SC.ok}22`, color: SC.ok, border: `1px solid ${SC.ok}44`, borderRadius: 10, padding: '1px 8px', fontSize: 11, fontWeight: 700, fontFamily: 'monospace' }}>{d.num_sta}</span> : <span style={{ color: 'var(--text-muted)' }}>–</span>}
                                                    </td>}
                                                    <td style={{ padding: '8px 12px', minWidth: 120 }}>{d.cpu_pct != null ? <PerfBar val={d.cpu_pct} max={100} warn={70} crit={90} unit="%" /> : <span style={{ color: 'var(--text-muted)' }}>–</span>}</td>
                                                    <td style={{ padding: '8px 12px', minWidth: 120 }}>{d.ram_pct != null ? <PerfBar val={d.ram_pct} max={100} warn={75} crit={90} unit="%" /> : <span style={{ color: 'var(--text-muted)' }}>–</span>}</td>
                                                </tr>
                                            ))}
                                        </tbody>
                                    </table>
                                )}
                            </div>
                        );
                    });
                })()}
            </>
        );
    };

    // ─── Tab: Agents ──────────────────────────────────────────────────────────
    const renderAgents = () => {
        const isAgentOffline = (a) => {
            if (!a.last_checkin) return true;
            return Date.now() - new Date(a.last_checkin).getTime() > 5 * 60 * 1000;
        };

        const filtered = agents.filter(a => {
            if (agentSearch && !a.hostname.toLowerCase().includes(agentSearch.toLowerCase()) && !(a.ip_address || '').includes(agentSearch)) return false;
            if (agentFilter === 'online' && a.status !== 'online') return false;
            if (agentFilter === 'offline' && a.status !== 'offline') return false;
            if (agentFilter === 'warn' && warnings(a).length === 0) return false;
            return true;
        });

        const sorted = [...filtered].sort((a, b) => {
            const aOffline = isAgentOffline(a);
            const bOffline = isAgentOffline(b);
            // Offline immer ans Ende
            if (aOffline !== bOffline) return aOffline ? 1 : -1;
            if (agentSort === 'cpu') {
                const av = a.cpu_usage_percent ?? (a.ram_total_gb > 0 ? (a.ram_used_gb / a.ram_total_gb) * 100 : 0);
                const bv = b.cpu_usage_percent ?? (b.ram_total_gb > 0 ? (b.ram_used_gb / b.ram_total_gb) * 100 : 0);
                return bv - av;
            }
            if (agentSort === 'ram') {
                const av = a.ram_total_gb > 0 ? (a.ram_used_gb / a.ram_total_gb) * 100 : 0;
                const bv = b.ram_total_gb > 0 ? (b.ram_used_gb / b.ram_total_gb) * 100 : 0;
                return bv - av;
            }
            if (agentSort === 'name') return (a.hostname || '').localeCompare(b.hostname || '');
            if (agentSort === 'seen') return new Date(b.last_checkin || 0) - new Date(a.last_checkin || 0);
            return 0;
        });

        const MonPerf = ({ val, max, warn = 80, crit = 90, labelVal = null }) => {
            if (val == null || !max) return <span style={{ color: 'var(--text-muted)', fontSize: 11 }}>—</span>;
            const p = Math.min((val / max) * 100, 100);
            const st = p >= crit ? 'crit' : p >= warn ? 'warn' : 'ok';
            const display = labelVal ?? `${p.toFixed(0)}%`;
            return (
                <div className="mon-perf">
                    <div className="mon-perf-track">
                        <div className={`mon-perf-fill ${st}`} style={{ width: `${p}%` }} />
                    </div>
                    <span className="mon-perf-val" style={{ color: SC[st] }}>{display}</span>
                </div>
            );
        };

        return (
            <>
                <div style={{ display: 'flex', gap: 10, marginBottom: 16, flexWrap: 'wrap', alignItems: 'center' }}>
                    <input value={agentSearch} onChange={e => setAgentSearch(e.target.value)} placeholder="Hostname / IP suchen…" style={{ padding: '8px 12px', borderRadius: 10, border: '1px solid rgba(255,255,255,.08)', background: 'rgba(255,255,255,.04)', color: 'var(--text-primary)', fontSize: 13, width: 230 }} />
                    <div style={{ display: 'flex', padding: 3, borderRadius: 11, background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)', gap: 2 }}>
                        {[['all','Alle'],['online','Online'],['offline','Offline'],['warn','Warnung']].map(([v,l]) => (
                            <button key={v} onClick={() => setAgentFilter(v)} style={{ padding: '6px 14px', borderRadius: 8, border: 'none', background: agentFilter === v ? '#0d9488' : 'none', color: agentFilter === v ? '#fff' : 'var(--text-muted)', fontSize: 12.5, fontWeight: agentFilter === v ? 650 : 500, cursor: 'pointer', boxShadow: agentFilter === v ? '0 4px 12px -4px rgba(13,148,136,.45)' : 'none', transition: '.14s' }}>{l}</button>
                        ))}
                    </div>
                    <select value={agentSort} onChange={e => setAgentSort(e.target.value)} style={{ padding: '8px 12px', borderRadius: 10, border: '1px solid rgba(255,255,255,.08)', background: 'rgba(255,255,255,.04)', color: 'var(--text-primary)', fontSize: 12.5, outline: 'none' }}>
                        <option value="cpu">Sortierung: CPU-Auslastung</option>
                        <option value="ram">Sortierung: RAM-Auslastung</option>
                        <option value="name">Sortierung: Name</option>
                        <option value="seen">Sortierung: Zuletzt gesehen</option>
                    </select>
                    <span style={{ fontSize: 12, color: 'var(--text-muted)', marginLeft: 'auto' }}>{sorted.length} Einträge</span>
                </div>

                {sorted.length === 0
                    ? <div style={{ textAlign: 'center', padding: 40, color: 'var(--text-muted)' }}>Keine Agents gefunden</div>
                    : (
                        <div style={{ background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)', borderRadius: 14, overflow: 'hidden', backdropFilter: 'blur(10px)' }}>
                            <div className="mon-table-wrap">
                                <table className="mon-table">
                                    <thead>
                                        <tr>
                                            <th></th>
                                            <th>Host</th>
                                            <th>Status</th>
                                            <th style={{ minWidth: 150 }}>CPU</th>
                                            <th style={{ minWidth: 150 }}>RAM</th>
                                            <th style={{ minWidth: 150 }}>Disk</th>
                                            <th>Uptime</th>
                                            <th>Letzter Checkin</th>
                                            <th></th>
                                        </tr>
                                    </thead>
                                    <tbody>
                                        {sorted.map(a => {
                                            const w = warnings(a), hasErr = w.some(x => x.type === 'error');
                                            const state = a.status === 'offline' ? 'crit' : hasErr ? 'crit' : w.length ? 'warn' : 'ok';
                                            const isExp = expandedAgents.has(a.id);
                                            const services = agentServices(a);
                                            return (
                                                <React.Fragment key={a.id}>
                                                    <tr className={`lrow-${state}`} style={{ cursor: 'pointer' }} onClick={() => toggleAgent(a.id)}>
                                                        <td style={{ width: 28, textAlign: 'center', color: 'var(--text-muted)', fontSize: 11 }}>{isExp ? '▼' : '▶'}</td>
                                                        <td style={{ fontWeight: 700, fontFamily: 'monospace' }}>
                                                            <Link to={`/monitoring/device/${a.id}`} onClick={e => e.stopPropagation()} style={{ color: 'inherit', textDecoration: 'none', borderBottom: '1px dotted rgba(255,255,255,.3)' }}>{a.hostname}</Link>
                                                        </td>
                                                        <td><span className={`mon-chip ${state}`}>{state.toUpperCase()}</span></td>
                                                        <td><MonPerf val={a.cpu_usage_percent} max={100} warn={80} crit={90} /></td>
                                                        <td><MonPerf val={a.ram_used_gb} max={a.ram_total_gb} warn={85} crit={95} labelVal={a.ram_total_gb > 0 ? `${a.ram_used_gb?.toFixed(1)} / ${a.ram_total_gb?.toFixed(0)} GB` : null} /></td>
                                                        <td><MonPerf val={a.disk_total_gb - a.disk_free_gb} max={a.disk_total_gb} warn={75} crit={90} labelVal={a.disk_total_gb > 0 ? `${a.disk_free_gb?.toFixed(0)} GB frei` : null} /></td>
                                                        <td style={{ fontFamily: 'monospace', fontSize: 12, color: 'var(--text-muted)' }}>{uptimeStr(a.uptime_hours)}</td>
                                                        <td style={{ fontSize: 12, color: 'var(--text-muted)', whiteSpace: 'nowrap' }}>{timeAgo(a.last_checkin)}</td>
                                                        <td onClick={e => e.stopPropagation()}>
                                                            <button onClick={() => setSelectedAgent(a)} style={{ padding: '5px 10px', borderRadius: 8, border: '1px solid rgba(255,255,255,.08)', background: 'rgba(255,255,255,.04)', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 11.5, fontWeight: 550 }}>Details</button>
                                                        </td>
                                                    </tr>
                                                    {isExp && (
                                                        <tr style={{ borderBottom: '1px solid rgba(255,255,255,.06)' }}>
                                                            <td />
                                                            <td colSpan={8} style={{ padding: '0 0 0 16px', background: 'rgba(255,255,255,.02)' }}>
                                                                <table style={{ width: '100%', borderCollapse: 'collapse', fontSize: 12, marginBottom: 4 }}>
                                                                    <thead>
                                                                        <tr style={{ borderBottom: '1px solid rgba(255,255,255,.06)' }}>
                                                                            {['Status', 'Service', 'Perf-O-Meter', 'Wert', 'Details'].map(h => (
                                                                                <th key={h} style={{ padding: '5px 10px', textAlign: 'left', fontSize: 10, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: .4 }}>{h}</th>
                                                                            ))}
                                                                        </tr>
                                                                    </thead>
                                                                    <tbody>
                                                                        {services.map((svc, si) => (
                                                                            <tr key={si} style={{ borderBottom: '1px solid rgba(255,255,255,.04)' }}>
                                                                                <td style={{ padding: '6px 10px', borderLeft: `3px solid ${SC[svc.status]}` }}>
                                                                                    <span className={`mon-chip ${svc.status}`}>{svc.status.toUpperCase()}</span>
                                                                                </td>
                                                                                <td style={{ padding: '6px 10px', fontWeight: 600 }}>{svc.name}</td>
                                                                                <td style={{ padding: '6px 10px', minWidth: 160 }}>
                                                                                    {svc.perf ? <MonPerf val={svc.perf.val} max={svc.perf.max} warn={svc.perf.warn} crit={svc.perf.crit} labelVal={svc.perf.labelVal} /> : <span style={{ color: 'var(--text-muted)' }}>—</span>}
                                                                                </td>
                                                                                <td style={{ padding: '6px 10px', fontFamily: 'monospace', fontSize: 11, color: SC[svc.status], fontWeight: 700 }}>{svc.value}</td>
                                                                                <td style={{ padding: '6px 10px', color: 'var(--text-muted)', fontSize: 11 }}>{svc.detail}</td>
                                                                            </tr>
                                                                        ))}
                                                                    </tbody>
                                                                </table>
                                                                <div style={{ display: 'flex', gap: 8, padding: '8px 0 10px' }}>
                                                                    <button onClick={() => setSelectedAgent(a)} style={{ padding: '4px 12px', borderRadius: 8, border: '1px solid rgba(255,255,255,.08)', background: 'none', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 11 }}>Software &amp; Details</button>
                                                                    <button onClick={() => handleAgentDelete(a.id, a.hostname)} style={{ padding: '4px 12px', borderRadius: 8, border: `1px solid ${SC.crit}44`, background: 'none', color: SC.crit, cursor: 'pointer', fontSize: 11 }}>Entfernen</button>
                                                                </div>
                                                            </td>
                                                        </tr>
                                                    )}
                                                </React.Fragment>
                                            );
                                        })}
                                    </tbody>
                                </table>
                            </div>
                        </div>
                    )
                }
            </>
        );
    };

    // ─── Tab: Probleme ────────────────────────────────────────────────────────
    const renderProblems = () => {
        const visible = showAcked ? problems : activeProblems;

        const SevGroup = ({ severity, label, color, rows }) => {
            const items = rows.filter(p => (severity === 'crit' ? p.severity <= 1 : p.severity === 2));
            if (!items.length) return null;
            return (
                <div className="mon-sev">
                    <div className="mon-sev-head">
                        <span className="mon-sev-dot" style={{ background: color, boxShadow: `0 0 10px ${color}` }} />
                        <span className="mon-sev-name" style={{ color }}>{label}</span>
                        <span className="mon-sev-cnt" style={{ color, background: `${color}22`, border: `1px solid ${color}55` }}>{items.length}</span>
                        <span className="mon-sev-line" />
                    </div>
                    <div style={{ background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)', borderRadius: 14, overflow: 'hidden' }}>
                        {items.map(p => {
                            const isAck = acknowledged.has(p.id);
                            return (
                                <div key={p.id} className="mon-prob" style={{ opacity: isAck ? 0.5 : 1 }}>
                                    <div><span className={`mon-chip ${p.severity <= 1 ? 'crit' : 'warn'} lg`}>{p.statusLabel}</span></div>
                                    <div className="mon-prob-host">
                                        <div className="mon-prob-icn" style={{ color }}>{p.typeIcon}</div>
                                        <div style={{ minWidth: 0 }}>
                                            <div className="mon-prob-name">{p.name}</div>
                                            <div className="mon-prob-svc">{p.service}{p.raw?.host ? ` · ${p.raw.host}` : ''}</div>
                                        </div>
                                    </div>
                                    <div className="mon-prob-since">
                                        <div className="mon-prob-since-lbl">seit</div>
                                        {duration(p.lastCheck)}
                                    </div>
                                    {!isAck
                                        ? <button onClick={() => setAcknowledged(prev => new Set([...prev, p.id]))} style={{ padding: '5px 13px', borderRadius: 8, border: '1px solid rgba(255,255,255,.08)', background: 'rgba(255,255,255,.04)', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 12, fontWeight: 600, whiteSpace: 'nowrap' }}>✓ Bestätigen</button>
                                        : <button onClick={() => p.isDevice ? setSelectedDevice(p.raw) : setSelectedAgent(p.raw)} style={{ padding: '5px 13px', borderRadius: 8, border: '1px solid rgba(255,255,255,.08)', background: 'rgba(255,255,255,.04)', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 12 }}>Details</button>
                                    }
                                </div>
                            );
                        })}
                    </div>
                </div>
            );
        };

        return (
            <>
                <div style={{ display: 'flex', alignItems: 'center', gap: 16, marginBottom: 18 }}>
                    <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, cursor: 'pointer', color: 'var(--text-muted)' }}>
                        <input type="checkbox" checked={showAcked} onChange={e => setShowAcked(e.target.checked)} style={{ accentColor: '#0d9488', width: 15, height: 15 }} />
                        Bestätigte anzeigen
                    </label>
                    <span style={{ fontSize: 12, color: 'var(--text-muted)' }}>{activeProblems.length} aktiv · {inactiveProblems.length} langfristig offline · {acknowledged.size} bestätigt</span>
                </div>

                {visible.length === 0 && inactiveProblems.length === 0 ? (
                    <div style={{ textAlign: 'center', padding: '60px 20px', background: 'rgba(52,211,153,.06)', borderRadius: 14, border: `1px solid ${SC.ok}30` }}>
                        <div style={{ fontSize: 40, marginBottom: 10 }}>✓</div>
                        <div style={{ fontSize: 16, fontWeight: 700, color: SC.ok }}>Keine offenen Probleme</div>
                        <div style={{ fontSize: 13, color: 'var(--text-muted)', marginTop: 6 }}>Alle {devices.length + agents.length} Hosts sind in Ordnung</div>
                    </div>
                ) : (
                    <>
                        <SevGroup severity="crit" label="Kritisch" color={SC.crit} rows={visible} />
                        <SevGroup severity="warn" label="Warnung"  color={SC.warn} rows={visible} />
                        {inactiveProblems.length > 0 && (
                            <div className="mon-sev">
                                <div className="mon-sev-head">
                                    <span className="mon-sev-dot" style={{ background: SC.unknown }} />
                                    <span className="mon-sev-name" style={{ color: SC.unknown }}>Langfristig offline</span>
                                    <span className="mon-sev-cnt" style={{ color: SC.unknown, background: `${SC.unknown}22` }}>{inactiveProblems.length}</span>
                                    <span className="mon-sev-line" />
                                </div>
                                <div style={{ opacity: 0.6, background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)', borderRadius: 14, overflow: 'hidden' }}>
                                    {inactiveProblems.map(p => (
                                        <div key={p.id} className="mon-prob">
                                            <div><span className="mon-chip unk lg">OFFLINE</span></div>
                                            <div className="mon-prob-host">
                                                <div className="mon-prob-icn">{p.typeIcon}</div>
                                                <div><div className="mon-prob-name">{p.name}</div><div className="mon-prob-svc">{p.service}</div></div>
                                            </div>
                                            <div className="mon-prob-since"><div className="mon-prob-since-lbl">seit</div>{duration(p.lastCheck)}</div>
                                            <button onClick={() => p.isDevice ? setSelectedDevice(p.raw) : setSelectedAgent(p.raw)} style={{ padding: '5px 13px', borderRadius: 8, border: '1px solid rgba(255,255,255,.08)', background: 'none', color: 'var(--text-muted)', cursor: 'pointer', fontSize: 12 }}>Details</button>
                                        </div>
                                    ))}
                                </div>
                            </div>
                        )}
                    </>
                )}
            </>
        );
    };

    const extUnacked   = extAlerts.filter(a => !a.acknowledged).length;
    const netgoAlerts  = extAlerts.filter(a => a.source === 'netgo');
    const netgoUnacked = netgoAlerts.filter(a => !a.acknowledged).length;
    const awAlerts     = extAlerts.filter(a => a.source === 'arcticwolf');
    const awUnacked    = awAlerts.filter(a => !a.acknowledged).length;
    const mdoAlerts    = extAlerts.filter(a => a.source === 'mdo');
    const mdoUnacked   = mdoAlerts.filter(a => !a.acknowledged).length;

    const toggleAlertExpand = (id) => setExpandedAlerts(p => ({ ...p, [id]: !p[id] }));

    const renderExtAlerts = () => {
        const sevColor = (s) => s === 'CRIT' ? SC.crit : s === 'WARN' ? SC.warn : s === 'OK' ? SC.ok : SC.unknown;

        const renderAlertCard = (alert) => {
            const color = sevColor(alert.severity);
            const isAW  = alert.source === 'arcticwolf';
            const expanded = expandedAlerts[alert.id];

            let aw = null;
            if (isAW && alert.raw_body) {
                try { aw = JSON.parse(alert.raw_body); } catch { /* ignore */ }
            }

            const actions = (
                <div style={{ display: 'flex', flexDirection: 'column', gap: 6, flexShrink: 0 }}>
                    {!alert.ticket_id && (
                        <button onClick={() => handleExtCreateTicket(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: `1px solid var(--accent)`, background: 'var(--accent)', color: '#fff', fontSize: 12, cursor: 'pointer', fontWeight: 600, whiteSpace: 'nowrap' }}>🎫 Ticket</button>
                    )}
                    {!alert.acknowledged && (
                        <button onClick={() => handleExtAcknowledge(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer', whiteSpace: 'nowrap' }}>✓ Quittieren</button>
                    )}
                    <button onClick={() => handleExtRemove(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>🗑</button>
                </div>
            );

            // ── Arctic Wolf Detailkarte ──────────────────────────────────────
            if (isAW) {
                const labelStyle = { fontSize: 11, color: 'var(--text-muted)', minWidth: 130, flexShrink: 0 };
                const valStyle   = { fontSize: 12, color: 'var(--text-primary)', wordBreak: 'break-word' };
                const row = (label, val) => val ? (
                    <div style={{ display: 'flex', gap: 8, padding: '4px 0', borderBottom: '1px solid var(--border-color)' }}>
                        <span style={labelStyle}>{label}</span>
                        <span style={valStyle}>{val}</span>
                    </div>
                ) : null;
                const section = (title, text) => text ? (
                    <div style={{ marginTop: 10 }}>
                        <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 1, marginBottom: 4 }}>{title}</div>
                        <div style={{ fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.6 }}>{text}</div>
                    </div>
                ) : null;

                return (
                    <div key={alert.id} style={{ background: 'var(--bg-secondary)', border: `1px solid ${alert.acknowledged ? 'var(--border-color)' : color + '44'}`, borderLeft: `4px solid ${color}`, borderRadius: 10, padding: '14px 16px', opacity: alert.acknowledged ? 0.65 : 1 }}>
                        {/* Header */}
                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
                            <div style={{ flex: 1 }}>
                                <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', marginBottom: 8 }}>
                                    <span style={{ fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 6, background: color + '22', color, border: `1px solid ${color}44`, letterSpacing: 1 }}>
                                        {aw?.severity_label || alert.severity}
                                    </span>
                                    <span style={{ fontSize: 11, fontWeight: 600, color: 'var(--text-muted)', background: 'var(--bg-tertiary)', padding: '2px 8px', borderRadius: 6 }}>ARCTIC WOLF</span>
                                    {alert.acknowledged && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 6, background: 'var(--bg-tertiary)', color: 'var(--text-muted)', border: '1px solid var(--border-color)' }}>✓ Quittiert</span>}
                                    {alert.ticket_id    && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 6, background: SC.ok + '22', color: SC.ok, border: `1px solid ${SC.ok}44` }}>🎫 Ticket #{alert.ticket_id}</span>}
                                </div>
                                <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 4 }}>{alert.message || aw?.incident_name}</div>
                                <div style={{ fontSize: 12, color: 'var(--text-muted)' }}>
                                    🖥 {alert.device}{aw?.ip ? ` · ${aw.ip}` : ''}
                                    {alert.state_time && <span style={{ marginLeft: 12 }}>🕐 {alert.state_time}</span>}
                                    <span style={{ marginLeft: 12 }}>Eingang: {timeAgo(alert.created_at)}</span>
                                </div>
                            </div>
                            {actions}
                        </div>

                        {/* Schnell-Info-Grid */}
                        {aw && (
                            <div style={{ marginTop: 12, padding: '10px 12px', background: 'var(--bg-primary)', borderRadius: 8 }}>
                                {row('Event-Typ',  aw.event_type)}
                                {row('Application', aw.application)}
                                {row('User',        aw.user)}
                                {row('Process',     aw.process)}
                            </div>
                        )}

                        {/* Aufklapp-Button */}
                        {aw && (aw.what_is_it || aw.why_matters || aw.next_steps || aw.recommend) && (
                            <button onClick={() => toggleAlertExpand(alert.id)} style={{ marginTop: 10, padding: '4px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>
                                {expanded ? '▲ Weniger' : '▼ Mehr Details'}
                            </button>
                        )}

                        {/* Erweiterte Sektionen */}
                        {expanded && aw && (
                            <div style={{ marginTop: 12, padding: '12px', background: 'var(--bg-primary)', borderRadius: 8, display: 'flex', flexDirection: 'column', gap: 2 }}>
                                {section('Was ist passiert?',          aw.what_is_it)}
                                {section('Warum ist das relevant?',    aw.why_matters)}
                                {section('Wie wurde es erkannt?',      aw.how_detected)}
                                {section('Nächste Schritte',           aw.next_steps)}
                                {section('Empfehlungen Arctic Wolf',   aw.recommend)}
                            </div>
                        )}
                    </div>
                );
            }

            // ── Standard-Karte (Netgo & andere) ────────────────────────────
            return (
                <div key={alert.id} style={{ background: 'var(--bg-secondary)', border: `1px solid ${alert.acknowledged ? 'var(--border-color)' : color + '44'}`, borderLeft: `4px solid ${color}`, borderRadius: 10, padding: '12px 16px', opacity: alert.acknowledged ? 0.6 : 1 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
                        <div style={{ flex: 1 }}>
                            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 6 }}>
                                <span style={{ fontSize: 10, fontWeight: 700, padding: '2px 7px', borderRadius: 6, background: color + '22', color, border: `1px solid ${color}44`, letterSpacing: 1 }}>{alert.severity || 'UNKNOWN'}</span>
                                {alert.acknowledged && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 6, background: 'var(--bg-tertiary)', color: 'var(--text-muted)', border: '1px solid var(--border-color)' }}>✓ Quittiert</span>}
                                {alert.ticket_id   && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 6, background: SC.ok + '22', color: SC.ok, border: `1px solid ${SC.ok}44` }}>🎫 Ticket #{alert.ticket_id}</span>}
                                <span style={{ fontSize: 11, color: 'var(--text-muted)', marginLeft: 4 }}>{alert.source?.toUpperCase()}</span>
                            </div>
                            {alert.device && <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 2 }}>🖥 {alert.device}{alert.service ? ` · ${alert.service}` : ''}</div>}
                            {alert.state_transition && <div style={{ fontSize: 12, color: 'var(--text-muted)', marginBottom: 2 }}>Status: {alert.state_transition}</div>}
                            {alert.message && <div style={{ fontSize: 12, color: 'var(--text-secondary)', marginTop: 4, wordBreak: 'break-word' }}>{alert.message}</div>}
                            <div style={{ display: 'flex', gap: 14, marginTop: 6, fontSize: 11, color: 'var(--text-muted)' }}>
                                {alert.customer  && <span>Kunde: {alert.customer}</span>}
                                {alert.state_time && <span>🕐 {alert.state_time}</span>}
                                <span>Eingang: {timeAgo(alert.created_at)}</span>
                            </div>
                        </div>
                        {actions}
                    </div>
                </div>
            );
        };

        const otherAlerts = extAlerts.filter(a => a.source !== 'netgo' && a.source !== 'arcticwolf' && a.source !== 'mdo');
        const otherUnacked = otherAlerts.filter(a => !a.acknowledged).length;
        const hiddenCount = otherAlerts.filter(a => a.acknowledged).length;
        const visibleAlerts = hideAcknowledged ? otherAlerts.filter(a => !a.acknowledged) : otherAlerts;

        return (
            <div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                        <span style={{ fontSize: 13, color: 'var(--text-muted)' }}>{otherAlerts.length} Alert{otherAlerts.length !== 1 ? 's' : ''} · {otherUnacked} nicht quittiert</span>
                        {hiddenCount > 0 && (
                            <button onClick={() => setHideAcknowledged(h => !h)} style={{ padding: '3px 10px', borderRadius: 7, border: '1px solid var(--border-color)', background: hideAcknowledged ? 'var(--accent)' : 'none', color: hideAcknowledged ? '#fff' : 'var(--text-muted)', fontSize: 11, cursor: 'pointer' }}>
                                {hideAcknowledged ? `✓ Quittierte ausgeblendet (${hiddenCount})` : `Quittierte ausblenden (${hiddenCount})`}
                            </button>
                        )}
                    </div>
                    <button onClick={loadExtAlerts} style={{ padding: '5px 14px', borderRadius: 8, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>↻ Aktualisieren</button>
                </div>
                {visibleAlerts.length === 0 && (
                    <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-muted)', fontSize: 14 }}>✅ Keine sonstigen Alerts vorhanden</div>
                )}
                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                    {visibleAlerts.map(renderAlertCard)}
                </div>
            </div>
        );
    };

    const renderNetGoAlerts = () => {
        const sevColor = (s) => s === 'CRIT' ? SC.crit : s === 'WARN' ? SC.warn : s === 'OK' ? SC.ok : SC.unknown;

        const parseAi = (alert) => {
            if (!alert.ai_analysis) return null;
            try { return typeof alert.ai_analysis === 'string' ? JSON.parse(alert.ai_analysis) : alert.ai_analysis; } catch { return null; }
        };

        const parseTransition = (st) => {
            if (!st) return { from: '', to: '' };
            const m = st.match(/^(.+?)\s+(?:to|→)\s+(.+)$/i);
            return m ? { from: m[1].trim(), to: m[2].trim() } : { from: '', to: st };
        };

        const hiddenCount = netgoAlerts.filter(a => a.acknowledged).length;
        const visible = hideAcknowledged ? netgoAlerts.filter(a => !a.acknowledged) : netgoAlerts;

        // Kanban-Spalten
        const columns = [
            { key: 'CRIT',    label: 'Kritisch',          icon: '🔴', color: SC.crit,    alerts: visible.filter(a => (parseAi(a)?.severity || a.severity) === 'CRIT') },
            { key: 'WARN',    label: 'Warnung',            icon: '🟡', color: SC.warn,    alerts: visible.filter(a => (parseAi(a)?.severity || a.severity) === 'WARN') },
            { key: 'OK',      label: 'Wiederhergestellt',  icon: '🟢', color: SC.ok,      alerts: visible.filter(a => (parseAi(a)?.severity || a.severity) === 'OK') },
            { key: 'UNKNOWN', label: 'Unbekannt',          icon: '⚪', color: SC.unknown, alerts: visible.filter(a => !['CRIT','WARN','OK'].includes(parseAi(a)?.severity || a.severity)) },
        ].filter(col => col.alerts.length > 0);

        const KanbanCard = ({ alert }) => {
            const ai   = parseAi(alert);
            const sev  = ai?.severity || alert.severity;
            const col  = sevColor(sev);
            const trans = parseTransition(alert.state_transition);
            const stateFrom = ai?.state_from || trans.from;
            const stateTo   = ai?.state_to   || trans.to;
            const device    = ai?.device  || (alert.device?.length  < 40 ? alert.device  : '–');
            const service   = ai?.service || (alert.service?.length < 80 ? alert.service : '');

            return (
                <div style={{
                    background: 'var(--bg-secondary)',
                    border: `1px solid ${col}33`,
                    borderTop: `3px solid ${col}`,
                    borderRadius: 10,
                    overflow: 'hidden',
                    opacity: alert.acknowledged ? 0.55 : 1,
                    fontSize: 12,
                }}>
                    {/* Card-Header */}
                    <div style={{ padding: '10px 12px 8px', borderBottom: '1px solid var(--border-color)' }}>
                        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 6 }}>
                            <div style={{ fontWeight: 700, fontSize: 13, color: 'var(--text-primary)', lineHeight: 1.3 }}>
                                🖥 {device}
                            </div>
                            <span style={{ fontSize: 10, color: 'var(--text-muted)', flexShrink: 0, marginTop: 2 }}>{timeAgo(alert.created_at)}</span>
                        </div>
                        {service && <div style={{ fontSize: 11, color: 'var(--text-secondary)', marginTop: 2 }}>{service}</div>}
                    </div>

                    {/* State Transition */}
                    {(stateFrom || stateTo) && (
                        <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '6px 12px', background: col + '08' }}>
                            {stateFrom && <span style={{ fontSize: 11, fontWeight: 600, padding: '2px 7px', borderRadius: 5, background: `${SC.crit}22`, color: SC.crit }}>{stateFrom}</span>}
                            {stateFrom && stateTo && <span style={{ color: 'var(--text-muted)' }}>→</span>}
                            {stateTo   && <span style={{ fontSize: 11, fontWeight: 700, padding: '2px 7px', borderRadius: 5, background: `${col}22`, color: col }}>{stateTo}</span>}
                        </div>
                    )}

                    {/* KI-Block */}
                    <div style={{ padding: '8px 12px' }}>
                        {ai?.metrics && (
                            <div style={{ fontSize: 11, color: 'var(--text-muted)', marginBottom: 6, padding: '3px 7px', background: 'var(--bg-tertiary)', borderRadius: 5, display: 'inline-block' }}>
                                📊 {ai.metrics}
                            </div>
                        )}
                        {ai?.what ? (
                            <>
                                <div style={{ fontSize: 12, color: 'var(--text-primary)', lineHeight: 1.5, marginBottom: 6 }}>{ai.what}</div>
                                {ai.recommendation && (
                                    <div style={{ display: 'flex', gap: 5, padding: '5px 8px', borderRadius: 6, background: ai.action_needed ? `${SC.warn}12` : `${SC.ok}12`, border: `1px solid ${ai.action_needed ? SC.warn : SC.ok}30` }}>
                                        <span style={{ flexShrink: 0 }}>{ai.action_needed ? '⚠️' : '✅'}</span>
                                        <span style={{ fontSize: 11, color: 'var(--text-secondary)', lineHeight: 1.4 }}>{ai.recommendation}</span>
                                    </div>
                                )}
                            </>
                        ) : (
                            <div style={{ fontSize: 11, color: 'var(--text-muted)' }}>⏳ KI-Analyse ausstehend…</div>
                        )}
                    </div>

                    {/* Footer */}
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', padding: '6px 12px 8px', borderTop: '1px solid var(--border-color)' }}>
                        <div style={{ display: 'flex', gap: 6 }}>
                            {ai && <span style={{ fontSize: 10, padding: '1px 6px', borderRadius: 4, background: 'rgba(124,92,246,0.12)', color: '#a78bfa' }}>🤖 KI</span>}
                            {alert.acknowledged && <span style={{ fontSize: 10, padding: '1px 6px', borderRadius: 4, background: 'var(--bg-tertiary)', color: 'var(--text-muted)' }}>✓ Quittiert</span>}
                        </div>
                        <div style={{ display: 'flex', gap: 4 }}>
                            {!alert.acknowledged && (
                                <button onClick={() => handleExtAcknowledge(alert.id)} style={{ padding: '3px 9px', borderRadius: 6, border: `1px solid ${col}55`, background: col + '15', color: col, fontSize: 11, cursor: 'pointer', fontWeight: 600 }}>✓</button>
                            )}
                            <button onClick={() => handleExtRemove(alert.id)} style={{ padding: '3px 7px', borderRadius: 6, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 11, cursor: 'pointer' }}>🗑</button>
                        </div>
                    </div>
                </div>
            );
        };

        return (
            <div>
                {/* Header */}
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                        <span style={{ fontSize: 13, color: 'var(--text-muted)' }}>
                            {netgoAlerts.length} Alerts · {netgoUnacked} nicht quittiert
                        </span>
                        {hiddenCount > 0 && (
                            <button onClick={() => setHideAcknowledged(h => !h)} style={{ padding: '3px 10px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 11, cursor: 'pointer' }}>
                                {hideAcknowledged ? `Quittierte einblenden (${hiddenCount})` : 'Quittierte ausblenden'}
                            </button>
                        )}
                    </div>
                    <button onClick={loadExtAlerts} style={{ padding: '5px 14px', borderRadius: 8, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>↻ Aktualisieren</button>
                </div>

                {visible.length === 0 && (
                    <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-muted)', fontSize: 14 }}>✅ Keine aktiven NetGo-Alerts</div>
                )}

                {/* Kanban Board */}
                <div style={{ display: 'grid', gridTemplateColumns: `repeat(${columns.length}, 1fr)`, gap: 16, alignItems: 'start' }}>
                    {columns.map(col => (
                        <div key={col.key}>
                            {/* Spalten-Header */}
                            <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 10, padding: '8px 12px', borderRadius: 8, background: col.color + '12', border: `1px solid ${col.color}33` }}>
                                <span style={{ fontSize: 14 }}>{col.icon}</span>
                                <span style={{ fontWeight: 700, fontSize: 13, color: col.color }}>{col.label}</span>
                                <span style={{ marginLeft: 'auto', fontSize: 11, fontWeight: 700, padding: '1px 7px', borderRadius: 10, background: col.color + '22', color: col.color }}>{col.alerts.length}</span>
                            </div>
                            {/* Cards */}
                            <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                                {col.alerts.map(alert => <KanbanCard key={alert.id} alert={alert} />)}
                            </div>
                        </div>
                    ))}
                </div>
            </div>
        );
    };

    const renderArcticWolfAlerts = () => {
        const sevColor = (s) => s === 'CRIT' ? SC.crit : s === 'WARN' ? SC.warn : s === 'OK' ? SC.ok : SC.unknown;

        const hiddenCount = awAlerts.filter(a => a.acknowledged).length;
        const visible = hideAcknowledged ? awAlerts.filter(a => !a.acknowledged) : awAlerts;

        const renderAWCard = (alert) => {
            const color = sevColor(alert.severity);
            const expanded = expandedAlerts[alert.id];
            let aw = null;
            if (alert.raw_body) { try { aw = JSON.parse(alert.raw_body); } catch {} }

            const labelStyle = { fontSize: 11, color: 'var(--text-muted)', minWidth: 130, flexShrink: 0 };
            const valStyle   = { fontSize: 12, color: 'var(--text-primary)', wordBreak: 'break-word' };
            const row = (label, val) => val ? (
                <div style={{ display: 'flex', gap: 8, padding: '4px 0', borderBottom: '1px solid var(--border-color)' }}>
                    <span style={labelStyle}>{label}</span><span style={valStyle}>{val}</span>
                </div>
            ) : null;
            const section = (title, text) => text ? (
                <div style={{ marginTop: 10 }}>
                    <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 1, marginBottom: 4 }}>{title}</div>
                    <div style={{ fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.6 }}>{text}</div>
                </div>
            ) : null;

            return (
                <div key={alert.id} style={{ background: 'var(--bg-secondary)', border: `1px solid ${alert.acknowledged ? 'var(--border-color)' : color + '44'}`, borderLeft: `4px solid ${color}`, borderRadius: 10, padding: '14px 16px', opacity: alert.acknowledged ? 0.65 : 1 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
                        <div style={{ flex: 1 }}>
                            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', marginBottom: 8 }}>
                                <span style={{ fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 6, background: color + '22', color, border: `1px solid ${color}44`, letterSpacing: 1 }}>{aw?.severity_label || alert.severity}</span>
                                {alert.acknowledged && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 6, background: 'var(--bg-tertiary)', color: 'var(--text-muted)', border: '1px solid var(--border-color)' }}>✓ Quittiert</span>}
                                {alert.ticket_id    && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 6, background: SC.ok + '22', color: SC.ok, border: `1px solid ${SC.ok}44` }}>🎫 Ticket #{alert.ticket_id}</span>}
                            </div>
                            <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 4 }}>{alert.message || aw?.incident_name}</div>
                            <div style={{ fontSize: 12, color: 'var(--text-muted)' }}>
                                🖥 {alert.device}{aw?.ip ? ` · ${aw.ip}` : ''}
                                {alert.state_time && <span style={{ marginLeft: 12 }}>🕐 {alert.state_time}</span>}
                                <span style={{ marginLeft: 12 }}>Eingang: {timeAgo(alert.created_at)}</span>
                            </div>
                        </div>
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 6, flexShrink: 0 }}>
                            {!alert.ticket_id && (
                                <button onClick={() => handleExtCreateTicket(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: `1px solid var(--accent)`, background: 'var(--accent)', color: '#fff', fontSize: 12, cursor: 'pointer', fontWeight: 600, whiteSpace: 'nowrap' }}>🎫 Ticket</button>
                            )}
                            {!alert.acknowledged && (
                                <button onClick={() => handleExtAcknowledge(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer', whiteSpace: 'nowrap' }}>✓ Quittieren</button>
                            )}
                            <button onClick={() => handleExtRemove(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>🗑</button>
                        </div>
                    </div>
                    {aw && (
                        <div style={{ marginTop: 12, padding: '10px 12px', background: 'var(--bg-primary)', borderRadius: 8 }}>
                            {row('Event-Typ',   aw.event_type)}
                            {row('Application', aw.application)}
                            {row('User',        aw.user)}
                            {row('Process',     aw.process)}
                        </div>
                    )}
                    {aw && (aw.what_is_it || aw.why_matters || aw.next_steps || aw.recommend) && (
                        <button onClick={() => toggleAlertExpand(alert.id)} style={{ marginTop: 10, padding: '4px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>
                            {expanded ? '▲ Weniger' : '▼ Mehr Details'}
                        </button>
                    )}
                    {expanded && aw && (
                        <div style={{ marginTop: 12, padding: '12px', background: 'var(--bg-primary)', borderRadius: 8, display: 'flex', flexDirection: 'column', gap: 2 }}>
                            {section('Was ist passiert?',        aw.what_is_it)}
                            {section('Warum ist das relevant?',  aw.why_matters)}
                            {section('Wie wurde es erkannt?',    aw.how_detected)}
                            {section('Nächste Schritte',         aw.next_steps)}
                            {section('Empfehlungen Arctic Wolf', aw.recommend)}
                        </div>
                    )}
                </div>
            );
        };

        return (
            <div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                        <span style={{ fontSize: 13, color: 'var(--text-muted)' }}>{awAlerts.length} Alert{awAlerts.length !== 1 ? 's' : ''} · {awUnacked} nicht quittiert</span>
                        {hiddenCount > 0 && (
                            <button onClick={() => setHideAcknowledged(h => !h)} style={{ padding: '3px 10px', borderRadius: 7, border: '1px solid var(--border-color)', background: hideAcknowledged ? 'var(--accent)' : 'none', color: hideAcknowledged ? '#fff' : 'var(--text-muted)', fontSize: 11, cursor: 'pointer' }}>
                                {hideAcknowledged ? `✓ Quittierte ausgeblendet (${hiddenCount})` : `Quittierte ausblenden (${hiddenCount})`}
                            </button>
                        )}
                    </div>
                    <button onClick={loadExtAlerts} style={{ padding: '5px 14px', borderRadius: 8, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>↻ Aktualisieren</button>
                </div>
                {visible.length === 0 && (
                    <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-muted)', fontSize: 14 }}>✅ Keine Arctic Wolf Alerts vorhanden</div>
                )}
                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>
                    {visible.map(renderAWCard)}
                </div>
            </div>
        );
    };

    const renderMdoAlerts = () => {
        const sevColor = (s) => s === 'CRIT' ? SC.crit : s === 'WARN' ? SC.warn : s === 'OK' ? SC.ok : SC.unknown;

        const parseAi  = (alert) => { try { return alert.ai_analysis ? (typeof alert.ai_analysis === 'string' ? JSON.parse(alert.ai_analysis) : alert.ai_analysis) : null; } catch { return null; } };
        const parseRaw = (alert) => { try { return alert.raw_body ? (typeof alert.raw_body === 'string' ? JSON.parse(alert.raw_body) : alert.raw_body) : null; } catch { return null; } };

        const hiddenCount = mdoAlerts.filter(a => a.acknowledged).length;
        const visible = hideAcknowledged ? mdoAlerts.filter(a => !a.acknowledged) : mdoAlerts;

        const labelStyle = { fontSize: 11, color: 'var(--text-muted)', minWidth: 140, flexShrink: 0 };
        const valStyle   = { fontSize: 12, color: 'var(--text-primary)', wordBreak: 'break-word' };
        const row = (label, val) => val ? (
            <div style={{ display: 'flex', gap: 8, padding: '4px 0', borderBottom: '1px solid var(--border-color)' }}>
                <span style={labelStyle}>{label}</span><span style={valStyle}>{val}</span>
            </div>
        ) : null;

        const renderMdoCard = (alert) => {
            const color    = sevColor(alert.severity);
            const expanded = expandedAlerts[alert.id];
            const ai       = parseAi(alert);
            const raw      = parseRaw(alert);

            return (
                <div key={alert.id} style={{ background: 'var(--bg-secondary)', border: `1px solid ${alert.acknowledged ? 'var(--border-color)' : color + '44'}`, borderLeft: `4px solid ${color}`, borderRadius: 10, padding: '14px 16px', opacity: alert.acknowledged ? 0.65 : 1 }}>
                    <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
                        <div style={{ flex: 1 }}>
                            <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap', marginBottom: 8 }}>
                                <span style={{ fontSize: 10, fontWeight: 700, padding: '2px 8px', borderRadius: 6, background: color + '22', color, border: `1px solid ${color}44`, letterSpacing: 1 }}>{alert.severity}</span>
                                <span style={{ fontSize: 11, fontWeight: 600, color: '#60a5fa', background: 'rgba(96,165,250,0.12)', padding: '2px 8px', borderRadius: 6, border: '1px solid rgba(96,165,250,0.3)' }}>MS DEFENDER</span>
                                {alert.acknowledged && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 6, background: 'var(--bg-tertiary)', color: 'var(--text-muted)', border: '1px solid var(--border-color)' }}>✓ Quittiert</span>}
                                {alert.ticket_id    && <span style={{ fontSize: 10, padding: '2px 7px', borderRadius: 6, background: SC.ok + '22', color: SC.ok, border: `1px solid ${SC.ok}44` }}>🎫 Ticket #{alert.ticket_id}</span>}
                            </div>
                            <div style={{ fontSize: 15, fontWeight: 700, marginBottom: 4 }}>{alert.message}</div>
                            <div style={{ fontSize: 12, color: 'var(--text-muted)' }}>
                                👤 {alert.device || '(kein Benutzer)'}
                                {alert.service && <span style={{ marginLeft: 12 }}>📂 {alert.service}</span>}
                                {alert.state_time && <span style={{ marginLeft: 12 }}>🕐 {new Date(alert.state_time).toLocaleString('de-DE')}</span>}
                                <span style={{ marginLeft: 12 }}>Eingang: {timeAgo(alert.created_at)}</span>
                            </div>
                        </div>
                        <div style={{ display: 'flex', flexDirection: 'column', gap: 6, flexShrink: 0 }}>
                            {!alert.ticket_id && <button onClick={() => handleExtCreateTicket(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: `1px solid var(--accent)`, background: 'var(--accent)', color: '#fff', fontSize: 12, cursor: 'pointer', fontWeight: 600, whiteSpace: 'nowrap' }}>🎫 Ticket</button>}
                            {!alert.acknowledged && <button onClick={() => handleExtAcknowledge(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer', whiteSpace: 'nowrap' }}>✓ Quittieren</button>}
                            <button onClick={() => handleExtRemove(alert.id)} style={{ padding: '5px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>🗑</button>
                        </div>
                    </div>
                    {raw && (
                        <div style={{ marginTop: 12, padding: '10px 12px', background: 'var(--bg-primary)', borderRadius: 8 }}>
                            {row('Kategorie',          raw.category)}
                            {row('Bedrohungsfamilie',  raw.threatFamilyName)}
                            {row('Angriffsvektor',     ai?.attack_vector || (raw.attackTechniques || [])[0])}
                            {row('Bedrohungstyp',      ai?.threat_type)}
                            {row('Status (Defender)',  alert.state_transition)}
                        </div>
                    )}
                    {(ai?.what || ai?.recommendation) && (
                        <button onClick={() => toggleAlertExpand(alert.id)} style={{ marginTop: 10, padding: '4px 12px', borderRadius: 7, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>
                            {expanded ? '▲ Weniger' : '▼ KI-Analyse anzeigen'}
                        </button>
                    )}
                    {!ai && <div style={{ marginTop: 8, fontSize: 11, color: 'var(--text-muted)' }}>⏳ KI-Analyse ausstehend…</div>}
                    {expanded && ai && (
                        <div style={{ marginTop: 12, padding: '12px', background: 'var(--bg-primary)', borderRadius: 8 }}>
                            {ai.what && (
                                <div style={{ marginBottom: 10 }}>
                                    <div style={{ fontSize: 11, fontWeight: 700, color: 'var(--text-muted)', textTransform: 'uppercase', letterSpacing: 1, marginBottom: 4 }}>Was ist passiert?</div>
                                    <div style={{ fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.6 }}>{ai.what}</div>
                                </div>
                            )}
                            {ai.recommendation && (
                                <div style={{ display: 'flex', gap: 5, padding: '8px 10px', borderRadius: 7, background: ai.action_needed ? `${SC.warn}12` : `${SC.ok}12`, border: `1px solid ${ai.action_needed ? SC.warn : SC.ok}30` }}>
                                    <span style={{ flexShrink: 0 }}>{ai.action_needed ? '⚠️' : '✅'}</span>
                                    <span style={{ fontSize: 12, color: 'var(--text-secondary)', lineHeight: 1.5 }}>{ai.recommendation}</span>
                                </div>
                            )}
                        </div>
                    )}
                </div>
            );
        };

        return (
            <div>
                <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 14 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
                        <span style={{ fontSize: 13, color: 'var(--text-muted)' }}>{mdoAlerts.length} Alert{mdoAlerts.length !== 1 ? 's' : ''} · {mdoUnacked} nicht quittiert</span>
                        {hiddenCount > 0 && (
                            <button onClick={() => setHideAcknowledged(h => !h)} style={{ padding: '3px 10px', borderRadius: 7, border: '1px solid var(--border-color)', background: hideAcknowledged ? 'var(--accent)' : 'none', color: hideAcknowledged ? '#fff' : 'var(--text-muted)', fontSize: 11, cursor: 'pointer' }}>
                                {hideAcknowledged ? `✓ Quittierte ausgeblendet (${hiddenCount})` : `Quittierte ausblenden (${hiddenCount})`}
                            </button>
                        )}
                    </div>
                    <button onClick={loadExtAlerts} style={{ padding: '5px 14px', borderRadius: 8, border: '1px solid var(--border-color)', background: 'none', color: 'var(--text-muted)', fontSize: 12, cursor: 'pointer' }}>↻ Aktualisieren</button>
                </div>
                {visible.length === 0 && <div style={{ textAlign: 'center', padding: 60, color: 'var(--text-muted)', fontSize: 14 }}>✅ Keine aktiven Microsoft Defender Alerts</div>}
                <div style={{ display: 'flex', flexDirection: 'column', gap: 10 }}>{visible.map(renderMdoCard)}</div>
            </div>
        );
    };

    const tabs = [
        { id: 'overview',     label: '🖥 Host-Übersicht', badge: null },
        { id: 'network',      label: 'Netzwerk',          badge: devices.length + unifiDevices.length },
        { id: 'agents',       label: 'Agents',            badge: agents.length },
        { id: 'problems',     label: 'Probleme',          badge: activeProblems.length, red: activeProblems.length > 0 },
        { id: 'netgo',        label: 'NetGo',             badge: netgoUnacked, red: netgoUnacked > 0 },
        { id: 'arcticwolf',   label: 'Arctic Wolf',       badge: awUnacked, red: awUnacked > 0 },
        { id: 'mdo',          label: 'MS Defender',       badge: mdoUnacked, red: mdoUnacked > 0 },
        { id: 'ext-alerts',   label: 'Sonstige',          badge: extUnacked - netgoUnacked - awUnacked - mdoUnacked > 0 ? extUnacked - netgoUnacked - awUnacked - mdoUnacked : null, red: false },
    ];

    return (
        <div style={{ padding: 24 }}>
            <style>{`
                @keyframes monPulse { 0%,100%{opacity:1} 50%{opacity:.3} }
                @keyframes nmPulse  { 0%,100%{opacity:1;transform:scale(1)} 50%{opacity:.5;transform:scale(1.3)} }
                ::-webkit-scrollbar { width:6px; height:6px; }
                ::-webkit-scrollbar-track { background:transparent; }
                ::-webkit-scrollbar-thumb { background:rgba(255,255,255,0.12); border-radius:10px; }
                ::-webkit-scrollbar-thumb:hover { background:rgba(255,255,255,0.22); }
            `}</style>

            <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
                <div>
                    <h1 style={{ fontSize: 22, fontWeight: 750, margin: 0, letterSpacing: -.3 }}>📡 Monitoring</h1>
                    <div style={{ fontSize: 12, color: 'var(--text-muted)', marginTop: 3 }}>{devices.length + agents.length} Hosts · Letzter Scan {lastUpdated}</div>
                </div>
                <div style={{ display: 'flex', alignItems: 'center', gap: 9, padding: '7px 13px', borderRadius: 11, background: 'rgba(255,255,255,.04)', border: '1px solid rgba(255,255,255,.08)' }}>
                    <div style={{ position: 'relative', width: 16, height: 16 }}>
                        <svg width="16" height="16" viewBox="0 0 16 16" style={{ transform: 'rotate(-90deg)' }}>
                            <circle cx="8" cy="8" r="6.5" fill="none" stroke="rgba(255,255,255,.12)" strokeWidth="2" />
                            <circle cx="8" cy="8" r="6.5" fill="none" stroke={countdown <= 5 ? '#f59e0b' : '#14b8a6'} strokeWidth="2" strokeLinecap="round" strokeDasharray="40.8" strokeDashoffset={(40.8 * (1 - countdown / 30)).toFixed(1)} />
                        </svg>
                    </div>
                    <span style={{ fontFamily: 'monospace', fontSize: 13, fontWeight: 700, color: 'var(--text-primary)' }}>{countdown}s</span>
                </div>
            </div>

            <TacticalOverview devices={devices} agents={agents} problems={problems} acknowledged={acknowledged} countdown={countdown} lastUpdated={lastUpdated} onTabChange={setActiveTab} extAlerts={extAlerts} />

            {/* Tab bar — neues Design */}
            <div style={{ display: 'flex', gap: 0, marginBottom: 22, borderBottom: '1px solid rgba(255,255,255,.08)' }}>
                {tabs.map(({ id, label, badge, red }) => (
                    <button key={id} onClick={() => setActiveTab(id)} style={{ padding: '10px 20px', border: 'none', background: 'none', cursor: 'pointer', fontSize: 13, fontWeight: activeTab === id ? 700 : 500, color: activeTab === id ? '#14b8a6' : 'var(--text-muted)', borderBottom: activeTab === id ? '2px solid #14b8a6' : '2px solid transparent', marginBottom: -1, transition: 'all .14s', display: 'flex', alignItems: 'center', gap: 7, whiteSpace: 'nowrap' }}>
                        {label}
                        {badge != null && badge > 0 && (
                            <span style={{ fontSize: 10, fontWeight: 700, padding: '1px 7px', borderRadius: 20, background: red ? 'rgba(244,63,94,.16)' : 'rgba(255,255,255,.06)', color: red ? '#fda4af' : 'var(--text-muted)', border: `1px solid ${red ? 'rgba(244,63,94,.3)' : 'rgba(255,255,255,.08)'}`, minWidth: 20, textAlign: 'center' }}>{badge}</span>
                        )}
                    </button>
                ))}
            </div>

            {activeTab === 'overview'   && renderOverview()}
            {activeTab === 'network'    && renderNetwork()}
            {activeTab === 'agents'     && renderAgents()}
            {activeTab === 'problems'   && renderProblems()}
            {activeTab === 'netgo'      && renderNetGoAlerts()}
            {activeTab === 'arcticwolf' && renderArcticWolfAlerts()}
            {activeTab === 'mdo'        && renderMdoAlerts()}
            {activeTab === 'ext-alerts' && renderExtAlerts()}

            {selectedDevice && <NetworkDetailModal device={selectedDevice} onClose={() => setSelectedDevice(null)} onEdit={d => { setEditDevice(d); setShowDeviceForm(true); }} onDelete={d => { handleNetDelete(d); setSelectedDevice(null); }} onCheckNow={networkMonitorService.checkNow} />}
            {showDeviceForm && <DeviceFormModal device={editDevice} onSave={handleNetSave} onClose={() => { setShowDeviceForm(false); setEditDevice(null); }} />}
            {showDiscover  && <DiscoverModal onClose={() => setShowDiscover(false)} onAdd={handleNetSave} />}
            {selectedAgent && <AgentDetailModal agent={selectedAgent} onClose={() => setSelectedAgent(null)} onDelete={handleAgentDelete} />}
            {showUnifiCfg  && <UnifiConfigModal unifiConfig={unifiConfig} onSave={cfg => { setUnifiConfig(cfg); loadUnifi(); toast.success('Gespeichert'); }} onClose={() => setShowUnifiCfg(false)} />}
        </div>
    );
};

export default MonitoringPage;
