// GigLez - Map Visualization

let map;
let markerLayer;
let markerClusterGroup;
let heatmapLayer;
let capturesData = [];
let heatmapEnabled = false;

// Frequency color mapping
const FREQUENCY_COLORS = {
    315: '#10b981',  // Green
    433: '#3b82f6',  // Blue
    868: '#f59e0b',  // Orange
    915: '#ef4444',  // Red
    default: '#6b7280'  // Gray
};

// Initialize map
document.addEventListener('DOMContentLoaded', () => {
    initMap();
    loadCaptures();
    setupMapControls();
});

function initMap() {
    // Create map centered on US
    map = L.map('map').setView([39.8283, -98.5795], 4);

    // Add OpenStreetMap tiles
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors',
        maxZoom: 19
    }).addTo(map);

    // Create marker cluster group
    markerClusterGroup = L.markerClusterGroup({
        maxClusterRadius: 50,
        spiderfyOnMaxZoom: true,
        showCoverageOnHover: false,
        zoomToBoundsOnClick: true
    });

    // Create regular marker layer
    markerLayer = L.layerGroup();

    // Add cluster group by default
    map.addLayer(markerClusterGroup);

    // Export map to window for access from other modules
    window.map = map;
}

function setupMapControls() {
    // Cluster toggle
    document.getElementById('cluster-toggle').addEventListener('change', (e) => {
        if (e.target.checked) {
            map.removeLayer(markerLayer);
            map.addLayer(markerClusterGroup);
        } else {
            map.removeLayer(markerClusterGroup);
            map.addLayer(markerLayer);
        }
        renderMarkers();
    });

    // Frequency filter
    document.getElementById('frequency-filter').addEventListener('change', () => {
        if (heatmapEnabled) {
            renderHeatmap();
        } else {
            renderMarkers();
        }
    });

    // Heatmap toggle
    document.getElementById('heatmap-toggle').addEventListener('change', (e) => {
        heatmapEnabled = e.target.checked;
        if (heatmapEnabled) {
            // Hide markers, show heatmap
            map.removeLayer(markerClusterGroup);
            map.removeLayer(markerLayer);
            renderHeatmap();
        } else {
            // Hide heatmap, show markers
            if (heatmapLayer) {
                map.removeLayer(heatmapLayer);
            }
            // Re-add appropriate marker layer based on cluster toggle
            const clusterEnabled = document.getElementById('cluster-toggle').checked;
            if (clusterEnabled) {
                map.addLayer(markerClusterGroup);
            } else {
                map.addLayer(markerLayer);
            }
        }
    });
}

async function loadCaptures() {
    try {
        const response = await fetch('/api/v1/query/captures?limit=1000');

        if (!response.ok) {
            console.error('Failed to load captures');
            return;
        }

        const data = await response.json();
        capturesData = data.captures || [];

        renderMarkers();
        updateStats();

    } catch (error) {
        console.error('Error loading captures:', error);
    }
}

function renderMarkers() {
    // Clear existing markers
    markerClusterGroup.clearLayers();
    markerLayer.clearLayers();

    // Get frequency filter
    const frequencyFilter = document.getElementById('frequency-filter').value;

    // Filter captures
    let filtered = capturesData;

    if (frequencyFilter) {
        const targetFreq = parseInt(frequencyFilter) * 1e6;
        filtered = capturesData.filter(c => {
            const freq = c.frequency / 1e6;
            return Math.abs(freq - parseInt(frequencyFilter)) < 50;
        });
    }

    // Create markers
    filtered.forEach(capture => {
        const marker = createMarker(capture);

        // Add to both layers (only one will be visible)
        markerClusterGroup.addLayer(marker);
        markerLayer.addLayer(marker);
    });

    // Update count
    document.getElementById('total-captures').textContent = filtered.length;
}

