let map = null;
let planeMarkers = {};
let receiverMarker = null;
let flightPaths = {};
let flightPolylines = {};
let selectedHexId = null;
let selectedFlight = null;
let selectedPlanePulse = null;
let expandedHexId = null;
let showTrails = localStorage.getItem('showTrails') === 'true';
let useMetric = localStorage.getItem('useMetric') === 'true';
let coveragePolygon = null;
let loadedAirports = [];
let savedFilters = {};
try {
    const raw = localStorage.getItem('legendFilters');
    if (raw) savedFilters = JSON.parse(raw);
} catch (e) {}

const defaultFilters = {
    climb: true,
    stable: true,
    descend: true,
    military: true,
    large_airport: true,
    medium_airport: true,
    small_airport: true,
    heliport: true,
    seaplane_base: true
};
const filterState = Object.assign({}, defaultFilters, savedFilters);

window.recenterMap = function(e) {
    if (e) e.preventDefault();
    if (coveragePolygon) {
        map.fitBounds(coveragePolygon.getBounds(), {padding: [20, 20]});
    } else if (receiverMarker) {
        map.setView(receiverMarker.getLatLng(), 10);
    }
};

document.addEventListener('DOMContentLoaded', () => {
    const trailsToggle = document.getElementById('toggle-trails');
    const metricToggle = document.getElementById('toggle-metric');
    
    trailsToggle.checked = showTrails;
    metricToggle.checked = useMetric;

    trailsToggle.addEventListener('change', (e) => {
        showTrails = e.target.checked;
        localStorage.setItem('showTrails', showTrails);
        if (!showTrails) {
            for (const hex in flightPolylines) {
                map.removeLayer(flightPolylines[hex]);
            }
        } else {
            for (const hex in flightPolylines) {
                if (!map.hasLayer(flightPolylines[hex])) {
                    flightPolylines[hex].addTo(trailsLayer);
                }
            }
        }
    });

    metricToggle.addEventListener('change', (e) => {
        useMetric = e.target.checked;
        localStorage.setItem('useMetric', useMetric);
        fetchData();
    });

    window.addEventListener('resize', () => {
        if (map) {
            map.invalidateSize();
        }
    });

    // Écouteurs pour les actions de Spotter Card
    const btnApprove = document.getElementById('btn-spotter-approve');
    const btnReject = document.getElementById('btn-spotter-reject');
    const btnCancel = document.getElementById('btn-spotter-cancel');
    const btnSearch = document.getElementById('btn-spotter-search');
    const searchQuery = document.getElementById('spotter-search-query');

    if (btnApprove) {
        btnApprove.addEventListener('click', () => {
            if (selectedHexId) handleSpotterAction(selectedHexId, 'approve');
        });
    }
    if (btnReject) {
        btnReject.addEventListener('click', () => {
            if (selectedHexId) handleSpotterAction(selectedHexId, 'reject');
        });
    }
    if (btnCancel) {
        btnCancel.addEventListener('click', () => {
            if (selectedHexId) handleSpotterAction(selectedHexId, 'cancel');
        });
    }
    if (btnSearch && searchQuery) {
        const doSearch = () => {
            const q = searchQuery.value.trim();
            if (selectedHexId && q) {
                handleSpotterAction(selectedHexId, 'search', q);
            }
        };
        btnSearch.addEventListener('click', doSearch);
        searchQuery.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') doSearch();
        });
    }
});

function getPlaneSVG(color, category) {
    if (category === "A7" || category === "A6") {
        // Helicopter
        return `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M12 2C12.55 2 13 2.45 13 3V6.2L18.5 8.5C19.3 8.8 19.8 9.6 19.8 10.5V11L13 9.5V15L15 16.5V18L12 17.5L9 18V16.5L11 15V9.5L4.2 11V10.5C4.2 9.6 4.7 8.8 5.5 8.5L11 6.2V3C11 2.45 11.45 2 12 2ZM2 5H22V6H2V5Z" fill="${color}"/></svg>`;
    } else if (category === "A1" || category === "A2") {
        // Small Plane
        return `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M21 16V14L13 9V3.5C13 2.67 12.33 2 11.5 2C10.67 2 10 2.67 10 3.5V9L2 14V16L10 13.5V19L8 20.5V22L11.5 21L15 22V20.5L13 19V13.5L21 16Z" fill="${color}"/></svg>`;
    }
    // Jet
    return `<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M21 16V14L13 9V3.5C13 2.67 12.33 2 11.5 2C10.67 2 10 2.67 10 3.5V9L2 14V16L10 13.5V19L8 20.5V22L11.5 21L15 22V20.5L13 19V13.5L21 16Z" fill="${color}"/></svg>`;
}

