<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>AIRCRAFT RADAR // INTERCEPT</title>
    <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;500;700;900&family=Rajdhani:wght@300;400;500;600;700&family=JetBrains+Mono:wght@300;400;500&display=swap" rel="stylesheet">
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        :root {
            --bg-dark: #0a0a0f;
            --bg-panel: #0d1117;
            --bg-card: #161b22;
            --border-glow: #00ff88;
            --text-primary: #e6edf3;
            --text-secondary: #8b949e;
            --accent-green: #00ff88;
            --accent-cyan: #00d4ff;
            --accent-orange: #ff9500;
            --accent-red: #ff4444;
            --accent-yellow: #ffcc00;
            --grid-line: rgba(0, 255, 136, 0.1);
            --radar-cyan: #00ffff;
            --radar-bg: #1a1a2e;
        }

        body {
            font-family: 'Rajdhani', sans-serif;
            background: var(--bg-dark);
            color: var(--text-primary);
            min-height: 100vh;
            overflow-x: hidden;
        }

        /* Animated radar sweep background */
        .radar-bg {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background-image:
                linear-gradient(var(--grid-line) 1px, transparent 1px),
                linear-gradient(90deg, var(--grid-line) 1px, transparent 1px);
            background-size: 50px 50px;
            pointer-events: none;
            z-index: 0;
        }

        /* Scan line effect */
        .scanline {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            height: 4px;
            background: linear-gradient(90deg, transparent, var(--accent-green), transparent);
            animation: scan 4s linear infinite;
            pointer-events: none;
            z-index: 1000;
            opacity: 0.5;
        }

        @keyframes scan {
            0% { top: -4px; }
            100% { top: 100vh; }
        }

        /* Header */
        .header {
            position: relative;
            z-index: 10;
            padding: 12px 20px;
            background: linear-gradient(180deg, rgba(0,255,136,0.1) 0%, transparent 100%);
            border-bottom: 1px solid rgba(0,255,136,0.3);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .logo {
            font-family: 'Orbitron', monospace;
            font-size: 24px;
            font-weight: 900;
            letter-spacing: 4px;
            color: var(--accent-green);
            text-shadow: 0 0 20px var(--accent-green), 0 0 40px var(--accent-green);
        }

        .logo span {
            color: var(--text-secondary);
            font-weight: 400;
            font-size: 14px;
            margin-left: 15px;
            letter-spacing: 2px;
        }

        .status-bar {
            display: flex;
            gap: 20px;
            align-items: center;
            font-family: 'JetBrains Mono', monospace;
            font-size: 11px;
        }

        .status-item {
            display: flex;
            align-items: center;
            gap: 6px;
        }

        .status-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: var(--accent-green);
            box-shadow: 0 0 10px var(--accent-green);
            animation: pulse 2s ease-in-out infinite;
        }

        .status-dot.inactive {
            background: var(--accent-red);
            box-shadow: 0 0 10px var(--accent-red);
        }

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

        /* Stats badges in header */
        .stats-badges {
            display: flex;
            gap: 12px;
        }

        .stat-badge {
            background: rgba(0,255,136,0.1);
            border: 1px solid rgba(0,255,136,0.3);
            border-radius: 4px;
            padding: 4px 10px;
            font-family: 'JetBrains Mono', monospace;
            font-size: 11px;
        }

        .stat-badge .value {
            color: var(--accent-green);
            font-weight: 600;
        }

        .stat-badge .label {
            color: var(--text-secondary);
            margin-left: 4px;
        }

        .datetime {
            font-family: 'Orbitron', monospace;
            font-size: 12px;
            color: var(--accent-green);
        }

        .back-link {
            color: var(--accent-green);
            text-decoration: none;
            font-size: 11px;
            padding: 4px 10px;
            border: 1px solid var(--accent-green);
            border-radius: 4px;
        }

        /* Main dashboard grid */
        .dashboard {
            position: relative;
            z-index: 10;
            display: grid;
            grid-template-columns: 1fr 340px;
            grid-template-rows: 1fr auto;
            gap: 0;
            height: calc(100vh - 60px);
            min-height: 500px;
        }

        /* Panels */
        .panel {
            background: var(--bg-panel);
            border: 1px solid rgba(0,255,136,0.2);
            overflow: hidden;
            position: relative;
        }

        .panel::before {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            height: 2px;
            background: linear-gradient(90deg, transparent, var(--accent-green), transparent);
        }

        .panel-header {
            padding: 10px 15px;
            background: rgba(0,255,136,0.05);
            border-bottom: 1px solid rgba(0,255,136,0.1);
            font-family: 'Orbitron', monospace;
            font-size: 11px;
            font-weight: 500;
            letter-spacing: 2px;
            text-transform: uppercase;
            color: var(--accent-green);
            display: flex;
            justify-content: space-between;
            align-items: center;
        }

        .panel-indicator {
            width: 6px;
            height: 6px;
            background: var(--accent-green);
            border-radius: 50%;
            animation: blink 1s ease-in-out infinite;
        }

        @keyframes blink {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.3; }
        }

        @keyframes slideDown {
            from { opacity: 0; transform: translateX(-50%) translateY(-20px); }
            to { opacity: 1; transform: translateX(-50%) translateY(0); }
        }

        /* Main display container (map + radar scope) */
        .main-display {
            grid-column: 1;
            grid-row: 1;
            position: relative;
        }

        .display-container {
            position: relative;
            width: 100%;
            height: 100%;
        }

        #radarMap {
            width: 100%;
            height: 100%;
            display: block;
        }

        #radarScope {
            position: absolute;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            display: none;
            background: var(--radar-bg);
        }

        #radarScope.active {
            display: flex;
            justify-content: center;
            align-items: center;
        }

        #radarCanvas {
            max-width: 100%;
            max-height: 100%;
        }

        /* Right sidebar */
        .sidebar {
            grid-column: 2;
            grid-row: 1;
            display: flex;
            flex-direction: column;
            border-left: 1px solid rgba(0,255,136,0.2);
            overflow: hidden;
        }

        /* View toggle */
        .view-toggle {
            display: flex;
            padding: 10px;
            gap: 8px;
            background: var(--bg-panel);
            border-bottom: 1px solid rgba(0,255,136,0.2);
        }

        .view-btn {
            flex: 1;
            padding: 10px;
            border: 1px solid rgba(0,255,136,0.3);
            background: transparent;
            color: var(--text-secondary);
            font-family: 'Orbitron', monospace;
            font-size: 11px;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 2px;
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .view-btn:hover {
            border-color: var(--accent-green);
            color: var(--accent-green);
        }

        .view-btn.active {
            background: var(--accent-green);
            border-color: var(--accent-green);
            color: var(--bg-dark);
        }

        /* Selected aircraft panel */
        .selected-aircraft {
            flex-shrink: 0;
            max-height: 280px;
            overflow-y: auto;
        }

        .selected-info {
            padding: 12px;
        }

        .selected-callsign {
            font-family: 'Orbitron', monospace;
            font-size: 20px;
            font-weight: 700;
            color: var(--accent-green);
            text-shadow: 0 0 15px var(--accent-green);
            text-align: center;
            margin-bottom: 12px;
        }

        .telemetry-grid {
            display: grid;
            grid-template-columns: repeat(2, 1fr);
            gap: 6px;
        }

        .telemetry-item {
            background: rgba(0,0,0,0.3);
            border-radius: 4px;
            padding: 8px;
            border-left: 2px solid var(--accent-green);
        }

        .telemetry-label {
            font-size: 9px;
            text-transform: uppercase;
            letter-spacing: 1px;
            color: var(--text-secondary);
            margin-bottom: 2px;
        }

        .telemetry-value {
            font-family: 'JetBrains Mono', monospace;
            font-size: 12px;
            color: var(--accent-cyan);
        }

        /* Aircraft list */
        .aircraft-list {
            flex: 1;
            min-height: 0;
            display: flex;
            flex-direction: column;
        }

        .aircraft-list-content {
            flex: 1;
            overflow-y: auto;
            padding: 8px;
        }

        .aircraft-item {
            background: rgba(0,0,0,0.3);
            border: 1px solid rgba(0,255,136,0.15);
            border-radius: 4px;
            padding: 8px 10px;
            margin-bottom: 6px;
            cursor: pointer;
            transition: all 0.2s ease;
        }

        .aircraft-item:hover {
            border-color: var(--accent-green);
            background: rgba(0,255,136,0.05);
        }

        .aircraft-item.selected {
            border-color: var(--accent-green);
            box-shadow: 0 0 15px rgba(0,255,136,0.2);
            background: rgba(0,255,136,0.1);
        }

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

        .aircraft-callsign {
            font-family: 'Orbitron', monospace;
            font-size: 12px;
            font-weight: 600;
            color: var(--accent-green);
        }

        .aircraft-icao {
            font-family: 'JetBrains Mono', monospace;
            font-size: 9px;
            color: var(--text-secondary);
            background: rgba(0,255,136,0.1);
            padding: 2px 5px;
            border-radius: 3px;
        }

        .aircraft-details {
            display: grid;
            grid-template-columns: repeat(3, 1fr);
            gap: 6px;
            font-size: 10px;
        }

        .aircraft-detail {
            text-align: center;
        }

        .aircraft-detail-value {
            font-family: 'JetBrains Mono', monospace;
            color: var(--accent-cyan);
            font-size: 11px;
        }

        .aircraft-detail-label {
            color: var(--text-secondary);
            font-size: 8px;
            text-transform: uppercase;
        }

        /* Bottom controls bar */
        .controls-bar {
            grid-column: 1 / -1;
            grid-row: 2;
            display: flex;
            align-items: center;
            gap: 20px;
            padding: 10px 20px;
            background: var(--bg-panel);
            border-top: 1px solid rgba(0,255,136,0.3);
        }

        .control-group {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .control-group label {
            display: flex;
            align-items: center;
            gap: 6px;
            cursor: pointer;
            font-size: 11px;
            color: var(--text-primary);
        }

        .control-group input[type="checkbox"] {
            accent-color: var(--accent-green);
        }

        .control-group select {
            padding: 6px 10px;
            background: rgba(0,0,0,0.3);
            border: 1px solid rgba(0,255,136,0.3);
            border-radius: 4px;
            color: var(--accent-green);
            font-family: 'JetBrains Mono', monospace;
            font-size: 11px;
        }

        .control-group input[type="text"] {
            width: 80px;
            padding: 6px 8px;
            background: rgba(0,0,0,0.3);
            border: 1px solid rgba(0,255,136,0.3);
            border-radius: 4px;
            color: var(--accent-green);
            font-family: 'JetBrains Mono', monospace;
            font-size: 11px;
        }

        .control-label {
            font-size: 10px;
            text-transform: uppercase;
            letter-spacing: 1px;
            color: var(--text-secondary);
        }

        /* Start/stop button */
        .start-btn {
            padding: 8px 20px;
            border: 1px solid var(--accent-green);
            background: rgba(0,255,136,0.1);
            color: var(--accent-green);
            font-family: 'Orbitron', monospace;
            font-size: 11px;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 2px;
            border-radius: 4px;
            cursor: pointer;
            transition: all 0.2s ease;
            margin-left: auto;
        }

        .start-btn:hover {
            background: var(--accent-green);
            color: var(--bg-dark);
            box-shadow: 0 0 20px rgba(0,255,136,0.3);
        }

        .start-btn.active {
            background: var(--accent-red);
            border-color: var(--accent-red);
            color: #fff;
        }

        .start-btn.active:hover {
            box-shadow: 0 0 20px rgba(255,68,68,0.3);
        }

        /* GPS button */
        .gps-btn {
            padding: 6px 10px;
            background: rgba(0,255,136,0.2);
            border: 1px solid rgba(0,255,136,0.3);
            border-radius: 4px;
            color: var(--accent-green);
            font-family: 'JetBrains Mono', monospace;
            font-size: 10px;
            cursor: pointer;
        }

        /* Leaflet overrides */
        .leaflet-container {
            background: var(--bg-dark) !important;
        }

        .leaflet-control-zoom a {
            background: var(--bg-panel) !important;
            color: var(--accent-green) !important;
            border-color: rgba(0,255,136,0.3) !important;
        }

        .leaflet-control-attribution {
            background: rgba(0,0,0,0.7) !important;
            color: var(--text-secondary) !important;
            font-size: 9px !important;
        }

        /* Custom scrollbar */
        ::-webkit-scrollbar {
            width: 6px;
        }

        ::-webkit-scrollbar-track {
            background: var(--bg-dark);
        }

        ::-webkit-scrollbar-thumb {
            background: var(--accent-green);
            border-radius: 3px;
        }

        /* No aircraft message */
        .no-aircraft {
            text-align: center;
            padding: 30px 15px;
            color: var(--text-secondary);
        }

        .no-aircraft-icon {
            font-size: 36px;
            margin-bottom: 10px;
            opacity: 0.5;
        }

        /* Responsive */
        @media (max-width: 1000px) {
            .dashboard {
                grid-template-columns: 1fr;
                grid-template-rows: 1fr auto auto;
            }
            .main-display {
                min-height: 400px;
            }
            .sidebar {
                grid-column: 1;
                grid-row: 2;
                border-left: none;
                border-top: 1px solid rgba(0,255,136,0.2);
                max-height: 300px;
            }
            .controls-bar {
                grid-row: 3;
                flex-wrap: wrap;
            }
        }
    </style>
</head>
<body>
    <div class="radar-bg"></div>
    <div class="scanline"></div>

    <header class="header">
        <div class="logo">
            AIRCRAFT RADAR
            <span>// INTERCEPT</span>
        </div>
        <div class="stats-badges">
            <div class="stat-badge">
                <span class="value" id="statTotal">0</span>
                <span class="label">aircraft</span>
            </div>
            <div class="stat-badge">
                <span class="value" id="statMaxRange">0</span>
                <span class="label">nm max</span>
            </div>
            <div class="stat-badge">
                <span class="value" id="statMsgRate">0</span>
                <span class="label">msg/s</span>
            </div>
        </div>
        <div class="status-bar">
            <div class="status-item">
                <div class="status-dot inactive" id="trackingDot"></div>
                <span id="trackingStatus">STANDBY</span>
            </div>
            <div class="datetime" id="utcTime">--:--:-- UTC</div>
            <a href="/?mode=aircraft" class="back-link">Main Dashboard</a>
        </div>
    </header>

    <main class="dashboard">
        <!-- Main Display (Map or Radar Scope) -->
        <div class="main-display">
            <div class="display-container">
                <div id="radarMap"></div>
                <div id="radarScope">
                    <canvas id="radarCanvas"></canvas>
                </div>
            </div>
        </div>

        <!-- Sidebar -->
        <div class="sidebar">
            <!-- View Toggle -->
            <div class="view-toggle">
                <button class="view-btn active" id="mapViewBtn" onclick="setView('map')">MAP</button>
                <button class="view-btn" id="radarViewBtn" onclick="setView('radar')">RADAR</button>
            </div>

            <!-- Selected Aircraft -->
            <div class="panel selected-aircraft">
                <div class="panel-header">
                    <span>SELECTED TARGET</span>
                    <div class="panel-indicator"></div>
                </div>
                <div class="selected-info" id="selectedInfo">
                    <div class="no-aircraft">
                        <div class="no-aircraft-icon">&#9992;</div>
                        <div>Select an aircraft</div>
                    </div>
                </div>
            </div>

            <!-- Aircraft List -->
            <div class="panel aircraft-list">
                <div class="panel-header">
                    <span>TRACKED AIRCRAFT</span>
                    <div class="panel-indicator"></div>
                </div>
                <div class="aircraft-list-content" id="aircraftList">
                    <div class="no-aircraft">
                        <div>No aircraft detected</div>
                        <div style="font-size: 10px; margin-top: 5px;">Start tracking to begin</div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Controls Bar -->
        <div class="controls-bar">
            <div class="control-group">
                <label>
                    <input type="checkbox" id="showTrails" onchange="toggleTrails()">
                    Trails
                </label>
            </div>
            <div class="control-group">
                <label>
                    <input type="checkbox" id="showRangeRings" onchange="drawRangeRings()">
                    Range Rings
                </label>
            </div>
            <div class="control-group">
                <label>
                    <input type="checkbox" id="alertToggle" checked onchange="toggleAlerts()">
                    Alerts
                </label>
            </div>
            <div class="control-group">
                <span class="control-label">Filter:</span>
                <select id="aircraftFilter" onchange="applyFilter()">
                    <option value="all">All</option>
                    <option value="military">Military</option>
                    <option value="civil">Civil</option>
                    <option value="emergency">Emergency</option>
                </select>
            </div>
            <div class="control-group">
                <span class="control-label">Range:</span>
                <select id="rangeSelect" onchange="updateRange()">
                    <option value="50">50 nm</option>
                    <option value="100">100 nm</option>
                    <option value="200" selected>200 nm</option>
                    <option value="300">300 nm</option>
                </select>
            </div>
            <div class="control-group">
                <span class="control-label">Lat:</span>
                <input type="text" id="obsLat" value="51.5074" onchange="updateObserverLoc()">
            </div>
            <div class="control-group">
                <span class="control-label">Lon:</span>
                <input type="text" id="obsLon" value="-0.1278" onchange="updateObserverLoc()">
            </div>
            <div class="control-group">
                <select id="gpsSource" onchange="toggleGpsDongleControls()" style="font-size: 10px;">
                    <option value="manual">Manual</option>
                    <option value="browser">Browser</option>
                    <option value="dongle">USB GPS</option>
                </select>
            </div>
            <div class="control-group" id="browserGpsGroup">
                <button class="gps-btn" id="geolocateBtn" onclick="getGeolocation()">Locate</button>
            </div>
            <div class="control-group gps-dongle-controls" style="display: none;">
                <select class="gps-device-select" id="gpsDeviceSelect" style="font-size: 10px; max-width: 120px;">
                    <option value="">GPS Device...</option>
                </select>
                <select id="gpsBaudrateSelect" style="font-size: 10px; width: 65px;">
                    <option value="4800">4800</option>
                    <option value="9600" selected>9600</option>
                    <option value="38400">38400</option>
                    <option value="115200">115200</option>
                </select>
                <button class="gps-btn gps-connect-btn" onclick="startGpsDongle()">Connect</button>
                <button class="gps-btn gps-disconnect-btn" onclick="stopGpsDongle()" style="display: none; background: rgba(255,0,0,0.2); border-color: #ff4444;">Stop</button>
            </div>
            <button class="start-btn" id="startBtn" onclick="toggleTracking()">START</button>
        </div>
    </main>

    <script>
        // ============================================
        // STATE
        // ============================================
        let radarMap = null;
        let aircraft = {};
        let markers = {};
        let selectedIcao = null;
        let eventSource = null;
        let isTracking = false;
        let currentFilter = 'all';
        let alertedAircraft = {};
        let alertsEnabled = true;
        let currentView = 'map';  // 'map' or 'radar'

        // Aircraft trails
        let aircraftTrails = {};  // ICAO -> [{lat, lon, alt, time}, ...]
        let trailLines = {};      // ICAO -> L.polyline (array of segments)
        let showTrails = false;
        const MAX_TRAIL_POINTS = 100;

        // Radar scope
        let radarScope = null;
        let radarAnimationId = null;
        let maxRange = 200;  // nautical miles

        // Statistics
        let stats = {
            totalAircraftSeen: new Set(),
            maxRange: 0,
            messagesPerSecond: 0,
            messageTimestamps: []
        };

        // Observer location and range rings
        let observerLocation = { lat: 51.5074, lon: -0.1278 };
        let rangeRingsLayer = null;
        let observerMarker = null;

        // GPS Dongle state
        let gpsDevices = [];
        let gpsConnected = false;
        let gpsEventSource = null;

        // ============================================
        // AUDIO ALERTS
        // ============================================
        let audioContext = null;
        function getAudioContext() {
            if (!audioContext) {
                audioContext = new (window.AudioContext || window.webkitAudioContext)();
            }
            return audioContext;
        }

        function playAlertSound(type) {
            if (!alertsEnabled) return;
            try {
                const ctx = getAudioContext();
                const oscillator = ctx.createOscillator();
                const gainNode = ctx.createGain();
                oscillator.connect(gainNode);
                gainNode.connect(ctx.destination);

                if (type === 'emergency') {
                    oscillator.frequency.setValueAtTime(880, ctx.currentTime);
                    oscillator.frequency.setValueAtTime(660, ctx.currentTime + 0.15);
                    oscillator.frequency.setValueAtTime(880, ctx.currentTime + 0.3);
                    gainNode.gain.setValueAtTime(0.3, ctx.currentTime);
                    gainNode.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.5);
                    oscillator.start(ctx.currentTime);
                    oscillator.stop(ctx.currentTime + 0.5);
                } else if (type === 'military') {
                    oscillator.frequency.setValueAtTime(523, ctx.currentTime);
                    gainNode.gain.setValueAtTime(0.2, ctx.currentTime);
                    gainNode.gain.exponentialRampToValueAtTime(0.01, ctx.currentTime + 0.3);
                    oscillator.start(ctx.currentTime);
                    oscillator.stop(ctx.currentTime + 0.3);
                }
            } catch (e) {
                console.warn('Audio alert failed:', e);
            }
        }

        function checkAndAlertAircraft(icao, ac) {
            if (alertedAircraft[icao]) return;
            const militaryInfo = isMilitaryAircraft(icao, ac.callsign);
            const squawkInfo = checkSquawkCode(ac);

            if (squawkInfo) {
                alertedAircraft[icao] = 'emergency';
                playAlertSound('emergency');
                showAlertBanner(`EMERGENCY: ${squawkInfo.name} - ${ac.callsign || icao}`, '#ff0000');
            } else if (militaryInfo.military) {
                alertedAircraft[icao] = 'military';
                playAlertSound('military');
                showAlertBanner(`MILITARY: ${ac.callsign || icao}${militaryInfo.country ? ' (' + militaryInfo.country + ')' : ''}`, '#556b2f');
            }
        }

        function showAlertBanner(message, color) {
            const banner = document.createElement('div');
            banner.style.cssText = `
                position: fixed; top: 70px; left: 50%; transform: translateX(-50%);
                background: ${color}; color: white; padding: 10px 20px; border-radius: 6px;
                font-weight: bold; font-size: 13px; z-index: 10000;
                box-shadow: 0 4px 20px rgba(0,0,0,0.5); animation: slideDown 0.3s ease-out;
            `;
            banner.textContent = message;
            document.body.appendChild(banner);
            setTimeout(() => {
                banner.style.opacity = '0';
                banner.style.transition = 'opacity 0.3s';
                setTimeout(() => banner.remove(), 300);
            }, 5000);
        }

        function toggleAlerts() {
            alertsEnabled = document.getElementById('alertToggle').checked;
        }

        // ============================================
        // MILITARY/EMERGENCY DETECTION
        // ============================================
        const MILITARY_RANGES = [
            { start: 0xADF7C0, end: 0xADFFFF, country: 'US' },
            { start: 0xAE0000, end: 0xAEFFFF, country: 'US' },
            { start: 0x3F4000, end: 0x3F7FFF, country: 'FR' },
            { start: 0x43C000, end: 0x43CFFF, country: 'UK' },
            { start: 0x3D0000, end: 0x3DFFFF, country: 'DE' },
            { start: 0x501C00, end: 0x501FFF, country: 'NATO' },
        ];

        const MILITARY_PREFIXES = [
            'REACH', 'JAKE', 'DOOM', 'IRON', 'HAWK', 'VIPER', 'COBRA', 'THUNDER',
            'SHADOW', 'NIGHT', 'STEEL', 'GRIM', 'REAPER', 'BLADE', 'STRIKE',
            'RCH', 'CNV', 'MCH', 'EVAC', 'TOPCAT', 'ASCOT', 'RRR', 'HRK',
            'NAVY', 'ARMY', 'USAF', 'RAF', 'RCAF', 'RAAF', 'IAF', 'PAF'
        ];

        const SQUAWK_CODES = {
            '7500': { type: 'hijack', name: 'HIJACK' },
            '7600': { type: 'radio', name: 'RADIO FAILURE' },
            '7700': { type: 'mayday', name: 'EMERGENCY' }
        };

        function isMilitaryAircraft(icao, callsign) {
            const icaoNum = parseInt(icao, 16);
            for (const range of MILITARY_RANGES) {
                if (icaoNum >= range.start && icaoNum <= range.end) {
                    return { military: true, country: range.country };
                }
            }
            if (callsign) {
                const upper = callsign.toUpperCase();
                for (const prefix of MILITARY_PREFIXES) {
                    if (upper.startsWith(prefix)) {
                        return { military: true, type: 'callsign' };
                    }
                }
            }
            return { military: false };
        }

        function checkSquawkCode(aircraft) {
            if (aircraft.squawk && SQUAWK_CODES[aircraft.squawk]) {
                return SQUAWK_CODES[aircraft.squawk];
            }
            return null;
        }

        // ============================================
        // DISTANCE/BEARING CALCULATIONS
        // ============================================
        function calculateDistanceNm(lat1, lon1, lat2, lon2) {
            const R = 3440.065;
            const dLat = (lat2 - lat1) * Math.PI / 180;
            const dLon = (lon2 - lon1) * Math.PI / 180;
            const a = Math.sin(dLat/2) * Math.sin(dLat/2) +
                      Math.cos(lat1 * Math.PI / 180) * Math.cos(lat2 * Math.PI / 180) *
                      Math.sin(dLon/2) * Math.sin(dLon/2);
            const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
            return R * c;
        }

        function calculateBearing(lat1, lon1, lat2, lon2) {
            const dLon = (lon2 - lon1) * Math.PI / 180;
            const lat1Rad = lat1 * Math.PI / 180;
            const lat2Rad = lat2 * Math.PI / 180;
            const y = Math.sin(dLon) * Math.cos(lat2Rad);
            const x = Math.cos(lat1Rad) * Math.sin(lat2Rad) -
                      Math.sin(lat1Rad) * Math.cos(lat2Rad) * Math.cos(dLon);
            let bearing = Math.atan2(y, x) * 180 / Math.PI;
            return (bearing + 360) % 360;
        }

        // ============================================
        // STATISTICS
        // ============================================
        function updateStatistics(icao, ac) {
            if (!ac.lat || !ac.lon) return;
            stats.totalAircraftSeen.add(icao);

            const distance = calculateDistanceNm(
                observerLocation.lat, observerLocation.lon,
                ac.lat, ac.lon
            );

            if (distance > stats.maxRange) {
                stats.maxRange = distance;
            }

            const now = Date.now();
            stats.messageTimestamps.push(now);
            stats.messageTimestamps = stats.messageTimestamps.filter(t => now - t < 5000);
            stats.messagesPerSecond = stats.messageTimestamps.length / 5;

            updateStatsDisplay();
        }

        function updateStatsDisplay() {
            document.getElementById('statMaxRange').textContent = stats.maxRange.toFixed(0);
            document.getElementById('statMsgRate').textContent = stats.messagesPerSecond.toFixed(1);
            document.getElementById('statTotal').textContent = Object.keys(aircraft).length;
        }

        // ============================================
        // AIRCRAFT TRAILS
        // ============================================
        function toggleTrails() {
            showTrails = document.getElementById('showTrails').checked;
            if (!showTrails) {
                // Remove all trail lines from map
                Object.keys(trailLines).forEach(icao => {
                    if (trailLines[icao]) {
                        trailLines[icao].forEach(line => radarMap.removeLayer(line));
                        delete trailLines[icao];
                    }
                });
            } else {
                // Draw existing trails
                Object.keys(aircraftTrails).forEach(icao => {
                    updateTrailLine(icao);
                });
            }
        }

        function recordTrailPoint(icao, lat, lon, alt) {
            if (!aircraftTrails[icao]) aircraftTrails[icao] = [];
            const trail = aircraftTrails[icao];

            // Only add if moved significantly
            if (trail.length === 0 ||
                Math.abs(trail[trail.length-1].lat - lat) > 0.0005 ||
                Math.abs(trail[trail.length-1].lon - lon) > 0.0005) {
                trail.push({ lat, lon, alt: alt || 0, time: Date.now() });
                if (trail.length > MAX_TRAIL_POINTS) trail.shift();
            }
        }

        function getAltitudeColor(alt) {
            if (!alt || alt <= 0) return '#888888';
            if (alt < 10000) return '#00ff88';   // Green - low
            if (alt < 25000) return '#00d4ff';   // Cyan - medium
            if (alt < 35000) return '#ffcc00';   // Yellow - high
            return '#ff9500';                    // Orange - very high
        }

        function updateTrailLine(icao) {
            if (!showTrails || !radarMap) return;

            const trail = aircraftTrails[icao];
            if (!trail || trail.length < 2) return;

            // Remove old trail lines
            if (trailLines[icao]) {
                trailLines[icao].forEach(line => radarMap.removeLayer(line));
            }
            trailLines[icao] = [];

            // Create gradient segments
            const now = Date.now();
            for (let i = 1; i < trail.length; i++) {
                const p1 = trail[i-1];
                const p2 = trail[i];
                const age = (now - p2.time) / 1000;  // seconds
                const opacity = Math.max(0.2, 1 - (age / 120));  // Fade over 2 minutes

                const color = getAltitudeColor(p2.alt);
                const line = L.polyline([[p1.lat, p1.lon], [p2.lat, p2.lon]], {
                    color: color,
                    weight: 2,
                    opacity: opacity
                }).addTo(radarMap);
                trailLines[icao].push(line);
            }
        }

        function cleanupTrail(icao) {
            if (trailLines[icao]) {
                trailLines[icao].forEach(line => radarMap.removeLayer(line));
                delete trailLines[icao];
            }
            delete aircraftTrails[icao];
        }

        // ============================================
        // RADAR SCOPE (PPI)
        // ============================================
        class RadarScope {
            constructor(canvasId) {
                this.canvas = document.getElementById(canvasId);
                this.ctx = this.canvas.getContext('2d');
                this.sweepAngle = 0;
                this.blips = [];  // Aircraft blips with afterglow
                this.resize();
                window.addEventListener('resize', () => this.resize());
            }

            resize() {
                const container = this.canvas.parentElement;
                const size = Math.min(container.clientWidth, container.clientHeight) - 40;
                this.canvas.width = size;
                this.canvas.height = size;
                this.centerX = size / 2;
                this.centerY = size / 2;
                this.radius = (size / 2) - 30;
            }

            draw() {
                const ctx = this.ctx;
                const w = this.canvas.width;
                const h = this.canvas.height;

                // Clear
                ctx.fillStyle = '#1a1a2e';
                ctx.fillRect(0, 0, w, h);

                // Draw range rings
                this.drawRangeRings();

                // Draw compass rose
                this.drawCompassRose();

                // Draw aircraft blips
                this.drawBlips();

                // Draw sweep line
                this.drawSweep();

                // Draw center point (observer)
                ctx.beginPath();
                ctx.arc(this.centerX, this.centerY, 4, 0, Math.PI * 2);
                ctx.fillStyle = '#ffff00';
                ctx.fill();
            }

            drawRangeRings() {
                const ctx = this.ctx;
                const rings = [0.25, 0.5, 0.75, 1.0];

                ctx.strokeStyle = 'rgba(0, 255, 255, 0.2)';
                ctx.lineWidth = 1;

                rings.forEach((ratio, i) => {
                    const r = this.radius * ratio;
                    ctx.beginPath();
                    ctx.arc(this.centerX, this.centerY, r, 0, Math.PI * 2);
                    ctx.stroke();

                    // Range label
                    const rangeNm = Math.round(maxRange * ratio);
                    ctx.fillStyle = 'rgba(0, 255, 255, 0.5)';
                    ctx.font = '10px JetBrains Mono';
                    ctx.fillText(`${rangeNm}`, this.centerX + r + 5, this.centerY + 4);
                });
            }

            drawCompassRose() {
                const ctx = this.ctx;
                const directions = [
                    { angle: 0, label: 'N' },
                    { angle: 90, label: 'E' },
                    { angle: 180, label: 'S' },
                    { angle: 270, label: 'W' }
                ];

                ctx.fillStyle = '#00ffff';
                ctx.font = 'bold 12px Orbitron';
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';

                directions.forEach(d => {
                    const rad = (d.angle - 90) * Math.PI / 180;
                    const x = this.centerX + (this.radius + 15) * Math.cos(rad);
                    const y = this.centerY + (this.radius + 15) * Math.sin(rad);
                    ctx.fillText(d.label, x, y);
                });

                // Draw tick marks every 30 degrees
                ctx.strokeStyle = 'rgba(0, 255, 255, 0.3)';
                ctx.lineWidth = 1;
                for (let angle = 0; angle < 360; angle += 30) {
                    const rad = (angle - 90) * Math.PI / 180;
                    const inner = this.radius - 5;
                    const outer = this.radius + 2;
                    ctx.beginPath();
                    ctx.moveTo(
                        this.centerX + inner * Math.cos(rad),
                        this.centerY + inner * Math.sin(rad)
                    );
                    ctx.lineTo(
                        this.centerX + outer * Math.cos(rad),
                        this.centerY + outer * Math.sin(rad)
                    );
                    ctx.stroke();
                }
            }

            drawSweep() {
                const ctx = this.ctx;
                const rad = (this.sweepAngle - 90) * Math.PI / 180;

                // Sweep line with gradient
                const gradient = ctx.createLinearGradient(
                    this.centerX, this.centerY,
                    this.centerX + this.radius * Math.cos(rad),
                    this.centerY + this.radius * Math.sin(rad)
                );
                gradient.addColorStop(0, 'rgba(0, 255, 255, 0.8)');
                gradient.addColorStop(1, 'rgba(0, 255, 255, 0.1)');

                ctx.beginPath();
                ctx.moveTo(this.centerX, this.centerY);
                ctx.lineTo(
                    this.centerX + this.radius * Math.cos(rad),
                    this.centerY + this.radius * Math.sin(rad)
                );
                ctx.strokeStyle = gradient;
                ctx.lineWidth = 2;
                ctx.stroke();

                // Sweep arc (afterglow)
                const startAngle = (this.sweepAngle - 90 - 30) * Math.PI / 180;
                const endAngle = (this.sweepAngle - 90) * Math.PI / 180;
                const arcGradient = ctx.createConicGradient(startAngle, this.centerX, this.centerY);
                arcGradient.addColorStop(0, 'rgba(0, 255, 255, 0)');
                arcGradient.addColorStop(1, 'rgba(0, 255, 255, 0.15)');

                ctx.beginPath();
                ctx.moveTo(this.centerX, this.centerY);
                ctx.arc(this.centerX, this.centerY, this.radius, startAngle, endAngle);
                ctx.closePath();
                ctx.fillStyle = arcGradient;
                ctx.fill();

                // Update sweep angle
                this.sweepAngle = (this.sweepAngle + 2) % 360;
            }

            drawBlips() {
                const ctx = this.ctx;
                const now = Date.now();

                // Update blips from aircraft data
                this.blips = [];
                Object.entries(aircraft).forEach(([icao, ac]) => {
                    if (!ac.lat || !ac.lon) return;
                    if (!passesFilter(icao, ac)) return;

                    const distance = calculateDistanceNm(
                        observerLocation.lat, observerLocation.lon,
                        ac.lat, ac.lon
                    );

                    if (distance > maxRange) return;

                    const bearing = calculateBearing(
                        observerLocation.lat, observerLocation.lon,
                        ac.lat, ac.lon
                    );

                    const ratio = distance / maxRange;
                    const rad = (bearing - 90) * Math.PI / 180;
                    const x = this.centerX + (this.radius * ratio) * Math.cos(rad);
                    const y = this.centerY + (this.radius * ratio) * Math.sin(rad);

                    this.blips.push({
                        x, y,
                        icao,
                        callsign: ac.callsign,
                        altitude: ac.altitude,
                        selected: icao === selectedIcao
                    });
                });

                // Draw blips
                this.blips.forEach(blip => {
                    // Blip glow
                    const gradient = ctx.createRadialGradient(blip.x, blip.y, 0, blip.x, blip.y, 12);
                    gradient.addColorStop(0, blip.selected ? 'rgba(255, 255, 0, 0.8)' : 'rgba(0, 255, 255, 0.8)');
                    gradient.addColorStop(1, 'rgba(0, 255, 255, 0)');
                    ctx.fillStyle = gradient;
                    ctx.fillRect(blip.x - 12, blip.y - 12, 24, 24);

                    // Blip dot
                    ctx.beginPath();
                    ctx.arc(blip.x, blip.y, blip.selected ? 5 : 3, 0, Math.PI * 2);
                    ctx.fillStyle = blip.selected ? '#ffff00' : '#00ffff';
                    ctx.fill();

                    // Label
                    if (blip.callsign || blip.selected) {
                        ctx.fillStyle = '#00ffff';
                        ctx.font = '9px JetBrains Mono';
                        ctx.textAlign = 'left';
                        ctx.fillText(blip.callsign || blip.icao, blip.x + 8, blip.y - 5);
                        if (blip.altitude) {
                            ctx.fillText(`${Math.round(blip.altitude/100)}`, blip.x + 8, blip.y + 7);
                        }
                    }
                });
            }

            handleClick(event) {
                const rect = this.canvas.getBoundingClientRect();
                const x = event.clientX - rect.left;
                const y = event.clientY - rect.top;

                // Find clicked blip
                for (const blip of this.blips) {
                    const dx = x - blip.x;
                    const dy = y - blip.y;
                    if (dx * dx + dy * dy < 100) {  // 10px radius
                        selectAircraft(blip.icao);
                        return;
                    }
                }
            }
        }

        function startRadarAnimation() {
            if (radarAnimationId) return;
            function animate() {
                if (currentView === 'radar' && radarScope) {
                    radarScope.draw();
                }
                radarAnimationId = requestAnimationFrame(animate);
            }
            animate();
        }

        function stopRadarAnimation() {
            if (radarAnimationId) {
                cancelAnimationFrame(radarAnimationId);
                radarAnimationId = null;
            }
        }

        // ============================================
        // VIEW TOGGLE
        // ============================================
        function setView(view) {
            currentView = view;
            const mapEl = document.getElementById('radarMap');
            const scopeEl = document.getElementById('radarScope');
            const mapBtn = document.getElementById('mapViewBtn');
            const radarBtn = document.getElementById('radarViewBtn');

            if (view === 'map') {
                mapEl.style.display = 'block';
                scopeEl.classList.remove('active');
                mapBtn.classList.add('active');
                radarBtn.classList.remove('active');
                stopRadarAnimation();
                // Invalidate map size after showing
                setTimeout(() => radarMap && radarMap.invalidateSize(), 100);
            } else {
                mapEl.style.display = 'none';
                scopeEl.classList.add('active');
                mapBtn.classList.remove('active');
                radarBtn.classList.add('active');
                if (!radarScope) {
                    radarScope = new RadarScope('radarCanvas');
                    document.getElementById('radarCanvas').addEventListener('click', (e) => radarScope.handleClick(e));
                }
                radarScope.resize();
                startRadarAnimation();
            }
        }

        function updateRange() {
            maxRange = parseInt(document.getElementById('rangeSelect').value);
            drawRangeRings();
        }

        // ============================================
        // RANGE RINGS (MAP)
        // ============================================
        function drawRangeRings() {
            if (!radarMap) return;

            if (rangeRingsLayer) {
                radarMap.removeLayer(rangeRingsLayer);
                rangeRingsLayer = null;
            }

            const showRings = document.getElementById('showRangeRings')?.checked;
            if (!showRings) return;

            rangeRingsLayer = L.layerGroup();

            const distances = [maxRange * 0.25, maxRange * 0.5, maxRange * 0.75, maxRange];
            distances.forEach(nm => {
                const meters = nm * 1852;
                const circle = L.circle([observerLocation.lat, observerLocation.lon], {
                    radius: meters,
                    color: '#00ff88',
                    fillColor: 'transparent',
                    fillOpacity: 0,
                    weight: 1,
                    opacity: 0.4,
                    dashArray: '5, 5'
                });

                const labelLat = observerLocation.lat + (nm * 0.0166);
                const label = L.marker([labelLat, observerLocation.lon], {
                    icon: L.divIcon({
                        className: 'range-label',
                        html: `<span style="color: #00ff88; font-size: 10px; background: rgba(0,0,0,0.7); padding: 1px 4px; border-radius: 2px;">${Math.round(nm)} nm</span>`,
                        iconSize: [40, 12],
                        iconAnchor: [20, 6]
                    })
                });

                rangeRingsLayer.addLayer(circle);
                rangeRingsLayer.addLayer(label);
            });

            // Observer marker
            if (observerMarker) radarMap.removeLayer(observerMarker);
            observerMarker = L.marker([observerLocation.lat, observerLocation.lon], {
                icon: L.divIcon({
                    className: 'observer-marker',
                    html: '<div style="width: 12px; height: 12px; background: #ff0; border: 2px solid #000; border-radius: 50%; box-shadow: 0 0 10px #ff0;"></div>',
                    iconSize: [12, 12],
                    iconAnchor: [6, 6]
                })
            }).bindPopup('Your Location').addTo(radarMap);

            rangeRingsLayer.addTo(radarMap);
        }

        function updateObserverLoc() {
            const lat = parseFloat(document.getElementById('obsLat').value);
            const lon = parseFloat(document.getElementById('obsLon').value);

            if (!isNaN(lat) && !isNaN(lon) && lat >= -90 && lat <= 90 && lon >= -180 && lon <= 180) {
                observerLocation.lat = lat;
                observerLocation.lon = lon;
                if (radarMap) {
                    radarMap.setView([lat, lon], radarMap.getZoom());
                }
                drawRangeRings();
            }
        }

        function getGeolocation() {
            if (!navigator.geolocation) {
                alert('Geolocation not supported');
                return;
            }
            if (!window.isSecureContext) {
                alert('GPS requires HTTPS. Enter coordinates manually.');
                return;
            }

            const btn = document.getElementById('geolocateBtn');
            btn.textContent = '...';

            navigator.geolocation.getCurrentPosition(
                (position) => {
                    observerLocation.lat = position.coords.latitude;
                    observerLocation.lon = position.coords.longitude;
                    document.getElementById('obsLat').value = observerLocation.lat.toFixed(4);
                    document.getElementById('obsLon').value = observerLocation.lon.toFixed(4);
                    if (radarMap) {
                        radarMap.setView([observerLocation.lat, observerLocation.lon], 8);
                    }
                    drawRangeRings();
                    btn.textContent = 'Locate';
                },
                (error) => {
                    alert('Location error: ' + error.message);
                    btn.textContent = 'Locate';
                },
                { enableHighAccuracy: true, timeout: 10000 }
            );
        }

        // ============================================
        // GPS DONGLE FUNCTIONS
        // ============================================
        function toggleGpsDongleControls() {
            const source = document.getElementById('gpsSource').value;
            const browserGroup = document.getElementById('browserGpsGroup');
            const dongleControls = document.querySelector('.gps-dongle-controls');

            if (source === 'dongle') {
                browserGroup.style.display = 'none';
                dongleControls.style.display = 'flex';
                refreshGpsDevices();
            } else if (source === 'browser') {
                browserGroup.style.display = 'flex';
                dongleControls.style.display = 'none';
            } else {
                browserGroup.style.display = 'none';
                dongleControls.style.display = 'none';
            }
        }

        async function refreshGpsDevices() {
            try {
                const response = await fetch('/gps/devices');
                const data = await response.json();
                if (data.status === 'ok') {
                    gpsDevices = data.devices;
                    const select = document.getElementById('gpsDeviceSelect');
                    select.innerHTML = '<option value="">GPS Device...</option>';
                    gpsDevices.forEach(device => {
                        const option = document.createElement('option');
                        option.value = device.path;
                        option.textContent = device.name;
                        option.disabled = !device.accessible;
                        select.appendChild(option);
                    });
                }
            } catch (e) {
                console.warn('Failed to get GPS devices:', e);
            }
        }

        async function startGpsDongle() {
            const devicePath = document.getElementById('gpsDeviceSelect').value;
            const baudrate = parseInt(document.getElementById('gpsBaudrateSelect').value) || 9600;
            if (!devicePath) {
                alert('Please select a GPS device');
                return;
            }

            try {
                const response = await fetch('/gps/start', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ device: devicePath, baudrate: baudrate })
                });
                const data = await response.json();

                if (data.status === 'started') {
                    gpsConnected = true;
                    startGpsStream();
                    document.querySelector('.gps-connect-btn').style.display = 'none';
                    document.querySelector('.gps-disconnect-btn').style.display = 'block';
                } else {
                    alert('Failed to start GPS: ' + data.message);
                }
            } catch (e) {
                alert('GPS connection error: ' + e.message);
            }
        }

        async function stopGpsDongle() {
            try {
                if (gpsEventSource) {
                    gpsEventSource.close();
                    gpsEventSource = null;
                }
                await fetch('/gps/stop', { method: 'POST' });
                gpsConnected = false;
                document.querySelector('.gps-connect-btn').style.display = 'block';
                document.querySelector('.gps-disconnect-btn').style.display = 'none';
            } catch (e) {
                console.warn('GPS stop error:', e);
            }
        }

        function startGpsStream() {
            if (gpsEventSource) {
                gpsEventSource.close();
            }

            gpsEventSource = new EventSource('/gps/stream');
            gpsEventSource.onmessage = (event) => {
                try {
                    const data = JSON.parse(event.data);
                    console.log('GPS data received:', data);
                    if (data.type === 'position' && data.latitude && data.longitude) {
                        observerLocation.lat = data.latitude;
                        observerLocation.lon = data.longitude;
                        document.getElementById('obsLat').value = data.latitude.toFixed(4);
                        document.getElementById('obsLon').value = data.longitude.toFixed(4);
                        if (radarMap) {
                            console.log('GPS: Updating map to', data.latitude, data.longitude);
                            radarMap.setView([data.latitude, data.longitude], radarMap.getZoom());
                        }
                        drawRangeRings();
                    }
                } catch (e) {
                    console.error('GPS parse error:', e);
                }
            };
            gpsEventSource.onerror = (e) => {
                console.warn('GPS stream error:', e);
                gpsConnected = false;
                document.querySelector('.gps-connect-btn').style.display = 'block';
                document.querySelector('.gps-disconnect-btn').style.display = 'none';
            };
        }

        // ============================================
        // FILTERING
        // ============================================
        function applyFilter() {
            currentFilter = document.getElementById('aircraftFilter').value;
            // Clear markers and redraw
            Object.keys(markers).forEach(icao => {
                radarMap.removeLayer(markers[icao]);
                delete markers[icao];
            });
            Object.keys(markerState).forEach(icao => delete markerState[icao]);
            pendingMarkerUpdates.clear();
            Object.keys(aircraft).forEach(icao => {
                if (aircraft[icao].lat && aircraft[icao].lon) {
                    pendingMarkerUpdates.add(icao);
                }
            });
            scheduleUIUpdate();
        }

        function passesFilter(icao, ac) {
            if (currentFilter === 'all') return true;
            const militaryInfo = isMilitaryAircraft(icao, ac.callsign);
            const squawkInfo = checkSquawkCode(ac);
            if (currentFilter === 'military') return militaryInfo.military;
            if (currentFilter === 'civil') return !militaryInfo.military;
            if (currentFilter === 'emergency') return !!squawkInfo;
            return true;
        }

        // ============================================
        // INITIALIZATION
        // ============================================
        document.addEventListener('DOMContentLoaded', () => {
            initMap();
            updateClock();
            setInterval(updateClock, 1000);
            setInterval(cleanupOldAircraft, 10000);
        });

        function updateClock() {
            const now = new Date();
            document.getElementById('utcTime').textContent =
                now.toISOString().substring(11, 19) + ' UTC';
        }

        function initMap() {
            radarMap = L.map('radarMap', {
                center: [51.5, -0.1],
                zoom: 7,
                minZoom: 3,
                maxZoom: 15
            });

            L.tileLayer('https://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}{r}.png', {
                attribution: '©OpenStreetMap, ©CartoDB'
            }).addTo(radarMap);

            if (navigator.geolocation) {
                navigator.geolocation.getCurrentPosition(pos => {
                    radarMap.setView([pos.coords.latitude, pos.coords.longitude], 8);
                    observerLocation.lat = pos.coords.latitude;
                    observerLocation.lon = pos.coords.longitude;
                    document.getElementById('obsLat').value = observerLocation.lat.toFixed(4);
                    document.getElementById('obsLon').value = observerLocation.lon.toFixed(4);
                }, () => {}, { timeout: 5000 });
            }
        }

        // ============================================
        // TRACKING CONTROL
        // ============================================
        async function toggleTracking() {
            const btn = document.getElementById('startBtn');

            if (!isTracking) {
                try {
                    const response = await fetch('/adsb/start', {
                        method: 'POST',
                        headers: { 'Content-Type': 'application/json' },
                        body: JSON.stringify({})
                    });

                    const text = await response.text();
                    let data;
                    try {
                        data = JSON.parse(text);
                    } catch (e) {
                        alert('Invalid response: ' + text);
                        return;
                    }

                    if (data.status === 'success' || data.status === 'started' || data.status === 'already_running') {
                        startEventStream();
                        drawRangeRings();
                        isTracking = true;
                        btn.textContent = 'STOP';
                        btn.classList.add('active');
                        document.getElementById('trackingDot').classList.remove('inactive');
                        document.getElementById('trackingStatus').textContent = 'TRACKING';
                    } else {
                        alert('Failed to start: ' + (data.message || JSON.stringify(data)));
                    }
                } catch (err) {
                    alert('Error: ' + err.message);
                }
            } else {
                try {
                    await fetch('/adsb/stop', { method: 'POST' });
                } catch (err) {}

                stopEventStream();
                isTracking = false;
                btn.textContent = 'START';
                btn.classList.remove('active');
                document.getElementById('trackingDot').classList.add('inactive');
                document.getElementById('trackingStatus').textContent = 'STANDBY';
            }
        }

        function startEventStream() {
            if (eventSource) eventSource.close();

            eventSource = new EventSource('/adsb/stream');
            eventSource.onmessage = (event) => {
                try {
                    const data = JSON.parse(event.data);
                    if (data.type === 'aircraft') {
                        updateAircraft(data);
                    }
                } catch (err) {}
            };
            eventSource.onerror = () => {};
        }

        function stopEventStream() {
            if (eventSource) {
                eventSource.close();
                eventSource = null;
            }
        }

        // ============================================
        // AIRCRAFT UPDATES
        // ============================================
        let pendingUIUpdate = false;
        let pendingMarkerUpdates = new Set();
        const MAX_MARKER_UPDATES_PER_FRAME = 20;

        function scheduleUIUpdate() {
            if (pendingUIUpdate) return;
            pendingUIUpdate = true;
            requestAnimationFrame(() => {
                updateStatsDisplay();
                renderAircraftList();

                let updateCount = 0;
                const toProcess = [];
                for (const icao of pendingMarkerUpdates) {
                    if (updateCount < MAX_MARKER_UPDATES_PER_FRAME) {
                        updateMarkerImmediate(icao);
                        toProcess.push(icao);
                        updateCount++;
                    }
                }
                toProcess.forEach(icao => pendingMarkerUpdates.delete(icao));

                if (pendingMarkerUpdates.size > 0) {
                    pendingUIUpdate = false;
                    scheduleUIUpdate();
                    return;
                }

                if (selectedIcao && aircraft[selectedIcao]) {
                    showAircraftDetails(selectedIcao);
                }

                pendingUIUpdate = false;
            });
        }

        function updateAircraft(data) {
            const icao = data.icao;
            if (!icao) return;

            aircraft[icao] = {
                ...aircraft[icao],
                ...data,
                lastSeen: Date.now()
            };

            checkAndAlertAircraft(icao, aircraft[icao]);
            updateStatistics(icao, aircraft[icao]);

            // Record trail point
            if (data.lat && data.lon) {
                recordTrailPoint(icao, data.lat, data.lon, data.altitude);
                if (showTrails) {
                    updateTrailLine(icao);
                }
                pendingMarkerUpdates.add(icao);
            }

            scheduleUIUpdate();
        }

        const markerState = {};

        function updateMarkerImmediate(icao) {
            const ac = aircraft[icao];
            if (!ac || !ac.lat || !ac.lon) return;

            if (!passesFilter(icao, ac)) {
                if (markers[icao]) {
                    radarMap.removeLayer(markers[icao]);
                    delete markers[icao];
                    delete markerState[icao];
                }
                return;
            }

            const militaryInfo = isMilitaryAircraft(icao, ac.callsign);
            const rotation = Math.round((ac.heading || 0) / 5) * 5;
            const color = militaryInfo.military ? '#556b2f' : getAltitudeColor(ac.altitude);
            const callsign = ac.callsign || icao;
            const alt = ac.altitude ? ac.altitude + ' ft' : 'N/A';

            const prevState = markerState[icao] || {};
            const iconChanged = prevState.rotation !== rotation || prevState.color !== color;
            const tooltipChanged = prevState.callsign !== callsign || prevState.alt !== alt;

            if (markers[icao]) {
                markers[icao].setLatLng([ac.lat, ac.lon]);
                if (iconChanged) {
                    markers[icao].setIcon(createMarkerIcon(rotation, color));
                }
                if (tooltipChanged) {
                    markers[icao].unbindTooltip();
                    markers[icao].bindTooltip(`${callsign}<br>${alt}`, {
                        permanent: false, direction: 'top', className: 'aircraft-tooltip'
                    });
                }
            } else {
                markers[icao] = L.marker([ac.lat, ac.lon], { icon: createMarkerIcon(rotation, color) })
                    .addTo(radarMap)
                    .on('click', () => selectAircraft(icao));
                markers[icao].bindTooltip(`${callsign}<br>${alt}`, {
                    permanent: false, direction: 'top', className: 'aircraft-tooltip'
                });
            }

            markerState[icao] = { rotation, color, callsign, alt };
        }

        function createMarkerIcon(rotation, color) {
            return L.divIcon({
                className: 'aircraft-marker',
                html: `<svg width="24" height="24" viewBox="0 0 24 24" style="transform: rotate(${rotation}deg); color: ${color}; filter: drop-shadow(0 0 5px ${color});">
                    <path fill="currentColor" d="M12 2L8 10H4v2l8 4 8-4v-2h-4L12 2zm0 14l-6 3v1h12v-1l-6-3z"/>
                </svg>`,
                iconSize: [24, 24],
                iconAnchor: [12, 12]
            });
        }

        // ============================================
        // AIRCRAFT LIST
        // ============================================
        let renderedAircraftOrder = [];
        let lastFullRebuild = 0;
        const MAX_AIRCRAFT_DISPLAY = 50;
        const MIN_REBUILD_INTERVAL = 2000;

        function renderAircraftList() {
            const container = document.getElementById('aircraftList');
            const sortedAircraft = Object.entries(aircraft)
                .filter(([icao, ac]) => passesFilter(icao, ac))
                .map(([icao, ac]) => ({ ...ac, icao }))
                .sort((a, b) => (b.altitude || 0) - (a.altitude || 0))
                .slice(0, MAX_AIRCRAFT_DISPLAY);

            if (sortedAircraft.length === 0) {
                if (container.querySelector('.no-aircraft')) return;
                container.innerHTML = `<div class="no-aircraft"><div>No aircraft detected</div></div>`;
                renderedAircraftOrder = [];
                return;
            }

            const newOrder = sortedAircraft.map(ac => ac.icao);
            const orderChanged = newOrder.length !== renderedAircraftOrder.length ||
                newOrder.some((icao, i) => icao !== renderedAircraftOrder[i]);

            const now = Date.now();
            const canRebuild = now - lastFullRebuild > MIN_REBUILD_INTERVAL;

            if (orderChanged && canRebuild) {
                lastFullRebuild = now;
                const fragment = document.createDocumentFragment();

                sortedAircraft.forEach(ac => {
                    const div = document.createElement('div');
                    div.className = `aircraft-item ${selectedIcao === ac.icao ? 'selected' : ''}`;
                    div.setAttribute('data-icao', ac.icao);
                    div.onclick = () => selectAircraft(ac.icao);
                    div.innerHTML = buildAircraftItemHTML(ac);
                    fragment.appendChild(div);
                });

                container.innerHTML = '';
                container.appendChild(fragment);
                renderedAircraftOrder = newOrder;
            } else {
                const existingItems = {};
                container.querySelectorAll('[data-icao]').forEach(el => {
                    existingItems[el.getAttribute('data-icao')] = el;
                });

                sortedAircraft.forEach(ac => {
                    const existingItem = existingItems[ac.icao];
                    if (existingItem) {
                        existingItem.className = `aircraft-item ${selectedIcao === ac.icao ? 'selected' : ''}`;
                        existingItem.innerHTML = buildAircraftItemHTML(ac);
                    }
                });
            }
        }

        function buildAircraftItemHTML(ac) {
            const callsign = ac.callsign || '------';
            const alt = ac.altitude ? ac.altitude.toLocaleString() : '---';
            const speed = ac.speed || '---';
            const heading = ac.heading ? ac.heading + '°' : '---';
            const militaryInfo = isMilitaryAircraft(ac.icao, ac.callsign);
            const badge = militaryInfo.military ?
                `<span style="background:#556b2f;color:#fff;padding:1px 4px;border-radius:2px;font-size:8px;margin-left:4px;">MIL</span>` : '';

            return `
                <div class="aircraft-header">
                    <span class="aircraft-callsign">${callsign}${badge}</span>
                    <span class="aircraft-icao">${ac.icao}</span>
                </div>
                <div class="aircraft-details">
                    <div class="aircraft-detail">
                        <div class="aircraft-detail-value">${alt}</div>
                        <div class="aircraft-detail-label">ALT</div>
                    </div>
                    <div class="aircraft-detail">
                        <div class="aircraft-detail-value">${speed}</div>
                        <div class="aircraft-detail-label">SPD</div>
                    </div>
                    <div class="aircraft-detail">
                        <div class="aircraft-detail-value">${heading}</div>
                        <div class="aircraft-detail-label">HDG</div>
                    </div>
                </div>
            `;
        }

        function selectAircraft(icao) {
            selectedIcao = icao;
            renderAircraftList();
            showAircraftDetails(icao);

            const ac = aircraft[icao];
            if (ac && ac.lat && ac.lon && currentView === 'map') {
                radarMap.setView([ac.lat, ac.lon], 10);
            }
        }

        function showAircraftDetails(icao) {
            const ac = aircraft[icao];
            const container = document.getElementById('selectedInfo');

            if (!ac) {
                container.innerHTML = `
                    <div class="no-aircraft">
                        <div class="no-aircraft-icon">&#9992;</div>
                        <div>Select an aircraft</div>
                    </div>`;
                return;
            }

            const callsign = ac.callsign || ac.icao;
            const lat = ac.lat ? ac.lat.toFixed(4) + '°' : 'N/A';
            const lon = ac.lon ? ac.lon.toFixed(4) + '°' : 'N/A';
            const alt = ac.altitude ? ac.altitude.toLocaleString() + ' ft' : 'N/A';
            const speed = ac.speed ? ac.speed + ' kts' : 'N/A';
            const heading = ac.heading ? ac.heading + '°' : 'N/A';
            const squawk = ac.squawk || 'N/A';
            const militaryInfo = isMilitaryAircraft(ac.icao, ac.callsign);
            const badge = militaryInfo.military ?
                `<div style="background:#556b2f;color:#fff;padding:3px 8px;border-radius:4px;font-size:10px;text-align:center;margin-bottom:8px;">MILITARY${militaryInfo.country ? ' (' + militaryInfo.country + ')' : ''}</div>` : '';

            container.innerHTML = `
                <div class="selected-callsign">${callsign}</div>
                ${badge}
                <div class="telemetry-grid">
                    <div class="telemetry-item">
                        <div class="telemetry-label">ICAO</div>
                        <div class="telemetry-value">${ac.icao}</div>
                    </div>
                    <div class="telemetry-item">
                        <div class="telemetry-label">Squawk</div>
                        <div class="telemetry-value">${squawk}</div>
                    </div>
                    <div class="telemetry-item">
                        <div class="telemetry-label">Lat</div>
                        <div class="telemetry-value">${lat}</div>
                    </div>
                    <div class="telemetry-item">
                        <div class="telemetry-label">Lon</div>
                        <div class="telemetry-value">${lon}</div>
                    </div>
                    <div class="telemetry-item">
                        <div class="telemetry-label">Altitude</div>
                        <div class="telemetry-value">${alt}</div>
                    </div>
                    <div class="telemetry-item">
                        <div class="telemetry-label">Speed</div>
                        <div class="telemetry-value">${speed}</div>
                    </div>
                    <div class="telemetry-item">
                        <div class="telemetry-label">Heading</div>
                        <div class="telemetry-value">${heading}</div>
                    </div>
                    <div class="telemetry-item">
                        <div class="telemetry-label">Range</div>
                        <div class="telemetry-value">${ac.lat ? calculateDistanceNm(observerLocation.lat, observerLocation.lon, ac.lat, ac.lon).toFixed(1) + ' nm' : 'N/A'}</div>
                    </div>
                </div>`;
        }

        function cleanupOldAircraft() {
            const now = Date.now();
            const timeout = 60000;
            let needsUpdate = false;

            Object.keys(aircraft).forEach(icao => {
                if (now - aircraft[icao].lastSeen > timeout) {
                    if (markers[icao]) {
                        radarMap.removeLayer(markers[icao]);
                        delete markers[icao];
                    }
                    cleanupTrail(icao);
                    delete aircraft[icao];
                    delete alertedAircraft[icao];
                    needsUpdate = true;

                    if (selectedIcao === icao) {
                        selectedIcao = null;
                        showAircraftDetails(null);
                    }
                }
            });

            if (needsUpdate) {
                scheduleUIUpdate();
            }
        }
    </script>
</body>
</html>
