<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Kharma Dashboard - Live Radar</title>
    <!-- Tailwind CSS for Dark Cybersecurity Aesthetics -->
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/lucide@latest/lucide.js"></script>

    <!-- Leaflet Configuration -->
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
        integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
        integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>

    <style>
        @import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@400;700&display=swap');

        body {
            font-family: 'JetBrains Mono', monospace;
            background-color: #020617;
            /* Slate 950 */
            color: #e2e8f0;
            /* Slate 200 */
        }

        .glass-panel {
            background: rgba(15, 23, 42, 0.7);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(51, 65, 85, 0.5);
            border-radius: 0.5rem;
        }

        /* Custom Scrollbar */
        ::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }

        ::-webkit-scrollbar-track {
            background: #0f172a;
        }

        ::-webkit-scrollbar-thumb {
            background: #334155;
            border-radius: 4px;
        }

        ::-webkit-scrollbar-thumb:hover {
            background: #475569;
        }

        .blink {
            animation: blink-animation 1s steps(5, start) infinite;
            -webkit-animation: blink-animation 1s steps(5, start) infinite;
        }

        @keyframes blink-animation {
            to {
                visibility: hidden;
            }
        }

        /* Map Styling Overrides for Dark Mode */
        .leaflet-container {
            background-color: #020617;
        }

        .leaflet-layer,
        .leaflet-control-zoom-in,
        .leaflet-control-zoom-out,
        .leaflet-control-attribution {
            filter: invert(100%) hue-rotate(180deg) brightness(95%) contrast(90%);
        }
    </style>
</head>