let trailsLayer = L.layerGroup();
let markersLayer = L.layerGroup();
let weatherLayer = L.layerGroup();
let coverageLayer = L.layerGroup();
let airportsLayer = L.layerGroup();

const weatherTileLayer = L.tileLayer('/tiles/weather/{z}/{x}/{y}.png', {
    opacity: 0.6, 
    attribution: '© RainViewer',
    maxNativeZoom: 7
}).addTo(weatherLayer);

// Auto-refresh weather every 10 minutes
setInterval(() => {
    weatherTileLayer.setUrl('/tiles/weather/{z}/{x}/{y}.png?t=' + new Date().getTime());
}, 600000);

function fetchCoverage() {
    fetch('/api/coverage')
        .then(r => r.json())
        .then(points => {
            if (points.length > 2) {
                if (coveragePolygon) {
                    coveragePolygon.setLatLngs(points);
                } else {
                    coveragePolygon = L.polygon(points, {
                        color: '#38bdf8', 
                        weight: 1,
                        fillColor: '#38bdf8', 
                        fillOpacity: 0.05,
                        smoothFactor: 1
                    }).addTo(coverageLayer);
                }
            }
        })
        .catch(e => console.error("Erreur de récupération de la couverture:", e));
}
fetchCoverage();
setInterval(fetchCoverage, 60000);

