// Custom Marker Tool for Leaflet Map integrated with Geoman
// Allows placing custom markers with shape, color, size, and label configuration

class CustomMarkerTool {
    constructor(map, shapeMap, colorMap) {
        this.map = map;
        this.shapeMap = shapeMap;
        this.colorMap = colorMap;
        this.isActive = false;
        this.pendingMarkerLatLng = null;
        this.clickHandler = null;
        
        // Default marker settings
        this.settings = {
            shape: 'circle',
            color: 'red',
            size: 1.0,
            opacity: 1.0,
            label: ''
        };
        
        this.init();
    }
    
    init() {
        this.createGeomanControl();
        this.createModal();
        this.attachEventListeners();
        this.setupGeomanIntegration();
    }
    
    createGeomanControl() {
        // Add custom action to Geoman toolbar
        const customMarkerAction = {
            name: 'customMarker',
            block: 'draw',
            title: 'Добавить кастомный маркер',
            className: 'leaflet-pm-icon-custom-marker',
            toggle: true,
            onClick: () => {},
            afterClick: () => {
                this.toggleTool();
            }
        };
        
        // Add the action to Geoman
        this.map.pm.Toolbar.createCustomControl(customMarkerAction);
        
        // Add custom icon style
        const style = document.createElement('style');
        style.textContent = `
            .leaflet-pm-icon-custom-marker {
                background-image: url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgdmlld0JveD0iMCAwIDI0IDI0IiBmaWxsPSJub25lIiBzdHJva2U9IiMzMzMiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIiBzdHJva2UtbGluZWpvaW49InJvdW5kIj48cGF0aCBkPSJNMjEgMTBjMCA3LTkgMTMtOSAxM3MtOS02LTktMTNhOSA5IDAgMCAxIDE4IDB6Ij48L3BhdGg+PGNpcmNsZSBjeD0iMTIiIGN5PSIxMCIgcj0iMyI+PC9jaXJjbGU+PC9zdmc+');
                background-size: 18px 18px;
                background-position: center;
                background-repeat: no-repeat;
            }
        `;
        document.head.appendChild(style);
    }
    
    createModal() {
        const overlay = document.createElement('div');
        overlay.id = 'customMarkerModalOverlay';
        overlay.className = 'style-modal-overlay';
        
        const modal = document.createElement('div');
        modal.id = 'customMarkerModal';
        modal.className = 'custom-marker-modal';
        
        modal.innerHTML = `
            <h5><i class="bi bi-geo-alt-fill"></i> Настройка маркера</h5>
            
            <div class="form-group">
                <label for="markerLabel">Подпись маркера:</label>
                <input type="text" id="markerLabel" placeholder="Введите подпись (необязательно)">
            </div>
            
            <div class="form-group">
                <label>Форма маркера:</label>
                <div class="shape-preview" id="shapePreview"></div>
            </div>
            
            <div class="form-group">
                <label for="markerColor">Цвет маркера:</label>
                <select id="markerColor"></select>
            </div>
            
            <div class="form-group">
                <label for="markerSize">Размер: <span class="range-value" id="markerSizeValue">1.0x</span></label>
                <input type="range" id="markerSize" min="0.5" max="3" step="0.1" value="1.0">
            </div>
            
            <div class="form-group">
                <label for="markerOpacity">Прозрачность: <span class="range-value" id="markerOpacityValue">100%</span></label>
                <input type="range" id="markerOpacity" min="0" max="1" step="0.1" value="1.0">
            </div>
            
            <div class="marker-preview" id="markerPreview">
                <div id="previewIcon"></div>
            </div>
            
            <div class="btn-row">
                <button class="btn-cancel" id="customMarkerCancel">Отмена</button>
                <button class="btn-place" id="customMarkerPlace">Разместить на карте</button>
            </div>
        `;
        
        document.body.appendChild(overlay);
        document.body.appendChild(modal);
        
        this.modal = modal;
        this.overlay = overlay;
        
        this.populateShapes();
        this.populateColors();
        this.updatePreview();
    }
    
