{% extends "mainapp/base.html" %}
{% load static %}
{% block title %}Карта объектов{% endblock title %}

{% block extra_css %}
<!-- MapLibre GL CSS -->
<link href="{% static 'maplibre/maplibre-gl.css' %}" rel="stylesheet">
<style>
    body {
        overflow: hidden;
    }
    #map {
        position: fixed;
        top: 56px;
        bottom: 0;
        left: 0;
        right: 0;
        z-index: 0;
    }

    /* Легенда */
    .maplibregl-ctrl-legend {
        background: white;
        padding: 10px;
        border-radius: 4px;
        box-shadow: 0 0 0 2px rgba(0,0,0,.1);
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        font-size: 11px;
        max-height: 400px;
        overflow-y: auto;
    }
    
    .maplibregl-ctrl-legend h6 {
        font-size: 12px;
        margin: 0 0 8px 0;
        font-weight: bold;
    }
    
    .legend-item {
        margin: 4px 0;
        display: flex;
        align-items: center;
        padding: 2px;
    }
    
    .legend-marker {
        width: 12px;
        height: 12px;
        margin-right: 8px;
        border-radius: 50%;
        border: 2px solid white;
        box-shadow: 0 0 3px rgba(0,0,0,0.3);
    }
    
    .legend-section {
        margin-bottom: 8px;
        padding-bottom: 6px;
        border-bottom: 1px solid #ddd;
    }
    
    .legend-section:last-child {
        border-bottom: none;
        margin-bottom: 0;
    }

    /* Слои контрол */
    .maplibregl-ctrl-layers {
        background: white;
        padding: 10px;
        border-radius: 4px;
        box-shadow: 0 0 0 2px rgba(0,0,0,.1);
        font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
        max-width: 250px;
        max-height: 400px;
        overflow-y: auto;
    }
    
    .maplibregl-ctrl-layers h6 {
        margin: 0 0 10px 0;
        font-size: 13px;
        font-weight: bold;
    }
    
    .layer-item {
        margin: 5px 0;
        font-size: 12px;
    }
    
    .layer-item label {
        cursor: pointer;
        display: flex;
        align-items: center;
        gap: 5px;
        user-select: none;
    }
    
    .layer-item input[type="checkbox"] {
        cursor: pointer;
    }

    /* Кастомные кнопки контролов */
    .maplibregl-ctrl-projection .maplibregl-ctrl-icon,
    .maplibregl-ctrl-3d .maplibregl-ctrl-icon,
    .maplibregl-ctrl-style .maplibregl-ctrl-icon {
        background-size: 20px 20px;
        background-position: center;
        background-repeat: no-repeat;
    }
    
    .maplibregl-ctrl-projection .maplibregl-ctrl-icon {
        background-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><circle cx="10" cy="10" r="6" fill="none" stroke="%23333" stroke-width="1.5"/><ellipse cx="10" cy="10" rx="3" ry="6" fill="none" stroke="%23333" stroke-width="1.5"/><line x1="4" y1="10" x2="16" y2="10" stroke="%23333" stroke-width="1.5"/></svg>');
    }
    
    .maplibregl-ctrl-3d .maplibregl-ctrl-icon {
        background-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><path d="M 5 13 L 5 8 L 10 5 L 15 8 L 15 13 L 10 16 Z M 5 8 L 10 10.5 M 10 10.5 L 15 8 M 10 10.5 L 10 16" fill="none" stroke="%23333" stroke-width="1.5" stroke-linejoin="round"/></svg>');
    }

    .maplibregl-ctrl-style .maplibregl-ctrl-icon {
        background-image: url('data:image/svg+xml;charset=utf-8,<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><rect x="3" y="3" width="6" height="6" fill="none" stroke="%23333" stroke-width="1.5"/><rect x="11" y="3" width="6" height="6" fill="none" stroke="%23333" stroke-width="1.5"/><rect x="3" y="11" width="6" height="6" fill="none" stroke="%23333" stroke-width="1.5"/><rect x="11" y="11" width="6" height="6" fill="none" stroke="%23333" stroke-width="1.5"/></svg>');
    }

    /* Popup стили */
    .maplibregl-popup-content {
        padding: 10px 15px;
        min-width: 150px;
    }
    
    .popup-title {
        font-weight: bold;
        margin-bottom: 5px;
        font-size: 13px;
    }
    
    .popup-info {
        font-size: 12px;
        color: #666;
    }

    /* Стили меню */
    .style-menu {
        background: white;
        border-radius: 4px;
        box-shadow: 0 0 0 2px rgba(0,0,0,.1);
        padding: 5px;
        min-width: 120px;
    }
    
    .style-menu button {
        display: block;
        width: 100%;
        padding: 6px 10px;
        border: none;
        background: none;
        text-align: left;
        cursor: pointer;
        font-size: 12px;
        border-radius: 2px;
    }
    
    .style-menu button:hover {
        background-color: #f0f0f0;
    }
    
    .style-menu button.active {
        background-color: #e3f2fd;
        color: #1976d2;
        font-weight: 500;
    }