function initMap(lat, lon) {
    let savedCenter = [lat, lon];
    let savedZoom = 7;
    try {
        if (localStorage.getItem('mapCenter')) savedCenter = JSON.parse(localStorage.getItem('mapCenter'));
        if (localStorage.getItem('mapZoom')) savedZoom = parseInt(localStorage.getItem('mapZoom'));
    } catch(e) {}

    let zoomDelta = parseFloat(localStorage.getItem('zoomDelta') || '0.5');
    let zoomWheelSpeed = parseInt(localStorage.getItem('zoomWheelSpeed') || '120');

    map = L.map('map', {
        center: savedCenter,
        zoom: savedZoom,
        layers: [markersLayer, trailsLayer, airportsLayer],
        zoomDelta: zoomDelta,
        zoomSnap: zoomDelta,
        wheelPxPerZoomLevel: zoomWheelSpeed
    });
    
    const cartoDark = L.tileLayer('/tiles/carto_dark/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© CARTO' });
    const osmLayer = L.tileLayer('/tiles/osm/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© OpenStreetMap' });
    const satelliteLayer = L.tileLayer('/tiles/satellite/{z}/{x}/{y}.png', { maxZoom: 19, attribution: '© Esri' });
    const topoLayer = L.tileLayer('/tiles/topo/{z}/{x}/{y}.png', { maxZoom: 17, attribution: '© OpenTopoMap' });
    
    const baseLayers = {
        "Mode Sombre (CartoDB)": cartoDark,
        "Vue Satellite (Esri)": satelliteLayer,
        "Topographique (OpenTopo)": topoLayer,
        "Standard (OSM)": osmLayer
    };

    const savedLayerName = localStorage.getItem('mapBaseLayer') || "Mode Sombre (CartoDB)";
    if (baseLayers[savedLayerName]) {
        baseLayers[savedLayerName].addTo(map);
    } else {
        cartoDark.addTo(map);
    }
    
    const overlays = {
        "Avions en vol": markersLayer, 
        "Trajectoires (Sillage)": trailsLayer,
        "Nuages & Précipitations": weatherLayer,
        "Zone de Couverture Antenne": coverageLayer
    };
    
    L.control.layers(baseLayers, overlays).addTo(map);

    // Bouton de recentrage
    const recenterControl = L.control({position: 'topleft'});
    recenterControl.onAdd = function() {
        const div = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
        div.innerHTML = `<a href="#" title="Centrer sur la zone de couverture" style="font-size: 16px; line-height: 30px; text-align: center; text-decoration: none; display: block; width: 30px; height: 30px; background-color: #fff; color: #333;" onclick="recenterMap(event)">🎯</a>`;
        return div;
    };
    recenterControl.addTo(map);

    // Restaurer l'état des calques
    for (const [name, layer] of Object.entries(overlays)) {
        const savedState = localStorage.getItem('overlay_' + name);
        if (savedState === 'true') {
            if (!map.hasLayer(layer)) layer.addTo(map);
        } else if (savedState === 'false') {
            if (map.hasLayer(layer)) map.removeLayer(layer);
        }
    }

    map.on('overlayadd', (e) => {
        localStorage.setItem('overlay_' + e.name, 'true');
    });
    map.on('overlayremove', (e) => {
        localStorage.setItem('overlay_' + e.name, 'false');
    });

    map.on('moveend', () => {
        localStorage.setItem('mapCenter', JSON.stringify(map.getCenter()));
        localStorage.setItem('mapZoom', map.getZoom());
    });
    
    map.on('baselayerchange', (e) => {
        localStorage.setItem('mapBaseLayer', e.name);
    });

    receiverMarker = L.circleMarker([lat, lon], {
        radius: 6,
        color: '#f43f5e',
        fillColor: '#f43f5e',
        fillOpacity: 1
    }).addTo(map).bindPopup("Récepteur PiAware");

    // Fetch airports
    fetch(`/api/airports?lat=${lat}&lon=${lon}`)
        .then(r => r.json())
        .then(airports => {
            loadedAirports = airports;
            renderAirports();
        })
        .catch(e => console.error("Erreur aéroports:", e));

    // Ajout de la légende cartographique
    const legend = L.control({position: 'bottomleft'});
    legend.onAdd = function (map) {
        const div = L.DomUtil.create('div', 'map-legend glass-panel');
        div.style.padding = '10px';
        div.style.fontSize = '12px';
        div.style.lineHeight = '1.5';
        div.style.color = '#f8fafc';
        div.style.background = 'rgba(15, 23, 42, 0.85)';
        div.style.backdropFilter = 'blur(8px)';
        div.style.border = '1px solid rgba(255, 255, 255, 0.1)';
        div.style.borderRadius = '8px';
        div.style.boxShadow = '0 4px 6px rgba(0,0,0,0.3)';
        div.style.pointerEvents = 'auto';
        
window.updateFilter = function(input) {
            const key = input.getAttribute('data-filter');
            if (key) {
                filterState[key] = input.checked;
                localStorage.setItem('legendFilters', JSON.stringify(filterState));
                renderAirports();
                fetchData();
            }
        };

        div.innerHTML = `
            <h4 style="margin: 0 0 8px 0; font-size: 13px; font-weight: 600; border-bottom: 1px solid rgba(255,255,255,0.1); padding-bottom: 4px; color: #f8fafc;">Légende</h4>
            <div style="margin-bottom: 10px;">
                <strong style="display:block; font-size: 10px; text-transform: uppercase; color: var(--text-muted); margin-bottom: 4px;">Avions (Tendance)</strong>
                <label style="display: flex; align-items: center; gap: 6px; margin-bottom: 2px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.climb ? 'checked' : ''} data-filter="climb" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 10px; height: 10px; background: #3b82f6; border-radius: 2px;"></span> Montée
                </label>
                <label style="display: flex; align-items: center; gap: 6px; margin-bottom: 2px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.stable ? 'checked' : ''} data-filter="stable" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 10px; height: 10px; background: #10b981; border-radius: 2px;"></span> Stable
                </label>
                <label style="display: flex; align-items: center; gap: 6px; margin-bottom: 2px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.descend ? 'checked' : ''} data-filter="descend" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 10px; height: 10px; background: #ef4444; border-radius: 2px;"></span> Descente
                </label>
            </div>
            <div>
                <strong style="display:block; font-size: 10px; text-transform: uppercase; color: var(--text-muted); margin-bottom: 4px;">Aéroports</strong>
                <label style="display: flex; align-items: center; gap: 6px; margin-bottom: 2px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.military ? 'checked' : ''} data-filter="military" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 8px; height: 8px; background: #ef4444; border: 1.5px solid #fff; border-radius: 50%;"></span> Militaire
                </label>
                <label style="display: flex; align-items: center; gap: 6px; margin-bottom: 2px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.large_airport ? 'checked' : ''} data-filter="large_airport" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 8px; height: 8px; background: #a855f7; border: 1.5px solid #fff; border-radius: 50%;"></span> International
                </label>
                <label style="display: flex; align-items: center; gap: 6px; margin-bottom: 2px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.medium_airport ? 'checked' : ''} data-filter="medium_airport" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 8px; height: 8px; background: #3b82f6; border: 1.5px solid #fff; border-radius: 50%;"></span> Régional / Moyen
                </label>
                <label style="display: flex; align-items: center; gap: 6px; margin-bottom: 2px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.small_airport ? 'checked' : ''} data-filter="small_airport" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 8px; height: 8px; background: #10b981; border: 1.5px solid #fff; border-radius: 50%;"></span> Aéro-club / Petit
                </label>
                <label style="display: flex; align-items: center; gap: 6px; margin-bottom: 2px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.heliport ? 'checked' : ''} data-filter="heliport" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 8px; height: 8px; background: #eab308; border: 1.5px solid #fff; border-radius: 50%;"></span> Héliport
                </label>
                <label style="display: flex; align-items: center; gap: 6px; cursor: pointer; user-select: none;">
                    <input type="checkbox" ${filterState.seaplane_base ? 'checked' : ''} data-filter="seaplane_base" onchange="updateFilter(this)" style="margin: 0; cursor: pointer;">
                    <span style="display: inline-block; width: 8px; height: 8px; background: #06b6d4; border: 1.5px solid #fff; border-radius: 50%;"></span> Hydrobase
                </label>
            </div>
        `;

        L.DomEvent.disableClickPropagation(div);
        L.DomEvent.disableScrollPropagation(div);
        return div;
    };
    legend.addTo(map);
    
    setTimeout(() => {
        map.invalidateSize();
    }, 200);
}

