{% extends "mapsapp/map2d_base.html" %}
{% load static %}
{% block content %}

<div class="db-objects-panel"
    style="position: absolute; top: 100px; z-index: 1000; background: white; padding: 10px; border: 1px solid #ccc; border-radius: 5px;">
    <div class="panel-title">Объекты из базы</div>
    <select id="objectSelector" class="object-select">
        <option value="">— Выберите объект —</option>
        {% for sat in sats %}
        <option value="{{ sat.id }}">{{ sat.name }}</option>
        {% endfor %}
    </select>
    <button id="loadObjectBtn" class="load-btn" style="display: block; width: 100%; margin-top: 10px;">Все
        точки</button>
    <button id="loadObjectTransBtn" class="load-btn" style="display: block; width: 100%; margin-top: 10px;">Точки
        транспондеров</button>
    <button id="clearMarkersBtn" type="button" onclick="clearAllMarkers()"
        style="display: block; width: 100%; margin-top: 10px;">Очистить маркеры</button>


</div>

<div class="footprint-control"
    style="position: absolute; top: 270px; z-index: 1000; background: white; padding: 10px; border: 1px solid #ccc; border-radius: 5px;">
    <div class="panel-title">Области покрытия</div>
    <div class="footprint-actions">
        <button id="showAllFootprints">Показать все</button>
        <button id="hideAllFootprints">Скрыть все</button>
    </div>
    <div id="footprintToggles"></div>
</div>
{% endblock content %}

