<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PiAware ATC Radar Scope</title>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"/>
    <style>
        :root {
            --atc-green: #34d399;
            --atc-dark-green: #065f46;
            --atc-bg: #000000;
            --refresh-rate: {{ refresh_rate }}s;
        }

        body, html {
            margin: 0;
            padding: 0;
            width: 100%;
            height: 100%;
            background-color: var(--atc-bg);
            color: var(--atc-green);
            font-family: 'Courier New', Courier, monospace;
            overflow: hidden;
        }

        #atc-map {
            width: 100%;
            height: 100%;
            background: var(--atc-bg);
        }

        /* Rendre la carte extrêmement sombre pour l'effet radar */
        .leaflet-tile-pane {
            filter: grayscale(100%) contrast(150%) brightness(30%) sepia(100%) hue-rotate(90deg) saturate(300%) opacity(0.3);
        }

        /* Overlay de balayage radar */
        #radar-container {
            position: absolute;
            top: 50%;
            left: 50%;
            width: 200vmax;
            height: 200vmax;
            transform: translate(-50%, -50%);
            pointer-events: none;
            z-index: 1000;
            overflow: hidden;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        #radar-sweep {
            width: 100%;
            height: 100%;
            border-radius: 50%;
            background: conic-gradient(from 0deg, rgba(52, 211, 153, 0) 0%, rgba(52, 211, 153, 0) 80%, rgba(52, 211, 153, 0.4) 100%);
            animation: spin var(--refresh-rate) linear infinite;
        }

        @keyframes spin {
            from { transform: rotate(0deg); }
            to { transform: rotate(360deg); }
        }

        /* Styles ATC */
        .atc-datablock {
            background: transparent;
            border: none;
            color: var(--atc-green);
            font-weight: bold;
            font-size: 13px;
            line-height: 1.1;
            text-shadow: 0 0 4px var(--atc-green);
            white-space: nowrap;
        }

        .atc-target {
            background: transparent;
            border: none;
        }
        .atc-target-icon {
            width: 8px;
            height: 8px;
            background-color: var(--atc-green);
            border-radius: 50%;
            box-shadow: 0 0 8px var(--atc-green);
            position: absolute;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
        }

        .atc-leader-line {
            position: absolute;
            background-color: var(--atc-green);
            transform-origin: 0 0;
            box-shadow: 0 0 2px var(--atc-green);
        }

        /* Header UI overlay */
        .atc-header {
            position: absolute;
            top: 20px;
            left: 20px;
            z-index: 2000;
            pointer-events: none;
            text-shadow: 0 0 5px var(--atc-green);
        }
        .atc-header h1 {
            margin: 0;
            font-size: 24px;
            text-transform: uppercase;
        }
        .atc-header .sys-status {
            font-size: 14px;
            margin-top: 5px;
        }
        
        .nav-back {
            position: absolute;
            top: 20px;
            right: 20px;
            z-index: 2000;
            color: var(--atc-green);
            text-decoration: none;
            border: 1px solid var(--atc-green);
            padding: 8px 16px;
            text-transform: uppercase;
            font-size: 14px;
            transition: all 0.2s;
            background: rgba(0, 20, 0, 0.5);
            text-shadow: 0 0 5px var(--atc-green);
            box-shadow: 0 0 5px rgba(52, 211, 153, 0.3);
        }
        .nav-back:hover {
            background: var(--atc-green);
            color: var(--atc-bg);
        }

        /* Emergency Flash */
        @keyframes emergency-flash {
            0% { background: rgba(220, 38, 38, 0.8); color: white; text-shadow: 0 0 5px white; }
            50% { background: transparent; color: #dc2626; text-shadow: 0 0 5px #dc2626; }
            100% { background: rgba(220, 38, 38, 0.8); color: white; text-shadow: 0 0 5px white; }
        }
        .emergency-flash {
            animation: emergency-flash 1s infinite;
            border: 2px solid #dc2626 !important;
        }

        .atc-airport {
            color: #065f46;
            font-size: 11px;
            font-family: monospace;
            white-space: nowrap;
        }
    </style>
</head>
<body>

    <div class="atc-header">
        <h1>Eurocat/TopSky Simulator</h1>
        <div class="sys-status">SYS: OK | SCAN: <span id="target-count">0</span> TRK | <span id="sys-time"></span> Z</div>
    </div>

    <a href="/" class="nav-back">⬅ Live Radar</a>

    <!-- Balayage centré sur l'écran (approximatif pour le style) -->
    <div id="radar-container">
        <div id="radar-sweep"></div>
    </div>

    <div id="atc-map"></div>

    <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
    <script>
        const REFRESH_RATE = {{ refresh_rate }} * 1000;
        
        // Initialisation de la carte (interactions désactivées pour plus de réalisme, sauf le zoom)
        const map = L.map('atc-map', {
            zoomControl: false,
            attributionControl: false
        }).setView([0, 0], 10);

        L.tileLayer('/tiles/carto_dark_nolabels/{z}/{x}/{y}.png', {
            maxZoom: 19
        }).addTo(map);

        let receiverLat = 0;
        let receiverLon = 0;
        let mapInitialized = false;

        const planesLayer = L.layerGroup().addTo(map);
        const ringsLayer = L.layerGroup().addTo(map);
        const trailsLayer = L.layerGroup().addTo(map);
        const geoLayer = L.layerGroup().addTo(map);
        const airportsLayer = L.layerGroup().addTo(map);

        // Historique et objets de carte
        const trailsHistory = {};
        const atcTargets = {};
        const atcDatablocks = {};
        const atcTrails = {};
        const atcVectors = {};
        const atcTethers = {};
        const labelOffsets = {}; // { hex_id: [pixel_dx, pixel_dy] }

        function getDestinationPoint(lat, lon, distanceKm, bearingDeg) {
            const R = 6371.0;
            const lat1 = lat * Math.PI / 180;
            const lon1 = lon * Math.PI / 180;
            const brng = bearingDeg * Math.PI / 180;
            const lat2 = Math.asin(Math.sin(lat1)*Math.cos(distanceKm/R) + Math.cos(lat1)*Math.sin(distanceKm/R)*Math.cos(brng));
            const lon2 = lon1 + Math.atan2(Math.sin(brng)*Math.sin(distanceKm/R)*Math.cos(lat1), Math.cos(distanceKm/R) - Math.sin(lat1)*Math.sin(lat2));
            return [lat2 * 180 / Math.PI, lon2 * 180 / Math.PI];
        }

        function drawRangeRings(lat, lon) {
            ringsLayer.clearLayers();
            const center = [lat, lon];
            // Dessiner des anneaux tous les 25 NM (46.3 km)
            for (let i = 1; i <= 6; i++) {
                const radiusMeters = i * 25 * 1852;
                L.circle(center, {
                    radius: radiusMeters,
                    color: '#065f46', // dark green
                    weight: 1,
                    fill: false,
                    interactive: false
                }).addTo(ringsLayer);
                
                // Label de distance
                L.marker(center, {
                    icon: L.divIcon({
                        className: 'atc-datablock',
                        html: `<div style="color: #065f46; transform: translateY(-${radiusMeters/1000 * map.getZoom() / 1.5}px);">${i*25}</div>`,
                        iconSize: [0, 0]
                    }),
                    interactive: false
                }).addTo(ringsLayer);
            }
            // Croix centrale
            L.marker(center, {
                icon: L.divIcon({
                    className: 'atc-datablock',
                    html: '<div style="font-size: 16px; margin-left:-4px; margin-top:-8px;">+</div>'
                }),
                interactive: false
            }).addTo(ringsLayer);
        }

        // Fonction pour formater l'altitude en FL (Flight Level) et ajouter la tendance
        function formatFlightLevel(alt, verticalRate) {
            if (!alt) return "---";
            const fl = Math.round(alt / 100).toString().padStart(3, '0');
            let trend = "";
            if (verticalRate && verticalRate > 250) trend = "↑";
            else if (verticalRate && verticalRate < -250) trend = "↓";
            return fl + trend;
        }

        // Fonction pour formater la vitesse (en dizaines de nœuds)
        function formatSpeed(speed) {
            if (!speed) return "---";
            return Math.round(speed / 10).toString().padStart(2, '0');
        }

        async function fetchAtcData() {
            try {
                const res = await fetch('/api/data?t=' + Date.now());
                const data = await res.json();

                if (!mapInitialized && data.receiver && data.receiver.lat) {
                    receiverLat = data.receiver.lat;
                    receiverLon = data.receiver.lon;
                    map.setView([receiverLat, receiverLon], 8);
                    drawRangeRings(receiverLat, receiverLon);
                    
                    // Fetch Borders
                    fetch('https://raw.githubusercontent.com/johan/world.geo.json/master/countries.geo.json')
                        .then(r => r.json())
                        .then(geo => {
                            L.geoJSON(geo, {
                                style: { color: '#065f46', weight: 1, fill: false, opacity: 0.3 },
                                interactive: false
                            }).addTo(geoLayer);
                        }).catch(e => console.error(e));

                    // Fetch Airports
                    fetch(`/api/airports?lat=${receiverLat}&lon=${receiverLon}`)
                        .then(r => r.json())
                        .then(airports => {
                            airports.forEach(apt => {
                                L.marker([apt.lat, apt.lon], {
                                    icon: L.divIcon({
                                        className: 'atc-airport',
                                        html: `<div style="transform: translate(-4px, -8px);">X<br/>${apt.icao}</div>`,
                                        iconSize: [0, 0]
                                    }),
                                    interactive: false
                                }).addTo(airportsLayer);
                            });
                        }).catch(e => console.error(e));

                    mapInitialized = true;
                }

                document.getElementById('target-count').innerText = data.aircraft.length;

                const nowHex = new Set();
                
                data.aircraft.forEach(flight => {
                    try {
                        if (!flight.latitude || !flight.longitude) return;
                        nowHex.add(flight.hex_id);

                        // Mise à jour de l'historique pour le trail
                        if (!trailsHistory[flight.hex_id]) {
                            trailsHistory[flight.hex_id] = [];
                        }
                        const lastPos = trailsHistory[flight.hex_id][trailsHistory[flight.hex_id].length - 1];
                        if (!lastPos || lastPos[0] !== flight.latitude || lastPos[1] !== flight.longitude) {
                            trailsHistory[flight.hex_id].push([flight.latitude, flight.longitude]);
                            if (trailsHistory[flight.hex_id].length > 15) {
                                trailsHistory[flight.hex_id].shift(); // Garder 15 derniers points
                            }
                        }

                        // Dessiner le trail en ligne pointillée pure (très performant, sans scintillement)
                        if (!atcTrails[flight.hex_id]) {
                            atcTrails[flight.hex_id] = L.polyline([], {
                                color: 'var(--atc-green)',
                                weight: 4,
                                opacity: 0.4,
                                dashArray: '4, 10', // 4px dot, 10px gap
                                interactive: false
                            }).addTo(trailsLayer);
                        }
                        atcTrails[flight.hex_id].setLatLngs(trailsHistory[flight.hex_id]);

                        const pos = [flight.latitude, flight.longitude];
                        
                        // Mise à jour douce de la position cible
                        if (!atcTargets[flight.hex_id]) {
                            atcTargets[flight.hex_id] = L.marker(pos, {
                                icon: L.divIcon({
                                    className: 'atc-target',
                                    html: '<div class="atc-target-icon"></div>',
                                    iconSize: [12, 12],
                                    iconAnchor: [6, 6]
                                }),
                                interactive: false
                            }).addTo(planesLayer);
                        } else {
                            atcTargets[flight.hex_id].setLatLng(pos);
                        }

                        // Vecteur de Vitesse (Prédiction à 2 minutes)
                        const speedKmh = (flight.ground_speed || 0) * 1.852;
                        const distKm = speedKmh * (2 / 60); // Distance parcourue en 2 min
                        const futurePos = getDestinationPoint(flight.latitude, flight.longitude, distKm, flight.heading || 0);

                        if (!atcVectors[flight.hex_id]) {
                            atcVectors[flight.hex_id] = L.polyline([], {
                                color: 'var(--atc-green)',
                                weight: 1,
                                interactive: false
                            }).addTo(planesLayer);
                        }
                        atcVectors[flight.hex_id].setLatLngs([pos, futurePos]);

                        // Formater les données du Datablock
                        const callsign = flight.callsign && flight.callsign !== "N/A" ? flight.callsign.padEnd(7, ' ') : flight.hex_id.toUpperCase();
                        const fl = formatFlightLevel(flight.altitude, flight.vertical_rate);
                        const spd = formatSpeed(flight.ground_speed);
                        const squawk = flight.squawk ? `A${flight.squawk}` : '';
                        
                        let isEmergency = flight.squawk === '7700' || flight.squawk === '7600';
                        let cssEmergency = isEmergency ? 'emergency-flash' : '';
                        
                        const datablockHtml = `
                            <div class="${cssEmergency}" style="background: rgba(0,20,0,0.8); padding: 2px 4px; border-left: 2px solid var(--atc-green); cursor: grab;">
                                <div>${callsign}</div>
                                <div>${fl} ${spd}</div>
                                <div style="font-size: 11px;">${squawk}</div>
                            </div>
                        `;

                        // Offset logic for Drag & Drop
                        let labelPos = futurePos;
                        let hasOffset = false;
                        if (labelOffsets[flight.hex_id]) {
                            const pt = map.latLngToLayerPoint(futurePos);
                            pt.x += labelOffsets[flight.hex_id][0];
                            pt.y += labelOffsets[flight.hex_id][1];
                            labelPos = map.layerPointToLatLng(pt);
                            hasOffset = true;
                        }

                        // Mise à jour douce du datablock
                        if (!atcDatablocks[flight.hex_id]) {
                            atcDatablocks[flight.hex_id] = L.marker(labelPos, {
                                icon: L.divIcon({
                                    className: 'atc-datablock',
                                    html: datablockHtml,
                                    iconSize: [100, 50],
                                    iconAnchor: [-5, -5]
                                }),
                                draggable: true
                            }).addTo(planesLayer);

                            // Handle drag
                            atcDatablocks[flight.hex_id].on('dragend', function(e) {
                                const newLatLng = e.target.getLatLng();
                                const basePt = map.latLngToLayerPoint(atcVectors[flight.hex_id].getLatLngs()[1]);
                                const newPt = map.latLngToLayerPoint(newLatLng);
                                labelOffsets[flight.hex_id] = [newPt.x - basePt.x, newPt.y - basePt.y];
                            });

                        } else {
                            atcDatablocks[flight.hex_id].setLatLng(labelPos);
                            atcDatablocks[flight.hex_id].setIcon(L.divIcon({
                                className: 'atc-datablock',
                                html: datablockHtml,
                                iconSize: [100, 50],
                                iconAnchor: [-5, -5]
                            }));
                        }

                        // Tether line if offset exists
                        if (hasOffset) {
                            if (!atcTethers[flight.hex_id]) {
                                atcTethers[flight.hex_id] = L.polyline([], {
                                    color: 'var(--atc-green)',
                                    weight: 1,
                                    dashArray: '2, 4',
                                    interactive: false
                                }).addTo(planesLayer);
                            }
                            // Calculate offset anchor visually (top left of datablock)
                            const anchorPt = map.latLngToLayerPoint(labelPos);
                            anchorPt.x += 5; // compensate for iconAnchor
                            anchorPt.y += 5;
                            const tetherEnd = map.layerPointToLatLng(anchorPt);
                            atcTethers[flight.hex_id].setLatLngs([futurePos, tetherEnd]);
                        } else {
                            if (atcTethers[flight.hex_id]) {
                                planesLayer.removeLayer(atcTethers[flight.hex_id]);
                                delete atcTethers[flight.hex_id];
                            }
                        }
                    } catch (e) {
                        console.error("Error updating flight", flight.hex_id, e);
                    }
                });
                
                // Nettoyage de l'historique des avions disparus
                Object.keys(atcTargets).forEach(hex => {
                    if (!nowHex.has(hex)) {
                        if (atcTargets[hex]) planesLayer.removeLayer(atcTargets[hex]);
                        delete atcTargets[hex];
                        if (atcDatablocks[hex]) planesLayer.removeLayer(atcDatablocks[hex]);
                        delete atcDatablocks[hex];
                        if (atcVectors[hex]) planesLayer.removeLayer(atcVectors[hex]);
                        delete atcVectors[hex];
                        if (atcTrails[hex]) trailsLayer.removeLayer(atcTrails[hex]);
                        delete atcTrails[hex];
                        if (atcTethers[hex]) planesLayer.removeLayer(atcTethers[hex]);
                        delete atcTethers[hex];
                        delete labelOffsets[hex];
                        delete trailsHistory[hex];
                    }
                });

            } catch (err) {
                console.error("Erreur de récupération des données ATC", err);
            } finally {
                setTimeout(fetchAtcData, REFRESH_RATE);
            }
        }

        // Horloge système
        setInterval(() => {
            const d = new Date();
            const el = document.getElementById('sys-time');
            if (el) el.innerText = d.toISOString().substring(11, 19);
        }, 1000);

        fetchAtcData();

        // Centrer la carte après un zoom pour garder les anneaux centrés
        map.on('zoomend', () => {
            if (receiverLat && receiverLon) {
                drawRangeRings(receiverLat, receiverLon);
            }
        });

    </script>
</body>
</html>