function renderAirports() {
    airportsLayer.clearLayers();
    loadedAirports.forEach(apt => {
        let typeKey = apt.type;
        const nameLower = apt.name.toLowerCase();
        const isMilitary = nameLower.includes('air base') || 
                           nameLower.includes('base aérienne') || 
                           nameLower.includes('base aerienne') || 
                           nameLower.includes('military') || 
                           nameLower.includes('militaire') || 
                           nameLower.includes('base d\'aviation') || 
                           nameLower.includes('base d’aviation') || 
                           nameLower.includes('aaf') || 
                           nameLower.includes('nas');

        if (isMilitary) {
            typeKey = 'military';
        }

        if (!filterState[typeKey]) {
            return;
        }

        let color = '#a855f7';
        if (isMilitary) {
            color = '#ef4444';
        } else {
            switch(apt.type) {
                case 'large_airport':
                    color = '#a855f7';
                    break;
                case 'medium_airport':
                    color = '#3b82f6';
                    break;
                case 'small_airport':
                    color = '#10b981';
                    break;
                case 'heliport':
                    color = '#eab308';
                    break;
                case 'seaplane_base':
                    color = '#06b6d4';
                    break;
                default:
                    color = '#8b5cf6';
            }
        }

        const icon = L.divIcon({
            html: `<div style="background-color: ${color}; width: 10px; height: 10px; border: 1.5px solid #ffffff; border-radius: 50%; box-shadow: 0 0 4px rgba(0,0,0,0.5);"></div>`,
            className: 'airport-icon',
            iconSize: [10, 10],
            iconAnchor: [5, 5]
        });
        L.marker([apt.lat, apt.lon], {icon: icon})
         .bindTooltip(`<b>${apt.name}</b><br/>${apt.icao}`, {direction: 'top', offset: [0, -10]})
         .addTo(airportsLayer);
    });
}

function selectAircraft(flight) {
    if (!flight.latitude || !flight.longitude) return;
    
    selectedHexId = flight.hex_id;
    selectedFlight = flight;
    expandedHexId = flight.hex_id;
    
    if (selectedPlanePulse) {
        map.removeLayer(selectedPlanePulse);
    }
    
    const pulseIcon = L.divIcon({
        html: '<div class="pulse-marker"></div>',
        className: 'pulse-icon-container',
        iconSize: [40, 40],
        iconAnchor: [20, 20]
    });
    
    selectedPlanePulse = L.marker([flight.latitude, flight.longitude], {icon: pulseIcon}).addTo(map);
    
    map.setView([flight.latitude, flight.longitude], 10);
    showSpotterCard(flight);
}