{% block extra_js %}
<script>
    function clearAllMarkers() {
        if (window.mainTreeControl && window.mainTreeControl._map) {
            map.removeControl(window.mainTreeControl);
            delete window.mainTreeControl;
            if (window.geoJsonOverlaysControl) {
                delete window.geoJsonOverlaysControl;
            }
        }
        map.eachLayer(function (layer) {
            if (!(layer instanceof L.TileLayer)) {
                map.removeLayer(layer);
            }
        });
    }
    let markerColors = ['red', 'green', 'orange', 'violet', 'grey', 'black', 'blue'];

    function getColorIcon(color) {
        return L.icon({
            iconUrl: '{% static "leaflet-markers/img/marker-icon-" %}' + color + '.png',
            shadowUrl: '{% static "leaflet-markers/img/marker-shadow.png" %}',
            iconSize: [25, 41],
            iconAnchor: [12, 41],
            popupAnchor: [1, -34],
            shadowSize: [41, 41]
        });
    }

    // --- Новая функция загрузки и отображения GeoJSON ---
    function loadGeoJsonForSatellite(satId) {
        if (!satId) {
            alert('Пожалуйста, выберите объект.');
            return;
        }

        if (window.mainTreeControl && window.mainTreeControl._map) {
            map.removeControl(window.mainTreeControl);
            delete window.mainTreeControl;
        }

        const url = `/api/locations/${encodeURIComponent(satId)}/geojson`;

        fetch(url)
            .then(response => {
                if (!response.ok) {
                    throw new Error('Сервер вернул ошибку: ' + response.status);
                }
                return response.json();
            })
            .then(data => {
                if (!data.features || data.features.length === 0) {
                    alert('Объекты с таким именем не найдены.');
                    return;
                }

                // --- Группировка данных по частоте ---
                const groupedByFreq = {};
                data.features.forEach(feature => {
                    const freq = feature.properties.freq / 1000000;
                    if (!groupedByFreq[freq]) {
                        groupedByFreq[freq] = [];
                    }
                    groupedByFreq[freq].push(feature);
                });

                // --- Создание overlay слоев для L.control.layers.tree ---
                const overlays = [];
                let freqIndex = 0;

                for (const [freq, features] of Object.entries(groupedByFreq)) {
                    const colorName = markerColors[freqIndex % markerColors.length];
                    const freqIcon = getColorIcon(colorName);
                    const freqGroupLayer = L.layerGroup();
                    const subgroup = [];

                    features.forEach((feature, idx) => {
                        const [lon, lat] = feature.geometry.coordinates;
                        const pointName = feature.properties.name || `Точка ${idx}`;
                        const marker = L.marker([lat, lon], { icon: freqIcon })
                            .bindPopup(`${pointName}<br>Частота: ${freq}`);
                        freqGroupLayer.addLayer(marker);

                        subgroup.push({
                            label: freq == -1 ? `${idx + 1} - Неизвестно` : `${idx + 1} - ${freq} МГц`,
                            layer: marker
                        });
                    });

                    // Группа для частоты
                    overlays.push({
                        label: `${features[0].properties.name} (${freq} МГц)`,
                        selectAllCheckbox: true,
                        children: subgroup,
                        layer: freqGroupLayer
                    });

                    freqIndex++;
                }
                const rootGroup = {
                    label: "Все точки",
                    selectAllCheckbox: true,
                    children: overlays,
                    layer: L.layerGroup()
                };

                const geoJsonControl = L.control.layers.tree(baseLayers, [rootGroup], {
                    collapsed: false,
                    autoZIndex: true
                });

                window.geoJsonOverlaysControl = geoJsonControl;
                if (window.mainTreeControl && window.mainTreeControl._map) {
                    map.removeControl(window.mainTreeControl);
                    delete window.mainTreeControl;
                }
                window.mainTreeControl = geoJsonControl.addTo(map);
            })
            .catch(err => {
                console.error('Ошибка загрузки GeoJSON:', err);
                alert('Не удалось загрузить объекты: ' + err.message);
                if (window.mainTreeControl && window.mainTreeControl._map) {
                    map.removeControl(window.mainTreeControl);
                    delete window.mainTreeControl;
                }
            });
    }

    function loadTranspondersPointsForSatellite(satId) {
        if (!satId) {
            alert('Пожалуйста, выберите объект.');
            return;
        }

        // --- Явная очистка перед началом ---
        if (window.mainTreeControl && window.mainTreeControl._map) {
            console.log('Удаляем старый контрол точек');
            map.removeControl(window.mainTreeControl);
            delete window.mainTreeControl;
            // window.geoJsonOverlaysControl также можно удалить, если он больше не нужен
            if (window.geoJsonOverlaysControl) {
                delete window.geoJsonOverlaysControl;
            }
        }
        // --- Конец очистки ---

        const url_points = `/api/locations/${encodeURIComponent(satId)}/geojson`;
        const url_trans = `/api/transponders/${encodeURIComponent(satId)}`;

        fetch(url_trans)
            .then(response => {
                if (!response.ok) {
                    throw new Error('Сервер вернул ошибку при загрузке транспондеров: ' + response.status);
                }
                return response.json();
            })
            .then(data_trans => {
                console.log('Загруженные транспондеры:', data_trans);

                return fetch(url_points)
                    .then(response => {
                        if (!response.ok) {
                            throw new Error('Сервер вернул ошибку при загрузке точек: ' + response.status);
                        }
                        return response.json();
                    })
                    .then(data_points => {
                        console.log('Загруженные точки:', data_points);
                        processAndDisplayTransponderPointsByZone(data_points, data_trans);
                    });
            })
            .catch(err => {
                console.error('Ошибка загрузки транспондеров или точек:', err);
                alert('Не удалось загрузить данные: ' + err.message);
                // Повторная проверка на случай ошибки
                if (window.mainTreeControl && window.mainTreeControl._map) {
                    map.removeControl(window.mainTreeControl);
                    delete window.mainTreeControl;
                    if (window.geoJsonOverlaysControl) {
                        delete window.geoJsonOverlaysControl;
                    }
                }
            });
    }

    function processAndDisplayTransponderPointsByZone(data_points, transpondersData) {
        if (!data_points.features || data_points.features.length === 0) {
            alert('Точки с таким идентификатором спутника не найдены.');
            return;
        }

        if (!transpondersData || !Array.isArray(transpondersData)) {
            console.error('Данные транспондеров недоступны или некорректны.');
            alert('Ошибка: данные транспондеров отсутствуют.');
            return;
        }

        // --- Функция для определения транспондера по частоте и поляризации ---
        function findTransponderForPoint(pointFreqHz, pointPolarization) {
            const pointFreqMhz = pointFreqHz / 1000000; // Переводим в МГц
            for (const trans of transpondersData) {
                if (typeof trans.frequency !== 'number' || typeof trans.frequency_range !== 'number' || typeof trans.polarization !== 'string') {
                    continue;
                }

                const centerFreq = trans.frequency;
                const bandwidth = trans.frequency_range;
                const halfBandwidth = bandwidth / 2;
                const lowerBound = centerFreq - halfBandwidth;
                const upperBound = centerFreq + halfBandwidth;

                if (
                    pointFreqMhz >= lowerBound &&
                    pointFreqMhz <= upperBound &&
                    pointPolarization === trans.polarization
                ) {
                    return trans;
                }
            }
            return null;
        }

        // --- Группировка точек по транспондерам ---
        const groupedByTransponder = {};
        data_points.features.forEach(feature => {
            const pointFreqHz = feature.properties.freq;
            let pointPolarization = feature.properties.polarization;
            if (pointPolarization === undefined || pointPolarization === null) {
                pointPolarization = feature.properties.pol;
            }
            if (pointPolarization === undefined || pointPolarization === null) {
                pointPolarization = feature.properties.polar;
            }
            if (pointPolarization === undefined || pointPolarization === null) {
                pointPolarization = feature.properties.polarisation;
            }
            if (pointPolarization === undefined || pointPolarization === null) {
                console.warn('Точка без поляризации, игнорируется:', feature);
                return;
            }

            const transponder = findTransponderForPoint(pointFreqHz, pointPolarization);

            if (transponder) {
                // --- ИСПРАВЛЕНО: используем name как уникальный идентификатор ---
                const transId = transponder.name;
                if (!groupedByTransponder[transId]) {
                    groupedByTransponder[transId] = {
                        transponder: transponder,
                        features: []
                    };
                }
                groupedByTransponder[transId].features.push(feature);
            } else {
                console.log(`Точка ${pointFreqHz / 1000000} МГц, ${pointPolarization} -> Не найден транспондер`);
            }
        });

        console.log('Сгруппированные данные:', groupedByTransponder);

        // --- Создание иерархии: зоны -> транспондеры -> точки (внутри слоя) ---
        const zonesMap = {};

        for (const [transId, groupData] of Object.entries(groupedByTransponder)) {
            const trans = groupData.transponder;
            const zoneName = trans.zone_name || 'Без зоны';

            if (!zonesMap[zoneName]) {
                zonesMap[zoneName] = [];
            }
            zonesMap[zoneName].push({
                transponder: trans,
                features: groupData.features
            });
        }

        console.log('Сгруппировано по зонам:', zonesMap);

        // --- Создание overlay слоев для L.control.layers.tree ---
        const overlays = [];
        let zoneIndex = 0;

        for (const [zoneName, transponderGroups] of Object.entries(zonesMap)) {
            const zoneGroupLayer = L.layerGroup();
            const zoneChildren = [];

            let transIndex = 0;
            for (const transGroup of transponderGroups) {
                const trans = transGroup.transponder;
                const features = transGroup.features;

                // Слой для одного транспондера
                const transGroupLayer = L.layerGroup();

                // Проходим по точкам транспондера
                features.forEach(feature => {
                    const [lon, lat] = feature.geometry.coordinates;
                    const pointName = feature.properties.name || `Точка`;
                    const pointFreqHz = feature.properties.freq;
                    const pointFreqMhz = (pointFreqHz / 1000000).toFixed(2);
                    const pointPolarization = feature.properties.polarization || feature.properties.pol || feature.properties.polar || feature.properties.polarisation || '?';

                    // --- НОВОЕ: определяем цвет по частоте точки ---
                    // Округляем частоту до ближайшего целого Гц или, например, до 1000 Гц (1 кГц) для группировки
                    // const freqKey = Math.round(pointFreqHz / 1000); // Группировка по 1 кГц
                    const freqKey = Math.round(pointFreqHz); // Группировка по 1 Гц (можно изменить)
                    const colorIndex = freqKey % markerColors.length; // Индекс цвета зависит от частоты
                    const colorName = markerColors[colorIndex];
                    const pointIcon = getColorIcon(colorName); // Создаём иконку с цветом для этой точки

                    const marker = L.marker([lat, lon], { icon: pointIcon }) // Используем иконку точки
                        .bindPopup(`${pointName}<br>Частота: ${pointFreqMhz} МГц<br>Поляр.: ${pointPolarization}<br>Транспондер: ${trans.name}<br>Зона: ${trans.zone_name}`);
                    transGroupLayer.addLayer(marker);
                });

                // Добавляем транспондер в дочерние элементы зоны
                // Транспондер не будет иметь фиксированного цвета, только его точки
                const lowerBound = (trans.frequency - trans.frequency_range / 2).toFixed(2);
                const upperBound = (trans.frequency + trans.frequency_range / 2).toFixed(2);
                zoneChildren.push({
                    label: `${trans.name} (${lowerBound} - ${upperBound})`,
                    selectAllCheckbox: true,
                    layer: transGroupLayer // Этот слой содержит точки с разными цветами
                });

                zoneGroupLayer.addLayer(transGroupLayer);
                transIndex++;
            }

            overlays.push({
                label: zoneName,
                selectAllCheckbox: true,
                children: zoneChildren,
                layer: zoneGroupLayer
            });

            zoneIndex++;
        }

        // --- Корневая группа ---
        const rootGroup = {
            label: "Все точки",
            selectAllCheckbox: true,
            children: overlays,
            layer: L.layerGroup()
        };

        // --- Создаем контрол и добавляем на карту ---
        const geoJsonControl = L.control.layers.tree(baseLayers, [rootGroup], {
            collapsed: false,
            autoZIndex: true
        });

        window.geoJsonOverlaysControl = geoJsonControl;
        if (window.mainTreeControl && window.mainTreeControl._map) {
            map.removeControl(window.mainTreeControl);
            delete window.mainTreeControl;
        }
        window.mainTreeControl = geoJsonControl.addTo(map);
    }

    // --- Обработчики событий ---
    document.addEventListener('DOMContentLoaded', () => {
        const select = document.getElementById('objectSelector');
        select.selectedIndex = 0;
        const loadBtn = document.getElementById('loadObjectBtn');
        const transBtn = document.getElementById('loadObjectTransBtn')

        // Загружаем footprint'ы при смене выбора
        select.addEventListener('change', function () {
            const satId = this.value;
            console.log(satId);
            loadFootprintsForSatellite(satId);
        });

        // Загружаем GeoJSON при нажатии кнопки
        loadBtn.addEventListener('click', function () {
            const satId = select.value;
            loadGeoJsonForSatellite(satId);
        });

        transBtn.addEventListener('click', function () {
            const satId = select.value;
            loadTranspondersPointsForSatellite(satId);
        });
    });
    let currentFootprintLayers = {};
    let currentSatelliteId = null;

    const togglesContainer = document.getElementById('footprintToggles');
    const showAllBtn = document.getElementById('showAllFootprints');
    const hideAllBtn = document.getElementById('hideAllFootprints');

    // --- Функции ---

    function escapeHtml(unsafe) {
        // Простая функция для экранирования HTML-символов в именах
        return unsafe
            .replace(/&/g, "&amp;")
            .replace(/</g, "<")
            .replace(/>/g, ">")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }

    function clearFootprintUIAndLayers() {
        // Удаляем все текущие слои footprint'ов с карты и очищаем объект
        Object.entries(currentFootprintLayers).forEach(([name, layer]) => {
            if (map.hasLayer(layer)) {
                map.removeLayer(layer);
            }
        });
        currentFootprintLayers = {};

        // Очищаем контейнер с чекбоксами
        togglesContainer.innerHTML = '';
    }

    function loadFootprintsForSatellite(satId) {
        // Проверка, если satId пустой - очищаем
        if (!satId) {
            clearFootprintUIAndLayers();
            currentSatelliteId = null;
            return;
        }

        // Сохраняем текущий ID спутника
        currentSatelliteId = satId;

        const url = `/api/footprint-names/${encodeURIComponent(satId)}`;

        fetch(url)
            .then(response => {
                if (!response.ok) {
                    throw new Error('Ошибка загрузки footprint\'ов: ' + response.statusText);
                }
                return response.json();
            })
            .then(footprints => {
                if (!Array.isArray(footprints)) {
                    throw new Error('Ожидался массив footprint\'ов');
                }

                // Очищаем старое состояние
                clearFootprintUIAndLayers();

                // Создаём новые слои и чекбоксы
                footprints.forEach(fp => {
                    // 1. Создаём тайловый слой Leaflet
                    // Убедитесь, что URL соответствует вашей структуре тайлов
                    const layer = L.tileLayer(`/tiles/${fp.name}/{z}/{x}/{y}.png`, {
                        minZoom: 0,
                        maxZoom: 21, // Установите соответствующий maxZoom
                        opacity: 0.7, // Установите нужную прозрачность
                        // attribution: 'SatBeams Rendered' // Можно добавить атрибуцию
                    });

                    // Слои изначально ДОБАВЛЕНЫ на карту (и видимы), если хотите изначально скрытыми - закомментируйте следующую строку
                    layer.addTo(map);

                    // Сохраняем слой в объекте
                    currentFootprintLayers[fp.name] = layer;

                    const safeNameAttr = encodeURIComponent(fp.name); // для data-атрибута
                    const safeFullName = escapeHtml(fp.fullname);     // для отображения

                    // 2. Создаём чекбокс и метку
                    const label = document.createElement('label');
                    label.style.display = 'block';
                    label.style.margin = '4px 0';
                    // Чекбокс изначально отмечен, если слой добавлен на карту
                    label.innerHTML = `
                    <input type="checkbox"
                        data-footprint="${safeNameAttr}"
                        checked> <!-- Отмечен, так как слой добавлен -->
                    ${safeFullName}
                `;
                    togglesContainer.appendChild(label);

                    // 3. Связываем чекбокс со слоем
                    const checkbox = label.querySelector('input');
                    checkbox.addEventListener('change', function () {
                        const footprintName = decodeURIComponent(this.dataset.footprint);
                        const layer = currentFootprintLayers[footprintName];
                        if (layer) {
                            if (this.checked && !map.hasLayer(layer)) {
                                // Если чекбокс отмечен и слой не на карте - добавляем
                                map.addLayer(layer);
                            } else if (!this.checked && map.hasLayer(layer)) {
                                // Если чекбокс снят и слой на карте - удаляем
                                map.removeLayer(layer);
                            }
                        }
                    });
                });
            })
            .catch(err => {
                console.error('Ошибка загрузки footprint\'ов:', err);
                alert('Не удалось загрузить области покрытия: ' + err.message);
                clearFootprintUIAndLayers(); // При ошибке очищаем UI
            });
    }


    function showAllFootprints() {
        Object.entries(currentFootprintLayers).forEach(([name, layer]) => {
            if (!map.hasLayer(layer)) {
                map.addLayer(layer);
            }
        });
        // Синхронизируем чекбоксы
        document.querySelectorAll('#footprintToggles input[type="checkbox"]').forEach(cb => {
            cb.checked = true;
        });
    }

    function hideAllFootprints() {
        Object.entries(currentFootprintLayers).forEach(([name, layer]) => {
            if (map.hasLayer(layer)) {
                map.removeLayer(layer);
            }
        });
        document.querySelectorAll('#footprintToggles input[type="checkbox"]').forEach(cb => {
            cb.checked = false;
        });
    }

    // --- Обработчики событий для кнопок ---
    showAllBtn.addEventListener('click', showAllFootprints);
    hideAllBtn.addEventListener('click', hideAllFootprints);
</script>
{% endblock extra_js %}