    populateShapes() {
        const shapePreview = document.getElementById('shapePreview');
        const shapes = Object.keys(this.shapeMap);
        
        shapes.forEach(shape => {
            const option = document.createElement('div');
            option.className = 'shape-option';
            option.dataset.shape = shape;
            option.innerHTML = this.shapeMap[shape]('#666', 24);
            option.title = this.getShapeName(shape);
            
            if (shape === this.settings.shape) {
                option.classList.add('selected');
            }
            
            option.addEventListener('click', () => {
                document.querySelectorAll('.shape-option').forEach(el => el.classList.remove('selected'));
                option.classList.add('selected');
                this.settings.shape = shape;
                this.updatePreview();
            });
            
            shapePreview.appendChild(option);
        });
    }
    
    populateColors() {
        const colorSelect = document.getElementById('markerColor');
        
        Object.keys(this.colorMap).forEach(colorName => {
            const option = document.createElement('option');
            option.value = colorName;
            option.textContent = this.getColorName(colorName);
            option.style.color = this.colorMap[colorName];
            
            if (colorName === this.settings.color) {
                option.selected = true;
            }
            
            colorSelect.appendChild(option);
        });
    }
    
    getShapeName(shape) {
        const names = {
            'circle': 'Круг',
            'square': 'Квадрат',
            'triangle': 'Треугольник',
            'star': 'Звезда',
            'pentagon': 'Пятиугольник',
            'hexagon': 'Шестиугольник',
            'diamond': 'Ромб',
            'cross': 'Крест'
        };
        return names[shape] || shape;
    }
    
    getColorName(color) {
        const names = {
            'red': 'Красный',
            'blue': 'Синий',
            'green': 'Зелёный',
            'purple': 'Фиолетовый',
            'orange': 'Оранжевый',
            'cyan': 'Голубой',
            'magenta': 'Пурпурный',
            'pink': 'Розовый',
            'teal': 'Бирюзовый',
            'indigo': 'Индиго',
            'brown': 'Коричневый',
            'navy': 'Тёмно-синий',
            'maroon': 'Бордовый',
            'olive': 'Оливковый',
            'coral': 'Коралловый',
            'turquoise': 'Бирюзовый'
        };
        return names[color] || color;
    }
    
    attachEventListeners() {
        // Size slider
        const sizeSlider = document.getElementById('markerSize');
        const sizeValue = document.getElementById('markerSizeValue');
        sizeSlider.addEventListener('input', () => {
            this.settings.size = parseFloat(sizeSlider.value);
            sizeValue.textContent = this.settings.size.toFixed(1) + 'x';
            this.updatePreview();
        });
        
        // Opacity slider
        const opacitySlider = document.getElementById('markerOpacity');
        const opacityValue = document.getElementById('markerOpacityValue');
        opacitySlider.addEventListener('input', () => {
            this.settings.opacity = parseFloat(opacitySlider.value);
            opacityValue.textContent = Math.round(this.settings.opacity * 100) + '%';
            this.updatePreview();
        });
        
        // Color select
        const colorSelect = document.getElementById('markerColor');
        colorSelect.addEventListener('change', () => {
            this.settings.color = colorSelect.value;
            this.updatePreview();
        });
        
        // Label input
        const labelInput = document.getElementById('markerLabel');
        labelInput.addEventListener('input', () => {
            this.settings.label = labelInput.value;
        });
        
        // Modal buttons
        document.getElementById('customMarkerCancel').addEventListener('click', () => {
            this.closeModal();
        });
        
        document.getElementById('customMarkerPlace').addEventListener('click', () => {
            this.startPlacement();
        });
        
        this.overlay.addEventListener('click', () => {
            this.closeModal();
        });
    }
    
    updatePreview() {
        const previewIcon = document.getElementById('previewIcon');
        const hexColor = this.colorMap[this.settings.color] || this.settings.color;
        const size = Math.round(20 * this.settings.size);
        const shapeFunc = this.shapeMap[this.settings.shape];
        
        if (shapeFunc) {
            previewIcon.innerHTML = shapeFunc(hexColor, size);
            previewIcon.style.opacity = this.settings.opacity;
        }
    }
    
