<?php
/**
 * Mesh Security Dashboard — Tab View
 * Renders node health pills, security event feed, and
 * integrity / key-rotation / lockdown panels.
 */
if (!defined('DASHBOARD_ROOT')) { http_response_code(403); exit; }

/* ── Load data ──────────────────────────────────────────────────── */
require __DIR__ . '/../modules/mesh_security_data.php';
require __DIR__ . '/../modules/mesh/engine_db_bridge.php';

/* ── AI Alerts data from Engine DB ─────────────────────────────── */
$aiAlerts     = EngineDB::getAlerts(20, true);
$aiStats      = EngineDB::getAlertStats();
$aiSuggestions = EngineDB::getSuggestions('pending', 5);

/* ── Helper: heartbeat freshness colour ─────────────────────────── */
function meshStatusColour(?string $heartbeat): string {
    if (!$heartbeat) return 'red';
    $age = time() - strtotime($heartbeat);
    if ($age < 120)  return 'green';
    if ($age < 600)  return 'amber';
    return 'red';
}
function meshStatusLabel(string $colour): string {
    return match($colour) {
        'green' => 'Healthy',
        'amber' => 'Stale',
        default => 'Offline',
    };
}

/* ── Severity badge colour ──────────────────────────────────────── */
function severityBadgeColour(string $sev): string {
    return match(strtolower($sev)) {
        'critical' => '#ef4444',
        'high'     => '#f97316',
        'medium'   => '#e6a817',
        'low'      => '#22c55e',
        default    => '#64748b',
    };
}

$now = time();
?>

<style>
/* ── Mesh Security Scoped Styles ────────────────────────────────── */
.msec-wrap{display:flex;flex-direction:column;gap:24px}