function showSpotterCard(flight) {
    const card = document.getElementById('spotter-card');
    if (!card) return;
    
    card.style.display = 'flex';
    document.getElementById('spotter-callsign').innerText = flight.callsign && flight.callsign !== 'N/A' ? flight.callsign : 'Inconnu';
    document.getElementById('spotter-hex').innerText = flight.hex_id;
    
    document.getElementById('spotter-photo').style.display = 'none';
    document.getElementById('spotter-airline-logo').style.display = 'none';
    document.getElementById('spotter-type').innerText = '';
    
    const loadingDiv = document.getElementById('spotter-loading');
    if (loadingDiv) {
        loadingDiv.innerText = 'Recherche en base de données...';
        loadingDiv.style.display = 'block';
    }
    
    // Set initial flight data
    let alt = flight.altitude;
    let spd = flight.ground_speed;
    let altUnit = 'ft';
    let spdUnit = 'kt';
    if (useMetric) {
        alt = alt ? Math.round(alt * 0.3048) : null;
        spd = spd ? Math.round(spd * 1.852) : null;
        altUnit = 'm';
        spdUnit = 'km/h';
    }
    const distText = flight.distance ? `${flight.distance.toFixed(1)} km` : '-';
    
    const elAlt = document.getElementById('spotter-alt');
    if (elAlt) {
        elAlt.innerText = alt ? `${alt} ${altUnit}` : '-';
        document.getElementById('spotter-spd').innerText = spd ? `${spd} ${spdUnit}` : '-';
        document.getElementById('spotter-hdg').innerText = flight.heading ? `${flight.heading}°` : '-';
        document.getElementById('spotter-dist').innerText = distText;
    }
    
    document.getElementById('spotter-photo-controls').style.display = 'none';
    document.getElementById('spotter-photo-search').style.display = 'none';
    document.getElementById('spotter-status-badge').style.display = 'none';

    fetch(`/api/details/${flight.hex_id}`).then(r => r.json()).then(details => {
        if (loadingDiv) loadingDiv.style.display = 'none';
        
        updateSpotterCardUI(flight.hex_id, details);
        
        if (flight.callsign && flight.callsign !== 'N/A' && flight.callsign.length >= 3) {
            const prefix = flight.callsign.substring(0, 3).toUpperCase();
            const logoUrl = `https://www.flightaware.com/images/airline_logos/90p/${prefix}.png`;
            const logoImg = document.getElementById('spotter-airline-logo');
            logoImg.src = logoUrl;
            logoImg.onload = () => logoImg.style.display = 'block';
            logoImg.onerror = () => logoImg.style.display = 'none';
        }
    }).catch((e) => {
        console.error("Error fetching aircraft details:", e);
        if (loadingDiv) {
            loadingDiv.innerText = 'Erreur lors de la recherche.';
            loadingDiv.style.display = 'block';
        }
    });
}

function handleSpotterAction(hexId, action, query = '') {
    const body = { action };
    if (action === 'search') {
        body.query = query;
    }
    
    document.querySelectorAll('.spotter-btn').forEach(btn => btn.disabled = true);
    const loadingDiv = document.getElementById('spotter-loading');
    if (loadingDiv) {
        loadingDiv.innerText = 'Mise à jour...';
        loadingDiv.style.display = 'block';
    }
    
    fetch(`/api/details/${hexId}/action`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
    })
    .then(r => r.json())
    .then(details => {
        if (loadingDiv) loadingDiv.style.display = 'none';
        document.querySelectorAll('.spotter-btn').forEach(btn => btn.disabled = false);
        
        if (details.success === false) {
            alert(details.error || "Une erreur est survenue");
            return;
        }
        
        updateSpotterCardUI(hexId, details);
        
        // Refresh dashboard immediately
        if (typeof fetchData === 'function') {
            fetchData();
        }
    })
    .catch(err => {
        console.error("Action error:", err);
        if (loadingDiv) {
            loadingDiv.innerText = 'Erreur lors de la mise à jour.';
            loadingDiv.style.display = 'block';
        }
        document.querySelectorAll('.spotter-btn').forEach(btn => btn.disabled = false);
    });
}

window.closeSpotterCard = function() {
    expandedHexId = null;
    selectedHexId = null;
    if (selectedPlanePulse) {
        map.removeLayer(selectedPlanePulse);
        selectedPlanePulse = null;
    }
    const spotterCard = document.getElementById('spotter-card');
    if (spotterCard) spotterCard.style.display = 'none';
    if (typeof fetchData === 'function') {
        fetchData();
    }
};

