{% extends "mainapp/base.html" %}
{% load static %}
{% block title %}Карта объекта #{{ source_id }} с точками{% endblock title %}

{% block extra_css %}
<!-- Leaflet CSS -->
<link href="{% static 'leaflet/leaflet.css' %}" rel="stylesheet">
<link href="{% static 'leaflet-measure/leaflet-measure.css' %}" rel="stylesheet">
<link href="{% static 'leaflet-tree/L.Control.Layers.Tree.css' %}" rel="stylesheet">
<!-- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/leaflet-playback@1.0.2/dist/LeafletPlayback.css" /> -->
<style>
    body {
        overflow: hidden;
    }
    #map {
        position: fixed;
        top: 56px; /* Высота navbar */
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 1;
    }
    .legend {
        background: white;
        padding: 8px;
        border-radius: 4px;
        box-shadow: 0 0 10px rgba(0,0,0,0.2);
        font-size: 11px;
    }
    .legend h6 {
        font-size: 12px;
        margin: 0 0 6px 0;
    }
    .legend-item {
        margin: 3px 0;
        display: flex;
        align-items: center;
    }
    .legend-marker {
        width: 18px;
        height: 30px;
        margin-right: 6px;
        background-size: contain;
        background-repeat: no-repeat;
    }
    .legend-section {
        margin-top: 8px;
        padding-top: 8px;
        border-top: 1px solid #ddd;
    }
    .legend-section:first-child {
        margin-top: 0;
        padding-top: 0;
        border-top: none;
    }
    .legend-section-title {
        font-weight: bold;
        font-size: 11px;
        margin-bottom: 4px;
    }
    .playback-control {
        position: fixed;
        bottom: 20px;
        left: 50%;
        transform: translateX(-50%);
        z-index: 1000;
        background: white;
        padding: 15px 20px;
        border-radius: 8px;
        box-shadow: 0 2px 10px rgba(0,0,0,0.3);
        display: flex;
        align-items: center;
        gap: 15px;
    }
    .playback-control button {
        padding: 6px 12px;
        border: none;
        border-radius: 4px;
        background: #007bff;
        color: white;
        cursor: pointer;
        font-size: 13px;
        min-width: auto;
    }
    .playback-control button:hover {
        background: #0056b3;
    }
    .playback-control button:disabled {
        background: #ccc;
        cursor: not-allowed;
    }
    .playback-control .time-display {
        font-size: 13px;
        font-weight: bold;
        min-width: 160px;
        text-align: center;
    }
    .playback-control input[type="range"] {
        width: 250px;
    }
    .playback-control .speed-control {
        display: flex;
        align-items: center;
        gap: 6px;
    }
    .playback-control .speed-control label {
        font-size: 11px;
        margin: 0;
    }
    .playback-control .speed-control select {
        padding: 3px 6px;
        border-radius: 4px;
        border: 1px solid #ccc;
        font-size: 12px;
    }
    .playback-control .visibility-controls {
        display: flex;
        flex-direction: column;
        gap: 4px;
        border-left: 1px solid #ddd;
        padding-left: 15px;
        margin-left: 10px;
    }
    .playback-control .visibility-controls label {
        display: flex;
        align-items: center;
        gap: 5px;
        font-size: 11px;
        margin: 0;
        cursor: pointer;
    }
    .playback-control .visibility-controls input[type="checkbox"] {
        cursor: pointer;
    }
</style>
{% endblock %}

{% block content %}
<div id="map"></div>
<div class="playback-control" id="playbackControl" style="display: none;">
    <button id="playBtn">▶</button>
    <button id="pauseBtn" disabled>⏸</button>
    <button id="resetBtn">⏮</button>
    <input type="range" id="timeSlider" min="0" max="100" value="0" step="1">
    <div class="time-display" id="timeDisplay">--</div>
    <div class="speed-control">
        <label for="speedSelect">Скорость:</label>
        <select id="speedSelect">
            <option value="0.5">0.5x</option>
            <option value="1" selected>1x</option>
            <option value="2">2x</option>
            <option value="5">5x</option>
            <option value="10">10x</option>
        </select>
    </div>
    <div class="visibility-controls">
        <label>
            <input type="checkbox" id="showPointsCheckbox" checked>
            Точки
        </label>
        <label>
            <input type="checkbox" id="showTrackCheckbox" checked>
            Трек
        </label>
    </div>