    setupGeomanIntegration() {
        // Listen to other Geoman tools to deactivate custom marker tool
        this.map.on('pm:globaldrawmodetoggled', (e) => {
            if (e.enabled && e.shape !== 'customMarker' && this.isActive) {
                this.deactivate();
            }
        });
        
        this.map.on('pm:globaleditmodetoggled', (e) => {
            if (e.enabled && this.isActive) {
                this.deactivate();
            }
        });
        
        this.map.on('pm:globaldragmodetoggled', (e) => {
            if (e.enabled && this.isActive) {
                this.deactivate();
            }
        });
        
        this.map.on('pm:globalremovalmodetoggled', (e) => {
            if (e.enabled && this.isActive) {
                this.deactivate();
            }
        });
        
        // Listen to custom edit mode toggle
        this.map.on('customeditmodetoggled', (e) => {
            if (e.enabled && this.isActive) {
                this.deactivate();
            }
        });
    }
    
    toggleTool() {
        if (this.isActive) {
            this.deactivate();
        } else {
            this.activate();
        }
    }
    
    activate() {
        if (this.isActive) return; // Prevent double activation
        
        this.isActive = true;
        
        // Disable all other Geoman tools (without triggering events that cause recursion)
        this.map.pm.disableDraw();
        this.map.pm.disableGlobalEditMode();
        this.map.pm.disableGlobalDragMode();
        this.map.pm.disableGlobalRemovalMode();
        
        // Disable custom edit mode
        if (window.customEditModeActive) {
            window.customEditModeActive = false;
            const editBtn = document.querySelector('.leaflet-pm-icon-custom-edit');
            if (editBtn && editBtn.parentElement) {
                editBtn.parentElement.classList.remove('active');
            }
            const indicator = document.getElementById('customEditIndicator');
            if (indicator) {
                indicator.classList.remove('active');
            }
        }
        
        // Toggle Geoman button state
        const customBtn = document.querySelector('.leaflet-pm-icon-custom-marker');
        if (customBtn && customBtn.parentElement) {
            customBtn.parentElement.classList.add('active');
        }
        
        this.showModal();
    }
    
    deactivate() {
        if (!this.isActive) return; // Prevent double deactivation
        
        this.isActive = false;
        
        // Toggle Geoman button state
        const customBtn = document.querySelector('.leaflet-pm-icon-custom-marker');
        if (customBtn && customBtn.parentElement) {
            customBtn.parentElement.classList.remove('active');
        }
        
        this.closeModal();
        this.cancelPlacement();
    }
    
    showModal() {
        this.overlay.classList.add('show');
        this.modal.classList.add('show');
        
        // Reset form
        document.getElementById('markerLabel').value = this.settings.label;
        document.getElementById('markerSize').value = this.settings.size;
        document.getElementById('markerOpacity').value = this.settings.opacity;
        document.getElementById('markerSizeValue').textContent = this.settings.size.toFixed(1) + 'x';
        document.getElementById('markerOpacityValue').textContent = Math.round(this.settings.opacity * 100) + '%';
    }
    
    closeModal() {
        this.overlay.classList.remove('show');
        this.modal.classList.remove('show');
        this.deactivate();
    }
    
    startPlacement() {
        this.overlay.classList.remove('show');
        this.modal.classList.remove('show');
        
        // Add crosshair cursor
        this.map.getContainer().classList.add('marker-placement-mode');
        
        // Remove previous click handler if exists
        if (this.clickHandler) {
            this.map.off('click', this.clickHandler);
        }
        
        // Create new click handler
        this.clickHandler = (e) => {
            // Prevent event from bubbling
            L.DomEvent.stopPropagation(e);
            this.placeMarker(e.latlng);
        };
        
        // Wait for map click
        this.map.on('click', this.clickHandler);
        
        // Show instruction
        this.showInstruction('Кликните на карту для размещения маркера.');
        
        // Add keyboard handlers
        this.keyHandler = (e) => {
            if (e.key === 'Escape') {
                console.log("Жму кнопку");
                this.deactivate();
            } else if (e.key === 'Enter' && this.pendingMarkerLatLng) {
                this.placeMarker(this.pendingMarkerLatLng);
            }
        };
        document.addEventListener('keydown', this.keyHandler);
    }
    
    cancelPlacement() {
        this.map.getContainer().classList.remove('marker-placement-mode');
        
        // Remove click handler
        if (this.clickHandler) {
            this.map.off('click', this.clickHandler);
            this.clickHandler = null;
        }
        
        // Remove keyboard handler
        if (this.keyHandler) {
            document.removeEventListener('keydown', this.keyHandler);
            this.keyHandler = null;
        }
        
        this.hideInstruction();
    }
    