function updateSpotterCardUI(hexId, details) {
    const photoImg = document.getElementById('spotter-photo');
    const controlsDiv = document.getElementById('spotter-photo-controls');
    const searchDiv = document.getElementById('spotter-photo-search');
    const badgeDiv = document.getElementById('spotter-status-badge');
    const typeDiv = document.getElementById('spotter-type');
    
    if (details.type) {
        typeDiv.innerText = details.type + (details.reg ? ' (' + details.reg + ')' : '');
    } else {
        typeDiv.innerText = 'Modèle inconnu';
    }
    
    if (details.photo) {
        photoImg.src = details.photo;
        photoImg.style.display = 'block';
    } else {
        photoImg.src = '';
        photoImg.style.display = 'none';
    }
    
    const queryInput = document.getElementById('spotter-search-query');
    if (queryInput) queryInput.value = '';

    const rejectBtn = document.getElementById('btn-spotter-reject');
    if (rejectBtn) {
        const remaining = details.photo_list ? (details.photo_list.length - (details.photo_index || 0) - 1) : 0;
        if (remaining > 0) {
            rejectBtn.innerHTML = `⏭️ Suivant (${remaining})`;
        } else {
            rejectBtn.innerHTML = `❌ Rejeter`;
        }
    }

    if (details.photo_status === 'pending') {
        controlsDiv.style.display = 'flex';
        searchDiv.style.display = 'block';
        badgeDiv.style.display = 'none';
    } else if (details.photo_status === 'approved') {
        controlsDiv.style.display = 'none';
        searchDiv.style.display = 'block';
        badgeDiv.style.display = 'block';
        badgeDiv.innerText = '✅ Image Validée';
        badgeDiv.style.background = 'rgba(16, 185, 129, 0.1)';
        badgeDiv.style.color = '#10b981';
        badgeDiv.style.border = '1px solid rgba(16, 185, 129, 0.2)';
    } else {
        controlsDiv.style.display = 'none';
        searchDiv.style.display = 'block';
        badgeDiv.style.display = 'block';
        badgeDiv.innerText = '❌ Aucune image validée';
        badgeDiv.style.background = 'rgba(239, 68, 68, 0.1)';
        badgeDiv.style.color = '#ef4444';
        badgeDiv.style.border = '1px solid rgba(239, 68, 68, 0.2)';
    }
}