</style>
{% endblock %}

{% block content %}
<div id="map"></div>
{% endblock content %}

{% block extra_js %}
<!-- MapLibre GL JavaScript -->
<script src="{% static 'maplibre/maplibre-gl.js' %}"></script>

<script>
    // Цвета для маркеров
    const markerColors = {
        'blue': '#3388ff',
        'orange': '#ff8c00',
        'green': '#28a745',
        'violet': '#9c27b0'
    };

    // Данные групп из Django
    const groups = [
        {% for group in groups %}
        {
            name: '{{ group.name|escapejs }}',
            color: '{{ group.color }}',
            points: [
                {% for point_data in group.points %}
                {
                    id: '{{ point_data.source_id|escapejs }}',
                    coordinates: [{{ point_data.point.0|safe }}, {{ point_data.point.1|safe }}]
                }{% if not forloop.last %},{% endif %}
                {% endfor %}
            ]
        }{% if not forloop.last %},{% endif %}
        {% endfor %}
    ];

    // Полигон фильтра
    const polygonCoords = {% if polygon_coords %}{{ polygon_coords|safe }}{% else %}null{% endif %};

    // Стили карт
    const mapStyles = {
        streets: {
            version: 8,
            sources: {
                'osm': {
                    type: 'raster',
                    tiles: ['https://a.tile.openstreetmap.org/{z}/{x}/{y}.png'],
                    tileSize: 256,
                    attribution: '&copy; OpenStreetMap'
                }
            },
            layers: [{
                id: 'osm',
                type: 'raster',
                source: 'osm'
            }]
        },
        satellite: {
            version: 8,
            sources: {
                'satellite': {
                    type: 'raster',
                    tiles: ['https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'],
                    tileSize: 256,
                    attribution: '&copy; Esri'
                }
            },
            layers: [{
                id: 'satellite',
                type: 'raster',
                source: 'satellite'
            }]
        },
        local: {
            version: 8,
            sources: {
                'local': {
                    type: 'raster',
                    tiles: ['http://127.0.0.1:8080/styles/basic-preview/{z}/{x}/{y}.png'],
                    tileSize: 256,
                    attribution: 'Local'
                }
            },
            layers: [{
                id: 'local',
                type: 'raster',
                source: 'local'
            }]
        }
    };

    // Инициализация карты
    const map = new maplibregl.Map({
        container: 'map',
        style: mapStyles.streets,
        center: [37.62, 55.75],
        zoom: 10,
        maxZoom: 18,
        minZoom: 0
    });

    let currentStyle = 'streets';
    let is3DEnabled = false;
    let isGlobeProjection = false;
    const allMarkers = [];

    // Добавляем стандартные контролы
    map.addControl(new maplibregl.NavigationControl(), 'top-right');
    map.addControl(new maplibregl.ScaleControl({ unit: 'metric' }), 'bottom-right');
    map.addControl(new maplibregl.FullscreenControl(), 'top-right');

    // Кастомный контрол для переключения проекции
    class ProjectionControl {
        onAdd(map) {
            this._map = map;
            this._container = document.createElement('div');
            this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group maplibregl-ctrl-projection';
            this._container.innerHTML = '<button type="button" title="Переключить проекцию"><span class="maplibregl-ctrl-icon"></span></button>';
            this._container.onclick = () => {
                if (isGlobeProjection) {
                    map.setProjection({ type: 'mercator' });
                    isGlobeProjection = false;
                } else {
                    map.setProjection({ type: 'globe' });
                    isGlobeProjection = true;
                }
            };
            return this._container;
        }
        onRemove() {
            this._container.parentNode.removeChild(this._container);
            this._map = undefined;
        }
    }


    // Кастомный контрол для переключения стилей
    class StyleControl {
        onAdd(map) {
            this._map = map;
            this._container = document.createElement('div');
            this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group maplibregl-ctrl-style';
            
            const button = document.createElement('button');
            button.type = 'button';
            button.title = 'Стиль карты';
            button.innerHTML = '<span class="maplibregl-ctrl-icon"></span>';
            
            const menu = document.createElement('div');
            menu.className = 'style-menu';
            menu.style.display = 'none';
            menu.style.position = 'absolute';
            menu.style.top = '100%';
            menu.style.right = '0';
            menu.style.marginTop = '5px';
            
            const styles = [
                { id: 'streets', name: 'Улицы' },
                { id: 'satellite', name: 'Спутник' },
                { id: 'local', name: 'Локально' }
            ];
            
            styles.forEach(style => {
                const btn = document.createElement('button');
                btn.textContent = style.name;
                btn.className = style.id === currentStyle ? 'active' : '';
                btn.onclick = () => {
                    this.switchStyle(style.id);
                    menu.querySelectorAll('button').forEach(b => b.classList.remove('active'));
                    btn.classList.add('active');
                    menu.style.display = 'none';
                };
                menu.appendChild(btn);
            });
            
            button.onclick = (e) => {
                e.stopPropagation();
                menu.style.display = menu.style.display === 'none' ? 'block' : 'none';
            };
            
            document.addEventListener('click', () => {
                menu.style.display = 'none';
            });
            
            this._container.appendChild(button);
            this._container.appendChild(menu);
            this._container.style.position = 'relative';
            
            return this._container;
        }
        
        switchStyle(styleName) {
            const center = this._map.getCenter();
            const zoom = this._map.getZoom();
            const bearing = this._map.getBearing();
            const pitch = this._map.getPitch();
            
            this._map.setStyle(mapStyles[styleName]);
            currentStyle = styleName;
            
            this._map.once('styledata', () => {
                this._map.setCenter(center);
                this._map.setZoom(zoom);
                this._map.setBearing(bearing);
                this._map.setPitch(pitch);
                
                addMarkersToMap();
                addFilterPolygon();
            });
        }
        
        onRemove() {
            this._container.parentNode.removeChild(this._container);
            this._map = undefined;
        }
    }

    // Кастомный контрол для слоев
    class LayersControl {
        onAdd(map) {
            this._map = map;
            this._container = document.createElement('div');
            this._container.className = 'maplibregl-ctrl maplibregl-ctrl-layers';
            
            const title = document.createElement('h6');
            title.textContent = 'Слои точек';
            this._container.appendChild(title);
            
            groups.forEach((group, groupIndex) => {
                const layerId = `points-layer-${groupIndex}`;
                
                const layerItem = document.createElement('div');
                layerItem.className = 'layer-item';
                
                const label = document.createElement('label');
                const checkbox = document.createElement('input');
                checkbox.type = 'checkbox';
                checkbox.checked = true;
                checkbox.addEventListener('change', (e) => {
                    const visibility = e.target.checked ? 'visible' : 'none';
                    if (map.getLayer(layerId)) {
                        map.setLayoutProperty(layerId, 'visibility', visibility);
                    }
                    // Также скрываем/показываем внутренний круг
                    const innerLayerId = `${layerId}-inner`;
                    if (map.getLayer(innerLayerId)) {
                        map.setLayoutProperty(innerLayerId, 'visibility', visibility);
                    }
                });
                
                const colorSpan = document.createElement('span');
                colorSpan.className = 'legend-marker';
                colorSpan.style.backgroundColor = markerColors[group.color];
                
                const nameSpan = document.createElement('span');
                nameSpan.textContent = `${group.name} (${group.points.length})`;
                
                label.appendChild(checkbox);
                label.appendChild(colorSpan);
                label.appendChild(nameSpan);
                layerItem.appendChild(label);
                this._container.appendChild(layerItem);
            });
            
            return this._container;
        }
        onRemove() {
            this._container.parentNode.removeChild(this._container);
            this._map = undefined;
        }
    }

    // Кастомный контрол для легенды
    class LegendControl {
        onAdd(map) {
            this._map = map;
            this._container = document.createElement('div');
            this._container.className = 'maplibregl-ctrl maplibregl-ctrl-legend';
            
            const title = document.createElement('h6');
            title.textContent = 'Легенда';
            this._container.appendChild(title);
            
            groups.forEach(group => {
                const section = document.createElement('div');
                section.className = 'legend-section';
                
                const item = document.createElement('div');
                item.className = 'legend-item';
                
                const marker = document.createElement('div');
                marker.className = 'legend-marker';
                marker.style.backgroundColor = markerColors[group.color];
                
                const text = document.createElement('span');
                text.textContent = `${group.name} (${group.points.length})`;
                
                item.appendChild(marker);
                item.appendChild(text);
                section.appendChild(item);
                this._container.appendChild(section);
            });
            
            if (polygonCoords && polygonCoords.length > 0) {
                const section = document.createElement('div');
                section.className = 'legend-section';
                
                const item = document.createElement('div');
                item.className = 'legend-item';
                
                const marker = document.createElement('div');
                marker.style.width = '18px';
                marker.style.height = '18px';
                marker.style.marginRight = '8px';
                marker.style.backgroundColor = 'rgba(51, 136, 255, 0.2)';
                marker.style.border = '2px solid #3388ff';
                marker.style.borderRadius = '2px';
                
                const text = document.createElement('span');
                text.textContent = 'Область фильтра';
                
                item.appendChild(marker);
                item.appendChild(text);
                section.appendChild(item);
                this._container.appendChild(section);
            }
            
            return this._container;
        }
        onRemove() {
            this._container.parentNode.removeChild(this._container);
            this._map = undefined;
        }
    }

    // Добавляем кастомные контролы
    map.addControl(new ProjectionControl(), 'top-right');
    map.addControl(new StyleControl(), 'top-right');
    map.addControl(new LayersControl(), 'top-left');
    map.addControl(new LegendControl(), 'bottom-left');

    // Добавление маркеров на карту
    function addMarkersToMap() {
        groups.forEach((group, groupIndex) => {
            const sourceId = `points-${groupIndex}`;
            const layerId = `points-layer-${groupIndex}`;
            
            // Создаем GeoJSON для группы
            const geojson = {
                type: 'FeatureCollection',
                features: group.points.map(point => ({
                    type: 'Feature',
                    geometry: {
                        type: 'Point',
                        coordinates: point.coordinates
                    },
                    properties: {
                        id: point.id,
                        groupName: group.name,
                        color: markerColors[group.color]
                    }
                }))
            };
            
            // Добавляем источник данных
            if (!map.getSource(sourceId)) {
                map.addSource(sourceId, {
                    type: 'geojson',
                    data: geojson
                });
            }
            
            // Добавляем слой с кругами (основной маркер)
            if (!map.getLayer(layerId)) {
                map.addLayer({
                    id: layerId,
                    type: 'circle',
                    source: sourceId,
                    paint: {
                        'circle-radius': 10,
                        'circle-color': ['get', 'color'],
                        'circle-stroke-width': 3,
                        'circle-stroke-color': '#ffffff',
                        'circle-opacity': 1
                    }
                });
                
                // Добавляем внутренний круг
                map.addLayer({
                    id: `${layerId}-inner`,
                    type: 'circle',
                    source: sourceId,
                    paint: {
                        'circle-radius': 4,
                        'circle-color': '#ffffff',
                        'circle-opacity': 1
                    }
                });
                
                // Добавляем popup при клике
                map.on('click', layerId, (e) => {
                    const coordinates = e.features[0].geometry.coordinates.slice();
                    const { id, groupName } = e.features[0].properties;
                    
                    new maplibregl.Popup()
                        .setLngLat(coordinates)
                        .setHTML(`<div class="popup-title">${id}</div><div class="popup-info">Группа: ${groupName}</div>`)
                        .addTo(map);
                });
                
                // Меняем курсор при наведении
                map.on('mouseenter', layerId, () => {
                    map.getCanvas().style.cursor = 'pointer';
                });
                
                map.on('mouseleave', layerId, () => {
                    map.getCanvas().style.cursor = '';
                });
            }
        });
    }

    // Добавление полигона фильтра
    function addFilterPolygon() {
        if (!polygonCoords || polygonCoords.length === 0) return;
        
        try {
            const polygonGeoJSON = {
                type: 'Feature',
                geometry: {
                    type: 'Polygon',
                    coordinates: [polygonCoords]
                }
            };
            
            if (!map.getSource('filter-polygon')) {
                map.addSource('filter-polygon', {
                    type: 'geojson',
                    data: polygonGeoJSON
                });
            }
            
            if (!map.getLayer('filter-polygon-fill')) {
                map.addLayer({
                    id: 'filter-polygon-fill',
                    type: 'fill',
                    source: 'filter-polygon',
                    paint: {
                        'fill-color': '#3388ff',
                        'fill-opacity': 0.2
                    }
                });
            }
            
            if (!map.getLayer('filter-polygon-outline')) {
                map.addLayer({
                    id: 'filter-polygon-outline',
                    type: 'line',
                    source: 'filter-polygon',
                    paint: {
                        'line-color': '#3388ff',
                        'line-width': 2,
                        'line-dasharray': [2, 2]
                    }
                });
            }
            
            map.on('click', 'filter-polygon-fill', (e) => {
                new maplibregl.Popup()
                    .setLngLat(e.lngLat)
                    .setHTML('<div class="popup-title">Область фильтра</div><div class="popup-info">Отображаются только источники с точками в этой области</div>')
                    .addTo(map);
            });
        } catch (e) {
            console.error('Ошибка при отображении полигона фильтра:', e);
        }
    }

    // Подгонка карты под все маркеры
    function fitMapToBounds() {
        const allCoordinates = [];
        
        groups.forEach(group => {
            group.points.forEach(point => {
                allCoordinates.push(point.coordinates);
            });
        });
        
        if (polygonCoords && polygonCoords.length > 0) {
            polygonCoords.forEach(coord => {
                allCoordinates.push(coord);
            });
        }
        
        if (allCoordinates.length > 0) {
            const bounds = allCoordinates.reduce((bounds, coord) => {
                return bounds.extend(coord);
            }, new maplibregl.LngLatBounds(allCoordinates[0], allCoordinates[0]));
            
            map.fitBounds(bounds, { padding: 50 });
        }
    }

    // Инициализация после загрузки карты
    map.on('load', () => {
        addMarkersToMap();
        addFilterPolygon();
        fitMapToBounds();
    });
</script>
{% endblock extra_js %}