</div>
{% endblock content %}

{% block extra_js %}
<!-- Leaflet JavaScript -->
<script src="{% static 'leaflet/leaflet.js' %}"></script>
<script src="{% static 'leaflet-measure/leaflet-measure.ru.js' %}"></script>
<script src="{% static 'leaflet-tree/L.Control.Layers.Tree.js' %}"></script>
<script src="{% static 'leaflet-polylineDecorator/leaflet.polylineDecorator.js' %}"></script>
<script src="{% static 'leaflet-playback/leaflet-playback.js' %}"></script>

<script>
    // Инициализация карты
    let map = L.map('map').setView([55.75, 37.62], 5);
    L.control.scale({
        imperial: false,
        metric: true
    }).addTo(map);
    map.attributionControl.setPrefix(false);
    
    const street = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    });
    street.addTo(map);
    
    const satellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
        attribution: 'Tiles &copy; Esri'
    });
    
    const street_local = L.tileLayer('/tiles/styles/basic-preview/512/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: 'Local Tiles'
    });
    
    const baseLayers = {
        "Улицы": street,
        "Спутник": satellite,
        "Локально": street_local
    };
    
    L.control.layers(baseLayers).addTo(map);
    map.setMaxZoom(18);
    map.setMinZoom(0);
    L.control.measure({ primaryLengthUnit: 'kilometers' }).addTo(map);

    // Функция для создания иконки
    var getColorIcon = function(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]
        });
    };

    var sourceOverlays = [];
    var glPointLayers = [];
    var glPointCoordinates = [];
    var glPointsData = [];
    var trackLayer = L.layerGroup(); // Layer group for track and related elements
    var glPointsGroupLayer = L.layerGroup(); // Layer group specifically for GL points

    // Сначала собираем все данные о точках ГЛ с временными метками
    {% for group in groups %}
        {% for point_data in group.points %}
            {% if not point_data.source_id %}
                glPointsData.push({
                    name: "{{ point_data.name|escapejs }}",
                    frequency: "{{ point_data.frequency|escapejs }}",
                    coords: [{{ point_data.point.1|safe }}, {{ point_data.point.0|safe }}],
                    timestamp: {% if point_data.timestamp %}"{{ point_data.timestamp|escapejs }}"{% else %}null{% endif %}
                });
            {% endif %}
        {% endfor %}
    {% endfor %}
    
    // Фильтруем точки с временными метками и сортируем
    var glPointsWithTime = glPointsData.filter(p => p.timestamp !== null);
    glPointsWithTime.sort((a, b) => new Date(a.timestamp) - new Date(b.timestamp));

    // Создаём слои для координат объекта и точек ГЛ
    {% for group in groups %}
        var groupName = '{{ group.name|escapejs }}';
        var colorName = '{{ group.color }}';
        var groupIcon = getColorIcon(colorName);
        var groupLayer = L.layerGroup();

        {% for point_data in group.points %}
            {% if point_data.source_id %}
                // Это координата объекта
                var pointName = "{{ point_data.source_id|escapejs }}";
                var marker = L.marker([{{ point_data.point.1|safe }}, {{ point_data.point.0|safe }}], {
                    icon: groupIcon
                }).bindPopup(pointName);
                groupLayer.addLayer(marker);
            {% else %}
                // Это точка ГЛ
                var pointName = "{{ point_data.name|escapejs }}";
                var pointCoords = [{{ point_data.point.1|safe }}, {{ point_data.point.0|safe }}];
                var pointNumber = {{ forloop.counter }};

                // Определяем цвет маркера: первый - зеленый, последний - оранжевый, остальные - обычный
                var markerIcon;
                if (pointNumber === 1) {
                    markerIcon = getColorIcon('green');
                } else if (pointNumber === glPointsData.length) {
                    markerIcon = getColorIcon('orange');
                } else {
                    markerIcon = groupIcon;
                }

                var marker = L.marker(pointCoords, {
                    icon: markerIcon
                }).bindPopup(pointNumber + '. ' + pointName + '<br>' + "{{ point_data.frequency|escapejs }}");
                groupLayer.addLayer(marker);
                glPointsGroupLayer.addLayer(marker); // Also add to GL points group layer

                // Сохраняем координаты для построения трека
                glPointCoordinates.push(pointCoords);

                // Добавляем каждую точку ГЛ отдельно в список
                glPointLayers.push({
                    label: pointNumber + " - {{ point_data.name|escapejs }} ({{ point_data.frequency|escapejs }})",
                    layer: marker
                });
            {% endif %}
        {% endfor %}

        // Для координат объекта добавляем как отдельный слой без вложенности
        {% if group.color in 'blue,orange,green,violet' %}
            sourceOverlays.push({
                label: groupName,
                layer: groupLayer
            });
        {% endif %}

        // НЕ добавляем слой группы на карту при загрузке - будет управляться через layer control
        {% if group.color in 'blue,orange,green,violet' %}
            // groupLayer.addTo(map); // Закомментировано - слои скрыты по умолчанию
        {% endif %}
    {% endfor %}

    // Создаём трек между точками ГЛ с номерами на сегментах
    if (glPointCoordinates.length > 1) {
        // Создаём отдельные сегменты линий между точками
        for (var i = 0; i < glPointCoordinates.length - 1; i++) {
            var segmentNumber = i + 1;

            // Создаем линию с стрелкой
            var segment = L.polyline([glPointCoordinates[i], glPointCoordinates[i + 1]], {
                color: 'blue',
                weight: 3,
                opacity: 0.7
            });
            trackLayer.addLayer(segment);

            // Добавляем стрелку через декоратор
            setTimeout(function(seg, segLayer, num) {
                return function() {
                    var decorator = L.polylineDecorator(seg, {
                        patterns: [
                            {
                                offset: '65%',
                                repeat: 0,
                                symbol: L.Symbol.arrowHead({
                                    pixelSize: 15,
                                    polygon: false,
                                    pathOptions: {
                                        stroke: true,
                                        color: 'blue',
                                        weight: 3,
                                        opacity: 0.7
                                    }
                                })
                            }
                        ]
                    });
                    segLayer.addLayer(decorator);
                };
            }(segment, trackLayer, segmentNumber), 100);

            // Вычисляем центр сегмента для размещения номера
            var midLat = (glPointCoordinates[i][0] + glPointCoordinates[i + 1][0]) / 2;
            var midLng = (glPointCoordinates[i][1] + glPointCoordinates[i + 1][1]) / 2;

            // Добавляем номер сегмента
            var segmentIcon = L.divIcon({
                className: 'segment-label',
                html: '<div style="background: rgba(0, 0, 255, 0.9); color: white; border: 2px solid white; border-radius: 50%; width: 28px; height: 28px; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 14px; box-shadow: 0 2px 4px rgba(0,0,0,0.4);">' + segmentNumber + '</div>',
                iconSize: [28, 28],
                iconAnchor: [14, 14]
            });
            var segmentMarker = L.marker([midLat, midLng], { icon: segmentIcon });
            trackLayer.addLayer(segmentMarker);
        }

        // НЕ добавляем слой трека на карту при загрузке - будет управляться через playback
        // trackLayer.addTo(map);
    }

    // НЕ добавляем GL точки на карту при загрузке - будет управляться через playback
    // if (glPointLayers.length > 0) {
    //     glPointsGroupLayer.addTo(map);
    // }

    // Создаём иерархию
    var treeOverlays = [];

    if (sourceOverlays.length > 0) {
        treeOverlays.push({
            label: "Координаты объекта #{{ source_id }}",
            selectAllCheckbox: true,
            children: sourceOverlays,
            layer: L.layerGroup()
        });
    }

    if (glPointLayers.length > 0) {
        treeOverlays.push({
            label: "Точки ГЛ",
            selectAllCheckbox: true,
            children: glPointLayers,
            layer: glPointsGroupLayer
        });
    }

    // Добавляем слой трека в контрол
    if (glPointCoordinates.length > 1) {
        treeOverlays.push({
            label: "Трек между точками ГЛ",
            layer: trackLayer
        });
    }

    // Создаём tree control
    const layerControl = L.control.layers.tree(baseLayers, treeOverlays, {
        collapsed: false,
        autoZIndex: true
    });
    layerControl.addTo(map);

    // Подгоняем карту под все маркеры
    {% if groups %}
        var groupBounds = L.featureGroup([]);
        {% for group in groups %}
            {% for point_data in group.points %}
                groupBounds.addLayer(L.marker([{{ point_data.point.1|safe }}, {{ point_data.point.0|safe }}]));
            {% endfor %}
        {% endfor %}
        map.fitBounds(groupBounds.getBounds().pad(0.1));
    {% endif %}

    // Добавляем легенду в левый нижний угол
    var legend = L.control({ position: 'bottomleft' });
    legend.onAdd = function(map) {
        var div = L.DomUtil.create('div', 'legend');
        div.innerHTML = '<h6><strong>Легенда</strong></h6>';
        
        // Координаты объекта
        var hasSourceCoords = false;
        {% for group in groups %}
            {% if group.color in 'blue,orange,green,violet' %}
                {% if not hasSourceCoords %}
                    if (!hasSourceCoords) {
                        div.innerHTML += '<div class="legend-section-title">Координаты объекта:</div>';
                        hasSourceCoords = true;
                    }
                {% endif %}
                div.innerHTML += `
                    <div class="legend-item">
                        <div class="legend-marker" style="background-image: url('{% static "leaflet-markers/img/marker-icon-" %}{{ group.color }}.png');"></div>
                        <span>{{ group.name|escapejs }}</span>
                    </div>
                `;
            {% endif %}
        {% endfor %}
        
        // Точки ГЛ
        {% for group in groups %}
            {% if group.color not in 'blue,orange,green,violet' %}
                div.innerHTML += '<div class="legend-section"><div class="legend-section-title">Точки ГЛ:</div></div>';
                div.innerHTML += `
                    <div class="legend-item">
                        <div class="legend-marker" style="background-image: url('{% static "leaflet-markers/img/marker-icon-" %}{{ group.color }}.png');"></div>
                        <span>{{ group.name|escapejs }}</span>
                    </div>
                `;
            {% endif %}
        {% endfor %}

        // Добавляем информацию о треке
        if (glPointCoordinates.length > 1) {
            div.innerHTML += '<div class="legend-section"><div class="legend-section-title">Трек между точками:</div></div>';
            div.innerHTML += `
                <div class="legend-item">
                    <div style="width: 18px; height: 3px; background: blue; margin-right: 6px;"></div>
                    <span>Соединительная линия</span>
                </div>
            `;
        }

        // Добавляем информацию о специальных точках
        if (glPointCoordinates.length > 1) {
            div.innerHTML += '<div class="legend-section"><div class="legend-section-title">Специальные точки:</div></div>';
            div.innerHTML += `
                <div class="legend-item">
                    <div class="legend-marker" style="background-image: url('{% static "leaflet-markers/img/marker-icon-green.png" %}');"></div>
                    <span>Первая точка</span>
                </div>
                <div class="legend-item">
                    <div class="legend-marker" style="background-image: url('{% static "leaflet-markers/img/marker-icon-orange.png" %}');"></div>
                    <span>Последняя точка</span>
                </div>
            `;
        }
        
        // Добавляем информацию о playback (если доступен)
        if (glPointsWithTime && glPointsWithTime.length > 1) {
            div.innerHTML += '<div class="legend-section"><div class="legend-section-title">Режим воспроизведения:</div></div>';
            div.innerHTML += `
                <div class="legend-item">
                    <div class="legend-marker" style="background-image: url('{% static "leaflet-markers/img/marker-icon-grey.png" %}');"></div>
                    <span>Пройденные точки</span>
                </div>
                <div class="legend-item">
                    <div style="width: 24px; height: 24px; margin-right: 6px; background: rgba(0, 0, 255, 0.9); color: white; border: 2px solid white; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 11px;">1</div>
                    <span>Номер сегмента трека</span>
                </div>
                <div class="legend-item">
                    <div style="width: 18px; height: 18px; margin-right: 6px; background: #007bff; border-radius: 3px; display: flex; align-items: center; justify-content: center; color: white; font-size: 10px;">▶</div>
                    <span>Используйте панель внизу</span>
                </div>
            `;
        }

        return div;
    };
    legend.addTo(map);

    // ============ PLAYBACK FUNCTIONALITY ============
    var playbackData = null;
    var currentPlaybackIndex = 0;
    var playbackInterval = null;
    var playbackMarkers = [];
    var playbackPolyline = null;
    var playbackSpeed = 1000; // milliseconds per step
    
    // Показываем контроллер только если есть точки с временными метками
    if (glPointsWithTime.length > 1) {
        document.getElementById('playbackControl').style.display = 'flex';
        
        // Инициализация слайдера
        var timeSlider = document.getElementById('timeSlider');
        timeSlider.max = glPointsWithTime.length - 1;
        
        // Функция для форматирования даты
        function formatDate(isoString) {
            var date = new Date(isoString);
            return date.toLocaleString('ru-RU', {
                year: 'numeric',
                month: '2-digit',
                day: '2-digit',
                hour: '2-digit',
                minute: '2-digit'
            });
        }
        
        // Функция для обновления отображения времени
        function updateTimeDisplay(index) {
            var timeDisplay = document.getElementById('timeDisplay');
            if (index >= 0 && index < glPointsWithTime.length) {
                timeDisplay.textContent = formatDate(glPointsWithTime[index].timestamp);
            }
        }
        
        // Функция для отрисовки точек до указанного индекса
        function renderPlaybackState(index) {
            // Очищаем предыдущие маркеры
            playbackMarkers.forEach(m => map.removeLayer(m));
            playbackMarkers = [];
            
            if (playbackPolyline) {
                map.removeLayer(playbackPolyline);
            }
            
            // Проверяем состояние чекбоксов
            var showPoints = document.getElementById('showPointsCheckbox').checked;
            var showTrack = document.getElementById('showTrackCheckbox').checked;
            
            // Рисуем все точки до текущего индекса
            var coords = [];
            for (var i = 0; i <= index; i++) {
                var point = glPointsWithTime[i];
                coords.push(point.coords);
                
                if (showPoints) {
                    var markerIcon;
                    
                    // Первая точка - зеленая, текущая - оранжевая, остальные - серые
                    if (i === 0) {
                        markerIcon = getColorIcon('green');
                    } else if (i === index) {
                        markerIcon = getColorIcon('orange');
                    } else {
                        markerIcon = getColorIcon('grey');
                    }
                    
                    var marker = L.marker(point.coords, { icon: markerIcon })
                        .bindPopup((i + 1) + '. ' + point.name + '<br>' + point.frequency + '<br>' + formatDate(point.timestamp));
                    marker.addTo(map);
                    playbackMarkers.push(marker);
                }
            }
            
            // Рисуем линию трека с номерами сегментов
            if (showTrack && coords.length > 1) {
                // Рисуем отдельные сегменты с номерами
                for (var i = 0; i < coords.length - 1; i++) {
                    var segmentNumber = i + 1;
                    
                    // Создаем линию сегмента
                    var segment = L.polyline([coords[i], coords[i + 1]], {
                        color: 'blue',
                        weight: 3,
                        opacity: 0.7
                    }).addTo(map);
                    playbackMarkers.push(segment);
                    
                    // Добавляем стрелку на последний сегмент
                    if (i === coords.length - 2) {
                        var decorator = L.polylineDecorator(segment, {
                            patterns: [{
                                offset: '65%',
                                repeat: 0,
                                symbol: L.Symbol.arrowHead({
                                    pixelSize: 15,
                                    polygon: false,
                                    pathOptions: {
                                        stroke: true,
                                        color: 'blue',
                                        weight: 3,
                                        opacity: 0.7
                                    }
                                })
                            }]
                        }).addTo(map);
                        playbackMarkers.push(decorator);
                    }
                    
                    // Вычисляем центр сегмента для размещения номера
                    var midLat = (coords[i][0] + coords[i + 1][0]) / 2;
                    var midLng = (coords[i][1] + coords[i + 1][1]) / 2;
                    
                    // Добавляем номер сегмента
                    var segmentIcon = L.divIcon({
                        className: 'segment-label',
                        html: '<div style="background: rgba(0, 0, 255, 0.9); color: white; border: 2px solid white; border-radius: 50%; width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; font-weight: bold; font-size: 12px; box-shadow: 0 2px 4px rgba(0,0,0,0.4);">' + segmentNumber + '</div>',
                        iconSize: [24, 24],
                        iconAnchor: [12, 12]
                    });
                    var segmentMarker = L.marker([midLat, midLng], { icon: segmentIcon });
                    segmentMarker.addTo(map);
                    playbackMarkers.push(segmentMarker);
                }
            }
            
            updateTimeDisplay(index);
            timeSlider.value = index;
        }
        
        // Кнопка воспроизведения
        document.getElementById('playBtn').addEventListener('click', function() {
            if (playbackInterval) return;
            
            this.disabled = true;
            document.getElementById('pauseBtn').disabled = false;
            
            playbackInterval = setInterval(function() {
                currentPlaybackIndex++;
                
                if (currentPlaybackIndex >= glPointsWithTime.length) {
                    // Достигли конца
                    clearInterval(playbackInterval);
                    playbackInterval = null;
                    document.getElementById('playBtn').disabled = false;
                    document.getElementById('pauseBtn').disabled = true;
                    currentPlaybackIndex = glPointsWithTime.length - 1;
                } else {
                    renderPlaybackState(currentPlaybackIndex);
                }
            }, playbackSpeed);
        });
        
        // Кнопка паузы
        document.getElementById('pauseBtn').addEventListener('click', function() {
            if (playbackInterval) {
                clearInterval(playbackInterval);
                playbackInterval = null;
                document.getElementById('playBtn').disabled = false;
                this.disabled = true;
            }
        });
        
        // Кнопка сброса
        document.getElementById('resetBtn').addEventListener('click', function() {
            if (playbackInterval) {
                clearInterval(playbackInterval);
                playbackInterval = null;
            }
            
            currentPlaybackIndex = 0;
            renderPlaybackState(0);
            
            document.getElementById('playBtn').disabled = false;
            document.getElementById('pauseBtn').disabled = true;
        });
        
        // Слайдер времени
        timeSlider.addEventListener('input', function() {
            if (playbackInterval) {
                clearInterval(playbackInterval);
                playbackInterval = null;
                document.getElementById('playBtn').disabled = false;
                document.getElementById('pauseBtn').disabled = true;
            }
            
            currentPlaybackIndex = parseInt(this.value);
            renderPlaybackState(currentPlaybackIndex);
        });
        
        // Выбор скорости
        document.getElementById('speedSelect').addEventListener('change', function() {
            var speedMultiplier = parseFloat(this.value);
            playbackSpeed = 1000 / speedMultiplier;
            
            // Если воспроизведение активно, перезапускаем с новой скоростью
            if (playbackInterval) {
                clearInterval(playbackInterval);
                document.getElementById('pauseBtn').click();
                setTimeout(function() {
                    document.getElementById('playBtn').click();
                }, 100);
            }
        });
        
        // Обработчики для чекбоксов видимости
        document.getElementById('showPointsCheckbox').addEventListener('change', function() {
            renderPlaybackState(currentPlaybackIndex);
        });
        
        document.getElementById('showTrackCheckbox').addEventListener('change', function() {
            renderPlaybackState(currentPlaybackIndex);
        });
        
        // Инициализация - показываем первую точку
        renderPlaybackState(0);
    }
</script>
{% endblock extra_js %}