function updateDashboard(data) {
    if (data.status) {
        const statusSpan = document.getElementById('sys-status');
        if (statusSpan) {
            statusSpan.textContent = data.status.piaware_status.toUpperCase();
            statusSpan.style.color = data.status.piaware_status === 'green' ? '#10b981' : '#f43f5e';
        }
        
        const cpuSpan = document.getElementById('sys-cpu');
        if (cpuSpan) cpuSpan.textContent = data.status.system_load ? `${data.status.system_load}%` : '--';
        
        const tempSpan = document.getElementById('sys-temp');
        if (tempSpan) tempSpan.textContent = data.status.cpu_temp ? `${data.status.cpu_temp}°C` : '--';
    }

    const listContainer = document.getElementById('aircraft-list');
    listContainer.innerHTML = '';
    document.getElementById('live-count').textContent = data.aircraft.length;

    const currentHexes = new Set();

    data.aircraft.sort((a, b) => (a.distance || 9999) - (b.distance || 9999)).forEach(flight => {
        currentHexes.add(flight.hex_id);
        
        let alt = flight.altitude;
        let spd = flight.ground_speed;
        let altUnit = 'ft';
        let spdUnit = 'kt';

        if (useMetric) {
            alt = alt ? Math.round(alt * 0.3048) : null;
            spd = spd ? Math.round(spd * 1.852) : null;
            altUnit = 'm';
            spdUnit = 'km/h';
        }

        // Update List
        const distText = flight.distance ? `${flight.distance.toFixed(1)} km` : '-';
        
        // Update Live Spotter Card Data if Selected
        if (flight.hex_id === selectedHexId) {
            const elAlt = document.getElementById('spotter-alt');
            if (elAlt) {
                elAlt.innerText = alt ? `${alt} ${altUnit}` : '-';
                document.getElementById('spotter-spd').innerText = spd ? `${spd} ${spdUnit}` : '-';
                document.getElementById('spotter-hdg').innerText = flight.heading ? `${flight.heading}°` : '-';
                document.getElementById('spotter-dist').innerText = distText;
            }
        }
        
        const isExpanded = (flight.hex_id === expandedHexId);
        const card = document.createElement('div');
        card.className = `aircraft-card${isExpanded ? ' expanded' : ''}`;
        card.innerHTML = `
            <div class="card-header">
                <span class="card-callsign">${flight.callsign && flight.callsign !== 'N/A' ? flight.callsign : 'Inconnu'}</span>
                <span class="card-hex">${flight.hex_id}</span>
                <span class="card-chevron">${isExpanded ? '▲' : '▼'}</span>
            </div>
            <div class="card-collapsible">
                <div class="card-details">
                    <span>Alt: ${alt || '-'} ${altUnit}</span>
                    <span>Spd: ${spd || '-'} ${spdUnit}</span>
                    <span>Dist: ${distText}</span>
                    <span>Hdg: ${flight.heading || '-'}°</span>
                </div>
                <div class="card-photo-container" id="card-photo-${flight.hex_id}">
                    ${isExpanded ? '<span style="font-size:0.75rem;color:gray;font-style:italic;">Recherche de photo...</span>' : ''}
                </div>
            </div>
        `;
        
        if (isExpanded) {
            setTimeout(() => {
                fetch(`/api/details/${flight.hex_id}`).then(r => r.json()).then(details => {
                    const pCont = document.getElementById(`card-photo-${flight.hex_id}`);
                    if (!pCont) return;
                    let html = '';
                    if (details.type) {
                        html += `<div style="font-size:0.75rem;font-weight:600;margin:0.25rem 0;color:var(--text-muted);">${details.type}</div>`;
                    }
                    if (details.photo && details.photo_status === 'approved') {
                        html += `<img src="${details.photo}" style="width:100%;border-radius:4px;border:1px solid rgba(255,255,255,0.05);margin-top:0.25rem;">`;
                    } else if (details.photo && details.photo_status === 'pending') {
                        html += `<div style="font-size:0.7rem;color:#f59e0b;font-style:italic;margin-top:0.25rem;">📷 Image en attente de validation (voir panneau latéral)</div>`;
                    } else {
                        html += `<div style="font-size:0.7rem;color:gray;font-style:italic;">Pas d'image validée</div>`;
                    }
                    pCont.innerHTML = html;
                }).catch(() => {
                    const pCont = document.getElementById(`card-photo-${flight.hex_id}`);
                    if (pCont) pCont.innerHTML = '';
                });
            }, 50);
        }

        card.onclick = (e) => {
            if (expandedHexId === flight.hex_id) {
                expandedHexId = null;
                selectedHexId = null;
                if (selectedPlanePulse) {
                    map.removeLayer(selectedPlanePulse);
                    selectedPlanePulse = null;
                }
                const spotterCard = document.getElementById('spotter-card');
                if (spotterCard) spotterCard.style.display = 'none';
            } else {
                expandedHexId = flight.hex_id;
                selectAircraft(flight);
            }
            // Mettre à jour l'affichage immédiatement
            fetchData();
        };
        listContainer.appendChild(card);

        // Détermination de la couleur (Montée/Descente) et de la tendance
        let color = '#10b981'; // Vert (vol en palier ou inconnu)
        let trend = 'stable';
        if (flight.vertical_rate > 64) {
            color = '#3b82f6'; // Bleu (en montée)
            trend = 'climb';
        } else if (flight.vertical_rate < -64) {
            color = '#ef4444'; // Rouge (en descente)
            trend = 'descend';
        }

        const isVisible = filterState[trend];

        // Update Map Marker & Trails
        if (flight.latitude && flight.longitude && isVisible) {
            // Trails
            if (!flightPaths[flight.hex_id]) flightPaths[flight.hex_id] = [];
            flightPaths[flight.hex_id].push([flight.latitude, flight.longitude]);
            if (flightPaths[flight.hex_id].length > 5000) flightPaths[flight.hex_id].shift();

            if (showTrails) {
                if (!flightPolylines[flight.hex_id]) {
                    flightPolylines[flight.hex_id] = L.polyline(flightPaths[flight.hex_id], {color: color, weight: 2, opacity: 0.6}).addTo(trailsLayer);
                } else {
                    flightPolylines[flight.hex_id].setStyle({color: color});
                    flightPolylines[flight.hex_id].setLatLngs(flightPaths[flight.hex_id]);
                    if (!trailsLayer.hasLayer(flightPolylines[flight.hex_id])) {
                        flightPolylines[flight.hex_id].addTo(trailsLayer);
                    }
                }
            } else {
                if (flightPolylines[flight.hex_id]) {
                    trailsLayer.removeLayer(flightPolylines[flight.hex_id]);
                }
            }
            
            const svgContent = getPlaneSVG(color, flight.category);

            if (planeMarkers[flight.hex_id]) {
                const marker = planeMarkers[flight.hex_id];
                marker.setLatLng([flight.latitude, flight.longitude]);
                if (selectedHexId && flight.hex_id === selectedHexId && selectedPlanePulse) {
                    selectedPlanePulse.setLatLng([flight.latitude, flight.longitude]);
                }
                const iconOuter = marker.getElement();
                if (iconOuter) {
                    const iconInner = iconOuter.querySelector('.plane-rotator');
                    if (iconInner) {
                        iconInner.style.transform = `rotate(${flight.heading || 0}deg)`;
                        // Mise à jour de la couleur de l'avion
                        iconInner.innerHTML = svgContent;
                    }
                }
                if (!markersLayer.hasLayer(marker)) {
                    marker.addTo(markersLayer);
                }
            } else {
                const icon = L.divIcon({
                    html: `<div class="plane-rotator" style="transform: rotate(${flight.heading || 0}deg); width: 24px; height: 24px; transition: transform 0.5s ease;">${svgContent}</div>`,
                    className: 'plane-icon',
                    iconSize: [24, 24],
                    iconAnchor: [12, 12]
                });
                
                const marker = L.marker([flight.latitude, flight.longitude], {icon: icon}).addTo(markersLayer);
                
                marker.on('click', () => {
                    selectAircraft(flight);
                });
                
                planeMarkers[flight.hex_id] = marker;
            }
        } else {
            // Retirer de la carte si non visible
            if (planeMarkers[flight.hex_id]) {
                markersLayer.removeLayer(planeMarkers[flight.hex_id]);
            }
            if (flightPolylines[flight.hex_id]) {
                trailsLayer.removeLayer(flightPolylines[flight.hex_id]);
            }
        }
    });

    // Remove old markers and trails
    for (const hex in planeMarkers) {
        if (!currentHexes.has(hex)) {
            markersLayer.removeLayer(planeMarkers[hex]);
            delete planeMarkers[hex];
            if (flightPolylines[hex]) {
                trailsLayer.removeLayer(flightPolylines[hex]);
                delete flightPolylines[hex];
            }
            delete flightPaths[hex];

            if (selectedHexId === hex) {
                if (selectedPlanePulse) {
                    map.removeLayer(selectedPlanePulse);
                    selectedPlanePulse = null;
                }
                selectedHexId = null;
                const spotterCard = document.getElementById('spotter-card');
                if (spotterCard) spotterCard.style.display = 'none';
            }
        }
    }
}

