{% extends "base.html" %}
{% block css %}
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
     integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
     crossorigin=""/>
<style>
    .legend {
        background: white;
        padding: 8px;
        line-height: 1.5;
        border-radius: 5px;
        box-shadow: 0 0 10px rgba(0,0,0,0.3);
        font-size: 14px;
        color: black;
    }
    .legend i {
        width: 12px;
        height: 12px;
        display: inline-block;
        margin-right: 6px;
        border-radius: 50%;
    }
    #filter-container {
        text-align: center;
        margin-top: 10px;
    }
    .filter-checkbox {
        margin: 0 10px;
    }
</style>
{% endblock %}

{% block body %}
<div id="map" style="width: 100%; height: 600px;"></div>

<div id="filter-container">
    <!-- Filters will be dynamically generated here -->
</div>

<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
     integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
     crossorigin=""></script>

<div id="filter-container">
    <input type="checkbox" class="filter-checkbox" id="filter-routers-only"> Show Routers Only
</div>

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

    var markers = {};
    var bounds = L.latLngBounds();
    var channels = new Set(); // Stores unique channels

var nodes = [
{% for node in nodes %}
{
    lat: {{ (node.last_lat / 10**7)|round(7) }},
    long: {{ (node.last_long / 10**7)|round(7) if node.last_long is not none else "null" }},
    long_name: {{ (node.long_name or "") | tojson }},
    short_name: {{ (node.short_name or "") | tojson }},
    channel: {{ (node.channel or "") | tojson }},
    hw_model: {{ (node.hw_model or "") | tojson }},
    role: {{ (node.role or "") | tojson }},
    last_update: {{ node.last_update | default("", true) | tojson }},
    firmware: {{ (node.firmware or "") | tojson }},
    id: {{ (node.node_id or "") | tojson }},
    isRouter: "{{ 'router' in node.role.lower() }}"
}{{ "," if not loop.last else "" }}
{% endfor %}
];

    function timeAgo(date) {
        var now = new Date();
        var diff = now - new Date(date);
        var seconds = Math.floor(diff / 1000);
        var minutes = Math.floor(seconds / 60);
        var hours = Math.floor(minutes / 60);
        var days = Math.floor(hours / 24);

        if (days > 0) return days + "d";
        if (hours > 0) return hours + "h";
        if (minutes > 0) return minutes + "m";
        return seconds + "s";
    }

    const palette = [
        "#e6194b", // red
        "#4363d8", // blue
        "#f58231", // orange
        "#911eb4", // purple
        "#46f0f0", // cyan
        "#f032e6", // magenta
        "#bcf60c", // lime
        "#fabebe", // pink
        "#008080", // teal
        "#e6beff", // lavender
        "#9a6324", // brown
        "#fffac8", // cream
        "#800000", // maroon
        "#aaffc3", // mint
        "#808000", // olive
        "#ffd8b1", // apricot
        "#000075", // navy
        "#808080"  // gray
    ];

    const colorMap = new Map();
    let nextColorIndex = 0;

    function hashToColor(str) {
        if (colorMap.has(str)) return colorMap.get(str);

        const color = palette[nextColorIndex % palette.length];
        colorMap.set(str, color);
        nextColorIndex++;
        return color;
    }

        nodes.forEach(function(node) {
            if (node.lat !== null && node.long !== null) {
                let category = node.channel;
                let isRouter = node.isRouter === "True"; // Convert from string
                channels.add(category);

            let color = hashToColor(category);

            let markerOptions = {
                radius: isRouter ? 9 : 7,
                color: "white",
                fillColor: color,
                fillOpacity: 1,
                weight: 0.7,
            };

            var popupContent = `
                <b><a href="/packet_list/${node.id}">${node.long_name}</a> (${node.short_name})</b><br>
                <b>Channel:</b> ${node.channel}<br>
                <b>Model:</b> ${node.hw_model}<br>
                <b>Role:</b> ${node.role}<br>
            `;
            if (node.last_update) popupContent += `<b>Last seen:</b> ${timeAgo(node.last_update)}<br>`;
            if (node.firmware) popupContent += `<b>Firmware:</b> ${node.firmware}<br>`;

            var marker = L.circleMarker([node.lat, node.long], markerOptions).bindPopup(popupContent);
            marker.addTo(map);

            if (!markers[category]) markers[category] = [];
            markers[category].push({ marker, isRouter });

            bounds.extend(marker.getLatLng());
        }
    });

    var bayAreaBounds = [
        [{{ site_config["site"]["map_top_left_lat"] }}, {{ site_config["site"]["map_top_left_lon"] }}],
        [{{ site_config["site"]["map_bottom_right_lat"] }}, {{ site_config["site"]["map_bottom_right_lon"] }}]
    ];
    map.fitBounds(bayAreaBounds);

    let filterContainer = document.getElementById("filter-container");

    channels.forEach(channel => {
        let filterId = `filter-${channel.replace(/\s+/g, '-').toLowerCase()}`;
        let color = hashToColor(channel);
        let filterHtml = `
            <label style="color:${color};">
                <input type="checkbox" class="filter-checkbox" id="${filterId}" checked> ${channel}
            </label>
        `;
        filterContainer.innerHTML += filterHtml;
    });

    function updateMarkers() {
        let showRoutersOnly = document.getElementById("filter-routers-only").checked;

        channels.forEach(channel => {
            let filterId = `filter-${channel.replace(/\s+/g, '-').toLowerCase()}`;
            let isChecked = document.getElementById(filterId).checked;

            markers[channel].forEach(obj => {
                let shouldShow = isChecked && (!showRoutersOnly || obj.isRouter);
                shouldShow ? map.addLayer(obj.marker) : map.removeLayer(obj.marker);
            });
        });
    }

    document.querySelectorAll(".filter-checkbox").forEach(input => {
        input.addEventListener("change", updateMarkers);
    });

</script>

{% endblock %}