function createMarker(capture) {
    // Determine color based on frequency
    const freqMHz = Math.round(capture.frequency / 1e6);
    let color = FREQUENCY_COLORS.default;

    for (const [freq, col] of Object.entries(FREQUENCY_COLORS)) {
        if (freq === 'default') continue;
        if (Math.abs(freqMHz - parseInt(freq)) < 50) {
            color = col;
            break;
        }
    }

    // Create custom icon
    const icon = L.divIcon({
        className: 'custom-marker',
        html: `<div style="background-color: ${color}; width: 12px; height: 12px; border-radius: 50%; border: 2px solid white; box-shadow: 0 0 4px rgba(0,0,0,0.3);"></div>`,
        iconSize: [12, 12],
        iconAnchor: [6, 6]
    });

    // Create marker
    const marker = L.marker([capture.latitude, capture.longitude], { icon });

    // Create popup
    const popupContent = createPopupContent(capture);
    marker.bindPopup(popupContent);

    return marker;
}

function createPopupContent(capture) {
    const freqMHz = (capture.frequency / 1e6).toFixed(2);
    const ts = capture.timestamp || capture.captured_at;
    const parsed = ts ? new Date(ts) : null;
    const date = parsed && !isNaN(parsed) ? parsed.toLocaleDateString() : 'Unknown';

    let deviceInfo = 'Unknown Device';
    if (capture.device_name) {
        deviceInfo = `<strong>${capture.device_name}</strong>`;
        if (capture.match_confidence) {
            deviceInfo += ` (${(capture.match_confidence * 100).toFixed(0)}% confidence)`;
        }
    }

    return `
        <div class="marker-popup">
            <h4>${deviceInfo}</h4>
            <p><strong>Frequency:</strong> ${freqMHz} MHz</p>
            <p><strong>Protocol:</strong> ${capture.protocol || 'RAW'}</p>
            <p><strong>Captured:</strong> ${date}</p>
            <p><strong>Location:</strong> ${capture.latitude.toFixed(6)}, ${capture.longitude.toFixed(6)}</p>
            ${capture.accuracy ? `<p><strong>Accuracy:</strong> ±${capture.accuracy.toFixed(1)}m</p>` : ''}
            <button onclick="viewCaptureDetails(${capture.id})" class="btn btn-primary" style="margin-top: 0.5rem;">
                View Details
            </button>
        </div>
    `;
}

function updateStats() {
    // Total captures
    document.getElementById('total-captures').textContent = capturesData.length;

    // Unique devices
    const uniqueDevices = new Set(
        capturesData
            .filter(c => c.device_name)
            .map(c => c.device_name)
    ).size;
    document.getElementById('unique-devices').textContent = uniqueDevices;
}

function renderHeatmap() {
    // Remove existing heatmap layer if it exists
    if (heatmapLayer) {
        map.removeLayer(heatmapLayer);
    }

    // Get frequency filter
    const frequencyFilter = document.getElementById('frequency-filter').value;

    // Filter captures
    let filtered = capturesData;

    if (frequencyFilter) {
        const targetFreq = parseInt(frequencyFilter) * 1e6;
        filtered = capturesData.filter(c => {
            const freq = c.frequency / 1e6;
            return Math.abs(freq - parseInt(frequencyFilter)) < 50;
        });
    }

    // Convert captures to heatmap data format
    // Format: [[lat, lng, intensity], ...]
    const heatmapData = filtered.map(capture => {
        // Use match confidence as intensity (default to 0.5 if no match)
        const intensity = capture.match_confidence || 0.5;
        return [capture.latitude, capture.longitude, intensity];
    });

    console.log(`Rendering heatmap with ${heatmapData.length} points`);

    // Create heatmap layer
    heatmapLayer = L.heatLayer(heatmapData, {
        radius: 25,           // Radius of each point
        blur: 15,             // Amount of blur
        maxZoom: 17,          // Zoom level where max intensity is reached
        max: 1.0,             // Maximum point intensity
        gradient: {           // Custom color gradient
            0.0: 'blue',
            0.3: 'cyan',
            0.5: 'lime',
            0.7: 'yellow',
            1.0: 'red'
        }
    });

    // Add to map
    map.addLayer(heatmapLayer);

    // Update count
    document.getElementById('total-captures').textContent = filtered.length;
}

// Export for external use
window.reloadMapData = loadCaptures;