async function fetchData() {
    try {
        const response = await fetch('/api/data?t=' + Date.now());
        const data = await response.json();
        
        if (!map && data.receiver.lat) {
            initMap(data.receiver.lat, data.receiver.lon);
        }
        
        updateDashboard(data);
    } catch (error) {
        console.error("Erreur de récupération des données", error);
    }
}

setInterval(fetchData, 2000);
fetchData();

// ==========================================
// PARAMÈTRES (MODALE)
// ==========================================
function showSettingsModal() {
    const modal = document.getElementById('settings-modal');
    if (modal) {
        modal.style.display = 'flex';
        
        const deltaVal = localStorage.getItem('zoomDelta') || '0.5';
        const wheelVal = localStorage.getItem('zoomWheelSpeed') || '120';
        
        const deltaInput = document.getElementById('zoom-delta');
        const wheelInput = document.getElementById('zoom-wheel-speed');
        const deltaDisplay = document.getElementById('zoom-delta-val');
        const wheelDisplay = document.getElementById('zoom-wheel-speed-val');
        
        if (deltaInput && deltaDisplay) {
            deltaInput.value = deltaVal;
            deltaDisplay.innerText = deltaVal;
            deltaInput.oninput = function() {
                deltaDisplay.innerText = this.value;
            };
        }
        
        if (wheelInput && wheelDisplay) {
            wheelInput.value = wheelVal;
            wheelDisplay.innerText = `${wheelVal}px (plus grand = plus doux)`;
            wheelInput.oninput = function() {
                wheelDisplay.innerText = `${this.value}px (plus grand = plus doux)`;
            };
        }
    }
}

function hideSettingsModal() {
    const modal = document.getElementById('settings-modal');
    if (modal) modal.style.display = 'none';
}

function saveSettings() {
    const days = document.getElementById('retention-days').value;
    const deltaVal = document.getElementById('zoom-delta').value;
    const wheelVal = document.getElementById('zoom-wheel-speed').value;
    
    // Sauvegarder dans localStorage
    localStorage.setItem('zoomDelta', deltaVal);
    localStorage.setItem('zoomWheelSpeed', wheelVal);
    
    // Appliquer à la carte en cours si elle existe
    if (map) {
        const parsedDelta = parseFloat(deltaVal);
        map.options.zoomDelta = parsedDelta;
        map.options.zoomSnap = parsedDelta;
        map.options.wheelPxPerZoomLevel = parseInt(wheelVal);
    }

    fetch('/api/config', {
        method: 'POST',
        headers: {'Content-Type': 'application/json'},
        body: JSON.stringify({"HISTORY_RETENTION_DAYS": days})
    }).then(r => r.json()).then(res => {
        if (res.success) {
            const msg = document.getElementById('settings-msg');
            msg.style.display = 'block';
            setTimeout(() => {
                msg.style.display = 'none';
                hideSettingsModal();
            }, 1500);
        }
    });
}