/* ── Header row ─────────────────────────────────────────────────── */
.msec-header{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:12px}
.msec-header h2{margin:0;font-size:1.35rem;font-weight:700;color:#fff;letter-spacing:.02em}
.msec-header-badges{display:flex;gap:10px}
.msec-hbadge{padding:5px 14px;border-radius:8px;font-size:.82rem;font-weight:600;color:#fff;background:rgba(255,255,255,.07)}
.msec-hbadge.crit{background:rgba(239,68,68,.18);color:#ef4444}
.msec-hbadge.canary{background:rgba(230,168,23,.15);color:#e6a817}
.msec-hbadge.ai{background:rgba(147,51,234,.18);color:#a78bfa}

/* ── AI Alerts Panel ───────────────────────────────────────────── */
.msec-ai-header{display:flex;align-items:center;gap:12px;margin-bottom:14px}
.msec-ai-header h3{margin:0;display:flex;align-items:center;gap:8px}
.msec-ai-kpis{display:flex;gap:10px;margin-left:auto}
.msec-ai-kpi{padding:4px 12px;border-radius:6px;font-size:.75rem;font-weight:700}
.msec-ai-kpi.crit-bg{background:rgba(239,68,68,.15);color:#ef4444}
.msec-ai-kpi.high-bg{background:rgba(249,115,22,.15);color:#f97316}
.msec-ai-kpi.sug-bg{background:rgba(147,51,234,.15);color:#a78bfa}
.msec-ai-conf{display:inline-block;padding:1px 7px;border-radius:4px;font-size:.7rem;font-weight:600;background:rgba(255,255,255,.06);color:rgba(255,255,255,.5)}
.msec-ai-actions{display:flex;gap:6px}
.msec-ai-btn{padding:3px 10px;border:none;border-radius:5px;font-size:.72rem;font-weight:700;cursor:pointer;transition:all .15s}
.msec-ai-btn.ack{background:rgba(34,197,94,.15);color:#22c55e}
.msec-ai-btn.ack:hover{background:rgba(34,197,94,.3)}
.msec-ai-btn.res{background:rgba(147,51,234,.15);color:#a78bfa}
.msec-ai-btn.res:hover{background:rgba(147,51,234,.3)}

/* ── Node health pills ──────────────────────────────────────────── */
.msec-pills{display:grid;grid-template-columns:repeat(auto-fill,minmax(220px,1fr));gap:14px}
.msec-pill{
    background:rgba(16,20,34,.92);
    border:1px solid rgba(255,255,255,.06);
    border-radius:12px;
    padding:16px 18px;
    display:flex;flex-direction:column;gap:8px;
    transition:border-color .2s,box-shadow .2s;
}
.msec-pill:hover{border-color:rgba(230,168,23,.35);box-shadow:0 0 18px rgba(230,168,23,.08)}

.msec-pill-top{display:flex;align-items:center;gap:10px}
.msec-dot{
    width:12px;height:12px;border-radius:50%;flex-shrink:0;
    box-shadow:0 0 6px currentColor;
}
.msec-dot.green{background:#22c55e;color:#22c55e}
.msec-dot.amber{background:#e6a817;color:#e6a817}
.msec-dot.red{background:#ef4444;color:#ef4444}

.msec-pill-name{font-weight:700;font-size:1.0rem;color:#fff}
.msec-pill-id{font-size:.75rem;color:rgba(255,255,255,.35);margin-left:auto;font-family:monospace}

.msec-pill-stats{display:flex;gap:14px;flex-wrap:wrap}
.msec-pill-stat{font-size:.78rem;color:rgba(255,255,255,.55)}
.msec-pill-stat strong{color:#e6a817;font-weight:600}

.msec-pill-lockdown{
    font-size:.72rem;padding:3px 10px;border-radius:6px;
    background:rgba(239,68,68,.15);color:#ef4444;font-weight:600;
    align-self:flex-start;
}
.msec-pill-lockdown.none{background:rgba(34,197,94,.1);color:#22c55e}

/* ── Section card ───────────────────────────────────────────────── */
.msec-card{
    background:rgba(16,20,34,.92);
    border:1px solid rgba(255,255,255,.06);
    border-radius:12px;
    padding:20px;
}
.msec-card h3{margin:0 0 14px;font-size:1.05rem;font-weight:700;color:#fff;display:flex;align-items:center;gap:8px}
.msec-card h3 .msec-count{
    font-size:.75rem;padding:2px 9px;border-radius:6px;
    background:rgba(230,168,23,.15);color:#e6a817;font-weight:600;
}

/* ── Event feed table ───────────────────────────────────────────── */
.msec-events-wrap{max-height:380px;overflow-y:auto;border-radius:8px}
.msec-events-wrap::-webkit-scrollbar{width:5px}
.msec-events-wrap::-webkit-scrollbar-track{background:transparent}
.msec-events-wrap::-webkit-scrollbar-thumb{background:rgba(255,255,255,.12);border-radius:4px}

.msec-tbl{width:100%;border-collapse:collapse;font-size:.82rem}
.msec-tbl thead{position:sticky;top:0;z-index:2}
.msec-tbl th{
    text-align:left;padding:9px 12px;
    background:rgba(10,14,26,.95);
    color:rgba(255,255,255,.45);font-weight:600;font-size:.75rem;
    text-transform:uppercase;letter-spacing:.04em;
    border-bottom:1px solid rgba(255,255,255,.06);
}
.msec-tbl td{
    padding:8px 12px;
    border-bottom:1px solid rgba(255,255,255,.04);
    color:rgba(255,255,255,.7);
    vertical-align:middle;
}
.msec-tbl tbody tr:hover td{background:rgba(230,168,23,.04)}

.msec-sev-badge{
    display:inline-block;padding:2px 10px;border-radius:6px;
    font-size:.72rem;font-weight:700;text-transform:uppercase;
    letter-spacing:.03em;
}

/* ── Bottom 3 panels ────────────────────────────────────────────── */
.msec-bottom-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(320px,1fr));gap:16px}

.msec-integrity-bar{display:flex;height:10px;border-radius:6px;overflow:hidden;margin:10px 0 14px}
.msec-integrity-bar .pass{background:#22c55e}
.msec-integrity-bar .fail{background:#ef4444}

.msec-mini-tbl{width:100%;border-collapse:collapse;font-size:.78rem}
.msec-mini-tbl th{
    text-align:left;padding:7px 10px;
    color:rgba(255,255,255,.4);font-weight:600;font-size:.72rem;
    text-transform:uppercase;letter-spacing:.04em;
    border-bottom:1px solid rgba(255,255,255,.06);
}
.msec-mini-tbl td{
    padding:6px 10px;
    border-bottom:1px solid rgba(255,255,255,.03);
    color:rgba(255,255,255,.65);
}
.msec-mini-tbl tbody tr:hover td{background:rgba(230,168,23,.04)}

.msec-verified{color:#22c55e;font-weight:600}
.msec-unverified{color:#ef4444;font-weight:600}
.msec-ts{color:rgba(255,255,255,.35);font-size:.75rem;font-family:monospace}

/* ── Empty state ────────────────────────────────────────────────── */
.msec-empty{text-align:center;padding:28px 10px;color:rgba(255,255,255,.3);font-size:.85rem}
</style>

<div class="msec-wrap">

    <!-- ════════════ HEADER ════════════ -->
    <div class="msec-header">
        <h2>🛡️ Mesh Security</h2>
        <div class="msec-header-badges">
            <span class="msec-hbadge">Events: <?= number_format($totalEvents) ?></span>
            <?php if ($criticalEvents > 0): ?>
                <span class="msec-hbadge crit">⚠ <?= $criticalEvents ?> Critical (24h)</span>
            <?php endif; ?>
            <?php if ($canaryTriggerCount > 0): ?>
                <span class="msec-hbadge canary">🐦 <?= $canaryTriggerCount ?> Canary Trips</span>
            <?php endif; ?>
            <?php if ($aiStats['total'] > 0): ?>
                <span class="msec-hbadge ai">🤖 <?= $aiStats['total'] ?> AI Alerts (24h)</span>
            <?php endif; ?>
        </div>
    </div>

    <!-- ════════════ NODE HEALTH PILLS ════════════ -->
    <div class="msec-pills">
        <?php foreach ($nodeHealth as $nid => $nd):
            $colour   = meshStatusColour($nd['last_heartbeat']);
            $label    = $meshNodes[$nid] ?? ($nd['hostname'] ?? $nid);
            $statusTx = meshStatusLabel($colour);
            $lockLvl  = isset($lockdownByNode[$nid]) ? (int)$lockdownByNode[$nid]['level'] : 0;
            $hbAgo    = $nd['last_heartbeat']
                ? round((time() - strtotime($nd['last_heartbeat'])) / 60, 1) . 'm ago'
                : 'N/A';
        ?>
        <div class="msec-pill">
            <div class="msec-pill-top">
                <span class="msec-dot <?= $colour ?>" title="<?= UI::e($statusTx) ?>"></span>
                <span class="msec-pill-name"><?= UI::e($label) ?></span>
                <span class="msec-pill-id">#<?= (int)$nid ?></span>
            </div>
            <div class="msec-pill-stats">
                <span class="msec-pill-stat">Heartbeat: <strong><?= UI::e($hbAgo) ?></strong></span>
                <span class="msec-pill-stat">Runs: <strong><?= number_format((int)$nd['tool_run_count']) ?></strong></span>
                <?php if ((int)$nd['tool_fail_count'] > 0): ?>
                    <span class="msec-pill-stat" style="color:#ef4444">Fails: <strong><?= (int)$nd['tool_fail_count'] ?></strong></span>
                <?php endif; ?>
            </div>
            <?php if ($lockLvl > 0): ?>
                <span class="msec-pill-lockdown">🔒 Lockdown L<?= $lockLvl ?></span>
            <?php else: ?>
                <span class="msec-pill-lockdown none">Unlocked</span>
            <?php endif; ?>
        </div>
        <?php endforeach; ?>
    </div>

    <!-- ════════════ SECURITY EVENT FEED ════════════ -->
    <div class="msec-card">
        <h3>Security Event Feed <span class="msec-count"><?= count($secEvents) ?> recent</span></h3>
        <?php if (empty($secEvents)): ?>
            <div class="msec-empty">No security events recorded.</div>
        <?php else: ?>
            <div class="msec-events-wrap">
                <table class="msec-tbl">
                    <thead>
                        <tr>
                            <th>Time</th>
                            <th>Node</th>
                            <th>Source</th>
                            <th>Event</th>
                            <th>Severity</th>
                            <th>Details</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($secEvents as $ev): ?>
                        <tr>
                            <td class="msec-ts"><?= UI::e($ev['created_at']) ?></td>
                            <td><?= UI::e($ev['hostname']) ?></td>
                            <td><?= UI::e($ev['source_tag']) ?></td>
                            <td><?= UI::e($ev['event_type']) ?></td>
                            <td>
                                <span class="msec-sev-badge"
                                      style="background:<?= severityBadgeColour($ev['severity']) ?>22;color:<?= severityBadgeColour($ev['severity']) ?>">
                                    <?= UI::e(strtoupper($ev['severity'])) ?>
                                </span>
                            </td>
                            <td style="max-width:260px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
                                title="<?= UI::e($ev['details_enc']) ?>">
                                <?= UI::e($ev['details_enc']) ?>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>

    <!-- ════════════ AI SECURITY ALERTS (Engine/Mistral) ════════════ -->
    <div class="msec-card">
        <div class="msec-ai-header">
            <h3>🤖 AI Security Alerts <span class="msec-count"><?= $aiStats['unresolved'] ?> unresolved</span></h3>
            <div class="msec-ai-kpis">
                <?php if ($aiStats['critical'] > 0): ?>
                    <span class="msec-ai-kpi crit-bg"><?= $aiStats['critical'] ?> CRITICAL</span>
                <?php endif; ?>
                <?php if ($aiStats['high'] > 0): ?>
                    <span class="msec-ai-kpi high-bg"><?= $aiStats['high'] ?> HIGH</span>
                <?php endif; ?>
                <?php if ($aiStats['pending_suggestions'] > 0): ?>
                    <span class="msec-ai-kpi sug-bg"><?= $aiStats['pending_suggestions'] ?> Pending Actions</span>
                <?php endif; ?>
            </div>
        </div>
        <?php if (empty($aiAlerts)): ?>
            <div class="msec-empty" style="color:#22c55e">All clear — no unresolved AI alerts.</div>
        <?php else: ?>
            <div class="msec-events-wrap">
                <table class="msec-tbl">
                    <thead>
                        <tr>
                            <th>Time</th>
                            <th>Type</th>
                            <th>Severity</th>
                            <th>Node</th>
                            <th>Title</th>
                            <th>Confidence</th>
                            <th>Actions</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($aiAlerts as $aa): ?>
                        <tr>
                            <td class="msec-ts"><?= UI::e($aa['created_at']) ?></td>
                            <td style="font-family:monospace;font-size:.75rem"><?= UI::e($aa['alert_type']) ?></td>
                            <td>
                                <span class="msec-sev-badge"
                                      style="background:<?= severityBadgeColour($aa['severity']) ?>22;color:<?= severityBadgeColour($aa['severity']) ?>">
                                    <?= UI::e(strtoupper($aa['severity'])) ?>
                                </span>
                            </td>
                            <td><?= UI::e($aa['source_nid'] ?: '—') ?></td>
                            <td style="max-width:280px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
                                title="<?= UI::e($aa['description']) ?>">
                                <?= UI::e($aa['title']) ?>
                            </td>
                            <td>
                                <span class="msec-ai-conf"><?= number_format((float)$aa['confidence'] * 100, 0) ?>%</span>
                            </td>
                            <td>
                                <div class="msec-ai-actions">
                                    <?php if (!(int)$aa['acknowledged']): ?>
                                        <button class="msec-ai-btn ack" data-action="ack" data-uuid="<?= UI::e($aa['alert_uuid']) ?>">ACK</button>
                                    <?php endif; ?>
                                    <?php if (!(int)$aa['resolved']): ?>
                                        <button class="msec-ai-btn res" data-action="resolve" data-uuid="<?= UI::e($aa['alert_uuid']) ?>">RESOLVE</button>
                                    <?php endif; ?>
                                </div>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>

    <!-- ════════════ BOTTOM ROW: 3 PANELS ════════════ -->
    <div class="msec-bottom-grid">

        <!-- ── Integrity Status ─────────────────────────────────── -->
        <div class="msec-card">
            <h3>Integrity Status
                <span class="msec-count"><?= $integrityPassCount + $integrityFailCount ?> checks</span>
            </h3>
            <?php
                $intTotal = $integrityPassCount + $integrityFailCount;
                $passPct  = $intTotal > 0 ? round($integrityPassCount / $intTotal * 100, 1) : 0;
                $failPct  = $intTotal > 0 ? round($integrityFailCount / $intTotal * 100, 1) : 0;
            ?>
            <div style="display:flex;justify-content:space-between;font-size:.82rem;color:rgba(255,255,255,.55);margin-bottom:2px">
                <span style="color:#22c55e">✓ <?= $integrityPassCount ?> Passed</span>
                <span style="color:#ef4444">✗ <?= $integrityFailCount ?> Failed</span>
            </div>
            <div class="msec-integrity-bar">
                <?php if ($intTotal > 0): ?>
                    <div class="pass" style="width:<?= $passPct ?>%"></div>
                    <div class="fail" style="width:<?= $failPct ?>%"></div>
                <?php endif; ?>
            </div>
            <?php if (!empty($integrityRows)): ?>
                <table class="msec-mini-tbl">
                    <thead><tr><th>Node</th><th>File</th><th>Status</th><th>Checked</th></tr></thead>
                    <tbody>
                        <?php foreach (array_slice($integrityRows, 0, 10) as $ir): ?>
                        <tr>
                            <td><?= UI::e($ir['hostname']) ?></td>
                            <td style="font-family:monospace;font-size:.72rem;max-width:140px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"
                                title="<?= UI::e($ir['file_path']) ?>">
                                <?= UI::e(basename($ir['file_path'])) ?>
                            </td>
                            <td>
                                <?php if ((int)$ir['matched']): ?>
                                    <span class="msec-verified">✓ Match</span>
                                <?php else: ?>
                                    <span class="msec-unverified">✗ Mismatch</span>
                                <?php endif; ?>
                            </td>
                            <td class="msec-ts"><?= UI::e($ir['checked_at']) ?></td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            <?php else: ?>
                <div class="msec-empty">No integrity checks recorded.</div>
            <?php endif; ?>
        </div>

        <!-- ── Key Rotations ────────────────────────────────────── -->
        <div class="msec-card">
            <h3>Key Rotations <span class="msec-count"><?= count($keyRotations) ?> recent</span></h3>
            <?php if (!empty($keyRotations)): ?>
                <table class="msec-mini-tbl">
                    <thead><tr><th>Node</th><th>Key Type</th><th>Rotated</th><th>Verified</th></tr></thead>
                    <tbody>
                        <?php foreach ($keyRotations as $kr): ?>
                        <tr>
                            <td><?= UI::e($kr['hostname']) ?></td>
                            <td style="font-family:monospace;font-size:.75rem"><?= UI::e($kr['key_type']) ?></td>
                            <td class="msec-ts"><?= UI::e($kr['rotated_at']) ?></td>
                            <td>
                                <?php if ((int)$kr['verified']): ?>
                                    <span class="msec-verified">✓</span>
                                <?php else: ?>
                                    <span class="msec-unverified">✗</span>
                                <?php endif; ?>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            <?php else: ?>
                <div class="msec-empty">No key rotations recorded.</div>
            <?php endif; ?>
        </div>

        <!-- ── Lockdown State ───────────────────────────────────── -->
        <div class="msec-card">
            <h3>Lockdown State
                <span class="msec-count"><?= count($lockdownRows) ?> active</span>
            </h3>
            <?php if (!empty($lockdownRows)): ?>
                <table class="msec-mini-tbl">
                    <thead><tr><th>Node</th><th>Level</th><th>Activated</th><th>By</th></tr></thead>
                    <tbody>
                        <?php foreach ($lockdownRows as $ld): ?>
                        <tr>
                            <td><?= UI::e($ld['hostname']) ?></td>
                            <td>
                                <span style="color:<?= (int)$ld['level'] >= 3 ? '#ef4444' : ((int)$ld['level'] >= 2 ? '#e6a817' : '#22c55e') ?>;font-weight:700">
                                    L<?= (int)$ld['level'] ?>
                                </span>
                            </td>
                            <td class="msec-ts"><?= UI::e($ld['activated_at']) ?></td>
                            <td style="font-size:.75rem"><?= UI::e($ld['activated_by'] ?? '—') ?></td>
                        </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            <?php else: ?>
                <div class="msec-empty" style="color:#22c55e">All nodes unlocked — no active lockdowns.</div>
            <?php endif; ?>
        </div>

    </div><!-- /msec-bottom-grid -->

</div><!-- /msec-wrap -->