<body class="min-h-screen p-4 flex flex-col gap-4">

    <!-- Header / Nav -->
    <header class="glass-panel p-4 flex justify-between items-center">
        <div class="flex items-center gap-3">
            <i data-lucide="radar" class="text-emerald-500 w-8 h-8"></i>
            <div>
                <h1 class="text-xl font-bold text-white tracking-widest">KHARMA<span
                        class="text-emerald-500">_RADAR</span></h1>
                <p class="text-xs text-slate-400">Live Over-Watch Network Monitor</p>
            </div>
        </div>

        <div class="flex gap-6">
            <div class="flex flex-col items-center">
                <span class="text-xs tracking-widest text-slate-400">STATUS</span>
                <span class="text-emerald-500 font-bold flex items-center gap-2">
                    <span class="w-2 h-2 rounded-full bg-emerald-500 animate-pulse"></span>
                    ONLINE
                </span>
            </div>
            <div class="flex flex-col items-center">
                <span class="text-xs tracking-widest text-slate-400">CONNECTIONS</span>
                <span id="conn-count" class="text-white font-bold">0</span>
            </div>
            <div class="flex flex-col items-center">
                <span class="text-xs tracking-widest text-slate-400">VT ENGINE</span>
                <span id="vt-status" class="text-slate-500 font-bold">-</span>
            </div>
        </div>
    </header>

    <!-- Main Grid -->
    <main class="flex-1 grid grid-cols-1 lg:grid-cols-3 gap-4 overflow-hidden">

        <!-- Radar Table Panel (Spans 2 columns) -->
        <section class="glass-panel lg:col-span-2 flex flex-col overflow-hidden h-full min-h-[500px]">
            <div class="p-4 border-b border-slate-700/50 flex justify-between items-center bg-slate-800/20">
                <h2 class="text-sm font-bold tracking-widest text-slate-300 flex items-center gap-2">
                    <i data-lucide="activity" class="w-4 h-4 text-emerald-500"></i>
                    ACTIVE CONNECTIONS
                </h2>

                <div class="flex gap-2">
                    <input type="text" id="filter-input" placeholder="Filter process..."
                        class="bg-slate-900 border border-slate-700 rounded px-3 py-1 text-sm focus:outline-none focus:border-emerald-500 transition-colors placeholder:text-slate-600">
                </div>
            </div>

            <div class="flex-1 overflow-auto">
                <table class="w-full text-left text-sm border-collapse">
                    <thead class="bg-slate-900/50 text-slate-400 sticky top-0 z-10 backdrop-blur-md">
                        <tr>
                            <th class="px-4 py-3 font-medium whitespace-nowrap">Process</th>
                            <th class="px-4 py-3 font-medium whitespace-nowrap">PID</th>
                            <th class="px-4 py-3 font-medium whitespace-nowrap">Remote Target</th>
                            <th class="px-4 py-3 font-medium whitespace-nowrap">Location</th>
                            <th class="px-4 py-3 font-medium whitespace-nowrap text-center">VT</th>
                            <th class="px-4 py-3 font-medium whitespace-nowrap">Status</th>
                            <th class="px-4 py-3 font-medium whitespace-nowrap text-right">Action</th>
                        </tr>
                    </thead>
                    <tbody id="radar-body" class="divide-y divide-slate-800/50">
                        <!-- Rows injected via JS -->
                    </tbody>
                </table>
            </div>
        </section>

        <!-- World Map Panel -->
        <section class="glass-panel flex flex-col overflow-hidden h-[400px] lg:h-full lg:col-span-1">
            <div class="p-4 border-b border-slate-700/50 bg-slate-800/20">
                <h2 class="text-sm font-bold tracking-widest text-slate-300 flex items-center gap-2">
                    <i data-lucide="globe" class="w-4 h-4 text-emerald-500"></i>
                    GLOBAL INTEL MAP
                </h2>
            </div>
            <div id="radar-map" class="flex-1 w-full bg-[#020617] relative"></div>
        </section>

    </main>

    <footer class="text-center text-xs text-slate-600 py-2">
        Kharma Radar v4.0 &copy; 2026. Built with Flask, WebSockets, and pure malice.
    </footer>

    <!-- Templates & JS -->
    <script>
        // Initialize Lucide Icons
        lucide.createIcons();

        const radarBody = document.getElementById('radar-body');
        const connCount = document.getElementById('conn-count');
        const filterInput = document.getElementById('filter-input');
        const vtStatus = document.getElementById('vt-status');

        let allConnections = [];
        let map;
        let mapMarkers = [];

        // Initialize Map
        function initMap() {
            map = L.map('radar-map').setView([20.0, 0.0], 2);
            L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
                attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
            }).addTo(map);
        }

        // Fetch Live Data
        async function fetchRadarData() {
            try {
                const response = await fetch('/api/radar');
                if (!response.ok) throw new Error('Network response was not ok');

                const json = await response.json();
                if (json.status === 'success') {
                    allConnections = json.data;
                    renderTable();
                }
            } catch (error) {
                console.error("Error fetching radar data:", error);
            }
        }

        // Render Table Rows
        function renderTable() {
            const filterTerm = filterInput.value.toLowerCase();
            let html = '';

            let displayCount = 0;
            let isVtActive = false;

            allConnections.forEach(conn => {
                // Apply Filter
                if (filterTerm && !conn.process_name.toLowerCase().includes(filterTerm) &&
                    !conn.remote_address.includes(filterTerm) && !conn.location.toLowerCase().includes(filterTerm)) {
                    return;
                }

                displayCount++;

                // Styling logic based on Threat Intel & VT
                let rowStyle = "hover:bg-slate-800/30 transition-colors";
                let processClass = "text-emerald-400 font-bold";
                let statusBadge = `<span class="px-2 py-1 rounded bg-slate-800 text-slate-300 border border-slate-700">${conn.status}</span>`;
                let vtScoreHtml = `<span class="text-slate-600">-</span>`;

                if (conn.vt_total > -1) {
                    isVtActive = true;
                    if (conn.vt_malicious > 0) {
                        vtScoreHtml = `<span class="text-red-400 font-bold blink">${conn.vt_malicious}/${conn.vt_total}</span>`;
                    } else {
                        vtScoreHtml = `<span class="text-emerald-400">0/${conn.vt_total}</span>`;
                    }
                } else if (conn.vt_total === -1 && conn.exe === '') {
                    vtScoreHtml = `<span class="text-slate-600">Denied</span>`;
                }

                if (conn.is_malware) {
                    rowStyle = "bg-red-950/20 hover:bg-red-950/40 border-l-[3px] border-red-500 transition-colors";
                    processClass = "text-red-500 font-bold blink";
                    statusBadge = `<span class="px-2 py-1 rounded bg-red-900/50 text-red-400 border border-red-700/50 blink shadow-[0_0_10px_rgba(239,68,68,0.5)]">BREACHED</span>`;
                } else if (conn.status === 'AUTO-KILLED') {
                    rowStyle = "opacity-50 line-through bg-slate-900";
                    statusBadge = `<span class="px-2 py-1 rounded bg-slate-800 text-slate-400 border border-slate-700">AUTO-KILLED</span>`;
                }

                html += `
                    <tr class="${rowStyle}">
                        <td class="px-4 py-3 ${processClass}">${conn.process_name}</td>
                        <td class="px-4 py-3 text-slate-400">${conn.pid}</td>
                        <td class="px-4 py-3 font-mono ${conn.is_malware ? 'text-red-400' : 'text-slate-300'}">${conn.remote_address}</td>
                        <td class="px-4 py-3">
                            <div class="flex items-center gap-2 text-xs">
                                <span class="text-slate-300 truncate max-w-[150px]" title="${conn.location}">${conn.location}</span>
                            </div>
                        </td>
                        <td class="px-4 py-3 text-center bg-black/20">${vtScoreHtml}</td>
                        <td class="px-4 py-3">${statusBadge}</td>
                        <td class="px-4 py-3 text-right">
                            <button onclick="killProcess(${conn.pid})" 
                                    class="p-1.5 rounded hover:bg-red-500/20 text-slate-500 hover:text-red-400 transition-colors focus:outline-none"
                                    title="Kill PID ${conn.pid}">
                                <i data-lucide="skull" class="w-4 h-4"></i>
                            </button>
                        </td>
                    </tr>
                `;
            });

            radarBody.innerHTML = html;
            connCount.innerText = displayCount;

            // Re-bind icons for dynamic content
            lucide.createIcons();

            updateMapMarkers();

            // Update VT Banner
            if (isVtActive) {
                vtStatus.innerText = "ONLINE";
                vtStatus.className = "text-emerald-500 font-bold";
            } else {
                vtStatus.innerText = "OFFLINE";
                vtStatus.className = "text-yellow-500 font-bold";
            }
        }

        function updateMapMarkers() {
            // Clear existing markers
            mapMarkers.forEach(marker => map.removeLayer(marker));
            mapMarkers = [];

            const filterTerm = filterInput.value.toLowerCase();

            // Define custom marker styling
            const normalIcon = L.divIcon({
                className: 'custom-icon',
                html: '<div style="background-color: #10b981; width: 12px; height: 12px; border-radius: 50%; border: 2px solid #020617; box-shadow: 0 0 10px rgba(16,185,129,0.8);"></div>',
                iconSize: [12, 12]
            });
            const threatIcon = L.divIcon({
                className: 'custom-icon blink',
                html: '<div style="background-color: #ef4444; width: 16px; height: 16px; border-radius: 50%; border: 2px solid #020617; box-shadow: 0 0 15px rgba(239,68,68,1);"></div>',
                iconSize: [16, 16]
            });

            allConnections.forEach(conn => {
                if (filterTerm && !conn.process_name.toLowerCase().includes(filterTerm) &&
                    !conn.remote_address.includes(filterTerm) && !conn.location.toLowerCase().includes(filterTerm)) {
                    return;
                }

                if (conn.lat && conn.lon) {
                    const icon = conn.is_malware ? threatIcon : normalIcon;
                    const marker = L.marker([conn.lat, conn.lon], { icon: icon })
                        .bindPopup(`<b>${conn.process_name}</b><br>${conn.remote_address}<br>${conn.location}`)
                        .addTo(map);
                    mapMarkers.push(marker);
                }
            });
        }

        // Active Defense API
        async function killProcess(pid) {
            if (!confirm(`Engage Active Defense?\n\nTerminate process PID ${pid} permanently?`)) return;

            try {
                const response = await fetch(`/api/kill/${pid}`, { method: 'DELETE' });
                const json = await response.json();

                if (json.status === 'success') {
                    alert(`✅ ${json.message}`);
                    fetchRadarData(); // Force refresh
                } else {
                    alert(`❌ Failed: ${json.message}`);
                }
            } catch (error) {
                alert(`❌ API Error: ${error}`);
            }
        }

        // Event Listeners
        filterInput.addEventListener('input', renderTable);

        // Core Loop: Poll API every 2 seconds
        setInterval(fetchRadarData, 2000);

        // Initial Fetch & Map Init
        initMap();
        fetchRadarData();
    </script>
</body>

</html>