    placeMarker(latlng) {
        // Cancel placement mode
        this.cancelPlacement();
        
        const hexColor = this.colorMap[this.settings.color] || this.settings.color;
        const baseSize = 16;
        const size = Math.round(baseSize * this.settings.size);
        const shapeFunc = this.shapeMap[this.settings.shape];
        
        const icon = L.divIcon({
            className: 'custom-placed-marker',
            iconSize: [size, size],
            iconAnchor: [size/2, size/2],
            popupAnchor: [0, -size/2],
            html: `<div style="opacity: ${this.settings.opacity}">${shapeFunc(hexColor, size)}</div>`
        });
        
        const marker = L.marker(latlng, { icon: icon });
        
        // Add popup with label if provided
        if (this.settings.label) {
            marker.bindPopup(`<b>${this.settings.label}</b>`);
            marker.bindTooltip(this.settings.label, { permanent: false, direction: 'top' });
        }
        
        // Add to active drawing layer or create new one
        if (window.activeDrawingLayerId && window.drawingLayers[window.activeDrawingLayerId]) {
            // Capture layerId in closure - important for click handler
            const layerId = window.activeDrawingLayerId;
            const activeLayer = window.drawingLayers[layerId];
            activeLayer.layerGroup.addLayer(marker);
            
            // Store element info
            const elementInfo = {
                layer: marker,
                visible: true,
                label: this.settings.label,
                style: {
                    color: hexColor,
                    shape: this.settings.shape,
                    size: this.settings.size,
                    opacity: this.settings.opacity
                }
            };
            
            activeLayer.elements.push(elementInfo);
            
            // Add click handler for editing ONLY in custom edit mode
            // Use captured layerId, not window.activeDrawingLayerId
            marker.on('click', function(e) {
                // Check if custom edit mode is active (from global scope)
                if (window.customEditModeActive) {
                    L.DomEvent.stopPropagation(e);
                    // Find element in the layer where it was added
                    const layer = window.drawingLayers[layerId];
                    if (layer) {
                        const idx = layer.elements.findIndex(el => el.layer === marker);
                        if (idx !== -1 && window.openStyleModal) {
                            window.openStyleModal(layerId, idx);
                        }
                    }
                }
            });
            
            // Update layer panel
            if (window.renderDrawingLayers) {
                window.renderDrawingLayers();
            }
        } else {
            // Fallback: add directly to map
            marker.addTo(this.map);
        }
        
        // Deactivate tool after placing marker
        this.deactivate();
        
        // Fire custom event
        this.map.fire('custommarker:created', { marker: marker, settings: { ...this.settings } });
    }
    
    showInstruction(text) {
        let instruction = document.getElementById('markerPlacementInstruction');
        if (!instruction) {
            instruction = document.createElement('div');
            instruction.id = 'markerPlacementInstruction';
            instruction.style.cssText = `
                position: fixed;
                top: 70px;
                left: 50%;
                transform: translateX(-50%);
                z-index: 1500;
                background: #007bff;
                color: white;
                padding: 10px 20px;
                border-radius: 4px;
                box-shadow: 0 2px 10px rgba(0,0,0,0.3);
                font-size: 14px;
                font-weight: 500;
                display: flex;
                align-items: center;
                gap: 10px;
            `;
            document.body.appendChild(instruction);
            
            // Prevent map interactions on instruction
            L.DomEvent.disableClickPropagation(instruction);
            L.DomEvent.disableScrollPropagation(instruction);
        }
        instruction.innerHTML = `
            <span>${text}</span>
        `;
        // <button id="finishMarkerBtn" style="
        //         background: white;
        //         color: #007bff;ы
        //         border: none;
        //         padding: 4px 12px;
        //         border-radius: 3px;
        //         cursor: pointer;
        //         font-weight: 500;
        //         font-size: 12px;
        //     ">Отмена (ESC)</button>
        instruction.style.display = 'flex';
        
        // Add finish button handler
        const finishBtn = document.getElementById('finishMarkerBtn');
        if (finishBtn) {
            finishBtn.addEventListener('click', () => {
                this.deactivate();
            });
        }
    }
    
    hideInstruction() {
        const instruction = document.getElementById('markerPlacementInstruction');
        if (instruction) {
            instruction.style.display = 'none';
        }
    }
}
