// =====================================================================
// WebGIS Citizen Participation Portal — Application Logic
// Initializes the Leaflet Map, loads Contributions from the API,
// handles the CRUD Workflow, and manages all UI Interactions.
//
// Depends on: MUNICIPALITY Object (set in index.php), Leaflet, Geoman,
//             Sidebar v2, Geocoder, PolylineMeasure, Fullscreen, SweetAlert2
// =====================================================================


// =====================================================================
// Block 1: Configuration and Application State
// =====================================================================

// API Endpoint — relative Path from public/ to api/
var API_URL = '../api/contributions.php';

// Current User Name — set via Login Modal, stored in sessionStorage
var currentUser = sessionStorage.getItem('webgis_user') || '';

// Category Definitions with Labels, Icons, and Colors
var CATEGORIES = {
    mobility:    { label: 'Mobilität',   icon: '🚲', color: '#1565C0', faIcon: 'fa-bicycle' },
    building:    { label: 'Bauen',       icon: '🏗️', color: '#E65100', faIcon: 'fa-helmet-safety' },
    energy:      { label: 'Energie',     icon: '⚡', color: '#F9A825', faIcon: 'fa-bolt' },
    environment: { label: 'Umwelt',      icon: '🌳', color: '#2E7D32', faIcon: 'fa-tree' },
    industry:    { label: 'Industrie',   icon: '🏭', color: '#6A1B9A', faIcon: 'fa-industry' },
    consumption: { label: 'Konsum',      icon: '🛒', color: '#AD1457', faIcon: 'fa-cart-shopping' },
    other:       { label: 'Sonstiges',   icon: '📌', color: '#546E7A', faIcon: 'fa-map-pin' }
};

// Application State
var map;                        // Leaflet Map Instance
var sidebar;                    // Sidebar Instance
var contributionsLayer;         // GeoJSON Layer holding all Contributions
var contributionsData = [];     // Raw Contribution Data Array
var activeFilters = Object.keys(CATEGORIES);  // Active Category Filters (all enabled by Default)
var drawnGeometry = null;       // Temporary Storage for Geometry drawn with Geoman
var drawnGeomType = null;       // Temporary Storage for Geometry Type


// =====================================================================
// Block 2: Map Initialization
// =====================================================================

map = L.map('map', {
    center: MUNICIPALITY.center,
    zoom: MUNICIPALITY.zoom,
    zoomControl: false,           // Added manually in Block 3 for Position Control
    attributionControl: true
});


// =====================================================================
// Block 3: Basemaps and Layer Control
// =====================================================================

// Basemap Tile Layers
var basemapOSM = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
    attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a>',
    maxZoom: 20
});

var basemapCartoDB = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
    attribution: '© <a href="https://carto.com/">CARTO</a>',
    maxZoom: 20
});

var basemapSatellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
    attribution: '© <a href="https://www.esri.com/">Esri</a>',
    maxZoom: 20
});

var basemapTopo = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
    attribution: '© <a href="https://opentopomap.org">OpenTopoMap</a>',
    maxZoom: 18
});

// Set Default Basemap
basemapCartoDB.addTo(map);

// Layer Control
var basemaps = {
    'OpenStreetMap': basemapOSM,
    'CartoDB (hell)': basemapCartoDB,
    'Satellit (Esri)': basemapSatellite,
    'Topographisch': basemapTopo
};

var overlays = {};  // Populated later with Contribution Layer

var layerControl = L.control.layers(basemaps, overlays, {
    position: 'topright',
    collapsed: true
}).addTo(map);


// =====================================================================
// Block 4: Map Controls
// =====================================================================

// Zoom Control (top right)
L.control.zoom({
    position: 'topright'
}).addTo(map);

// Scale Bar (bottom right)
L.control.scale({
    position: 'bottomright',
    maxWidth: 200,
    imperial: false
}).addTo(map);

// Fullscreen Button
L.control.fullscreen({
    position: 'topright',
    title: 'Vollbild',
    titleCancel: 'Vollbild beenden'
}).addTo(map);

// Address Search (Geocoder with Nominatim)
L.Control.geocoder({
    position: 'topright',
    placeholder: 'Adresse suchen...',
    defaultMarkGeocode: true,
    geocoder: L.Control.Geocoder.nominatim({
        geocodingQueryParams: {
            countrycodes: 'de',
            viewbox: '8.0,52.5,8.5,52.8',
            bounded: 1
        }
    })
}).addTo(map);

// Polyline Measure Tool
L.control.polylineMeasure({
    position: 'topright',
    unit: 'metres',
    showBearings: false,
    clearMeasurementsOnStop: false,
    showClearControl: true
}).addTo(map);

// Mouse Position Display
var MousePositionControl = L.Control.extend({
    options: { position: 'bottomright' },

    onAdd: function () {
        var container = L.DomUtil.create('div', 'mouse-position-display');
        container.style.background = 'rgba(255,255,255,0.85)';
        container.style.padding = '2px 8px';
        container.style.fontSize = '12px';
        container.style.borderRadius = '4px';
        container.style.fontFamily = 'monospace';
        container.innerHTML = 'Lat: — | Lng: —';

        map.on('mousemove', function (e) {
            container.innerHTML = 'Lat: ' + e.latlng.lat.toFixed(5) + ' | Lng: ' + e.latlng.lng.toFixed(5);
        });

        return container;
    }
});

new MousePositionControl().addTo(map);

// GPS Location Button
var GpsControl = L.Control.extend({
    options: { position: 'topright' },

    onAdd: function () {
        var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control');
        var button = L.DomUtil.create('a', '', container);
        button.href = '#';
        button.title = 'Mein Standort';
        button.innerHTML = '<i class="fa-solid fa-location-crosshairs"></i>';
        button.style.fontSize = '16px';
        button.style.display = 'flex';
        button.style.alignItems = 'center';
        button.style.justifyContent = 'center';
        button.style.width = '30px';
        button.style.height = '30px';

        L.DomEvent.on(button, 'click', function (e) {
            L.DomEvent.preventDefault(e);
            map.locate({ setView: true, maxZoom: 17 });
        });

        return container;
    }
});

new GpsControl().addTo(map);

// GPS Location Found Handler
var gpsMarker = null;

map.on('locationfound', function (e) {
    if (gpsMarker) {
        map.removeLayer(gpsMarker);
    }
    gpsMarker = L.circleMarker(e.latlng, {
        radius: 8,
        color: '#1565C0',
        fillColor: '#42A5F5',
        fillOpacity: 0.8,
        weight: 2
    }).addTo(map).bindPopup('Ihr Standort').openPopup();
});

map.on('locationerror', function () {
    Swal.fire('Standort nicht gefunden', 'Bitte erlauben Sie den Standortzugriff in Ihrem Browser.', 'warning');
});


// =====================================================================
// Block 5: Sidebar Initialization
// =====================================================================

sidebar = L.control.sidebar({
    autopan: true,
    closeButton: true,
    container: 'sidebar',
    position: 'left'
}).addTo(map);


// =====================================================================
// Block 6: Geoman Drawing Tools and CRUD Trigger
// =====================================================================

map.pm.addControls({
    position: 'topright',
    drawMarker: true,
    drawPolyline: true,
    drawPolygon: true,
    drawCircleMarker: false,
    drawCircle: false,
    drawText: false,
    drawRectangle: false,
    editMode: false,
    dragMode: false,
    cutPolygon: false,
    removalMode: false,
    rotateMode: false
});

// When a Shape is drawn, capture the Geometry and open the Create Modal
map.on('pm:create', function (e) {
    var geojson = e.layer.toGeoJSON().geometry;

    // Determine Geometry Type and normalize to simple Types
    if (e.shape === 'Marker') {
        drawnGeometry = { type: 'Point', coordinates: geojson.coordinates };
        drawnGeomType = 'point';
    } else if (e.shape === 'Line') {
        drawnGeometry = { type: 'LineString', coordinates: geojson.coordinates };
        drawnGeomType = 'line';
    } else if (e.shape === 'Polygon') {
        drawnGeometry = { type: 'Polygon', coordinates: geojson.coordinates };
        drawnGeomType = 'polygon';
    } else {
        // Unsupported Shape — remove from Map and exit
        map.removeLayer(e.layer);
        return;
    }

    // Remove the drawn Layer — it will be re-added after API Confirmation
    map.removeLayer(e.layer);

    // Check if User is logged in
    if (!currentUser) {
        Swal.fire('Bitte anmelden', 'Sie müssen sich anmelden, um Beiträge zu erstellen.', 'info');
        showLoginModal();
        return;
    }

    // Populate hidden Fields and open Create Modal
    document.getElementById('create-geom').value = JSON.stringify(drawnGeometry);
    document.getElementById('create-geom-type').value = drawnGeomType;
    document.getElementById('create-modal').style.display = 'flex';
});


// =====================================================================
// Block 7: API Communication
// =====================================================================

// Generic API Call Function
function apiCall(data, callback) {
    var formData = new FormData();
    for (var key in data) {
        formData.append(key, data[key]);
    }

    fetch(API_URL, { method: 'POST', body: formData })
        .then(function (response) {
            return response.json().then(function (json) {
                json._status = response.status;
                return json;
            });
        })
        .then(function (json) {
            callback(json);
        })
        .catch(function (error) {
            console.error('API Error:', error);
            Swal.fire('Verbindungsfehler', 'Die Verbindung zum Server ist fehlgeschlagen.', 'error');
        });
}

// Load all Contributions from API and display on Map
function loadContributions() {
    apiCall({ action: 'read', municipality_id: MUNICIPALITY.id }, function (data) {
        if (data.error) {
            console.error('Load Error:', data.error);
            return;
        }

        contributionsData = data.features || [];

        // Remove existing Layer if present
        if (contributionsLayer) {
            map.removeLayer(contributionsLayer);
            layerControl.removeLayer(contributionsLayer);
        }

        // Create new GeoJSON Layer
        contributionsLayer = L.geoJSON(data, {
            pointToLayer: stylePoint,
            style: styleLinePolygon,
            onEachFeature: bindFeaturePopup
        }).addTo(map);

        layerControl.addOverlay(contributionsLayer, 'Beiträge');

        // Update Sidebar List and Statistics
        updateContributionsList();
        updateStatistics();
    });
}


// =====================================================================
// Block 8: Feature Styling by Category
// =====================================================================

// Style for Point Features (CircleMarkers)
function stylePoint(feature, latlng) {
    var cat = CATEGORIES[feature.properties.category] || CATEGORIES.other;

    return L.circleMarker(latlng, {
        radius: 8,
        color: '#ffffff',
        weight: 2,
        fillColor: cat.color,
        fillOpacity: 0.9
    });
}

// Style for Line and Polygon Features
function styleLinePolygon(feature) {
    var cat = CATEGORIES[feature.properties.category] || CATEGORIES.other;

    return {
        color: cat.color,
        weight: 3,
        opacity: 0.8,
        fillColor: cat.color,
        fillOpacity: 0.25
    };
}


// =====================================================================
// Block 9: Feature Popups (Read, Vote, Edit, Delete)
// =====================================================================

function bindFeaturePopup(feature, layer) {
    var props = feature.properties;
    var cat = CATEGORIES[props.category] || CATEGORIES.other;

    // Format Date
    var date = new Date(props.created_at);
    var dateStr = date.toLocaleDateString('de-DE', {
        day: '2-digit', month: '2-digit', year: 'numeric'
    });

    // Build Popup HTML
    var html = '' +
        '<div class="popup-detail">' +
            '<span class="popup-detail-category">' + cat.icon + ' ' + cat.label + '</span>' +
            '<div class="popup-detail-title">' + escapeHtml(props.title) + '</div>' +
            (props.description ? '<div class="popup-detail-description">' + escapeHtml(props.description) + '</div>' : '') +
            '<div class="popup-detail-meta">' +
                '<i class="fa-solid fa-user"></i> ' + escapeHtml(props.author_name) +
                ' &middot; <i class="fa-solid fa-calendar"></i> ' + dateStr +
            '</div>' +
            '<div class="popup-detail-votes">' +
                '<button class="popup-vote-btn" onclick="voteContribution(' + props.contribution_id + ', \'like\')" title="Gefällt mir">' +
                    '<i class="fa-solid fa-thumbs-up"></i> <span id="likes-' + props.contribution_id + '">' + props.likes_count + '</span>' +
                '</button>' +
                '<button class="popup-vote-btn" onclick="voteContribution(' + props.contribution_id + ', \'dislike\')" title="Gefällt mir nicht">' +
                    '<i class="fa-solid fa-thumbs-down"></i> <span id="dislikes-' + props.contribution_id + '">' + props.dislikes_count + '</span>' +
                '</button>' +
            '</div>' +
            '<div class="popup-detail-actions">' +
                '<button class="btn btn-primary" onclick="editContribution(' + props.contribution_id + ')"><i class="fa-solid fa-pen"></i> Bearbeiten</button>' +
                '<button class="btn btn-danger" onclick="deleteContribution(' + props.contribution_id + ')"><i class="fa-solid fa-trash"></i> Löschen</button>' +
            '</div>' +
        '</div>';

    layer.bindPopup(html, { maxWidth: 320, minWidth: 240 });

    // Tooltip on Hover
    layer.bindTooltip(cat.icon + ' ' + escapeHtml(props.title), {
        direction: 'top',
        offset: [0, -10]
    });
}


// =====================================================================
// Block 10: CRUD Operations
// =====================================================================

// CREATE — Submit new Contribution from Modal
function submitCreate() {
    var category = document.getElementById('create-category').value;
    var title = document.getElementById('create-title').value.trim();
    var description = document.getElementById('create-description').value.trim();
    var geom = document.getElementById('create-geom').value;
    var geomType = document.getElementById('create-geom-type').value;

    // Validate
    if (!category) {
        Swal.fire('Kategorie fehlt', 'Bitte wählen Sie eine Kategorie aus.', 'warning');
        return;
    }
    if (!title) {
        Swal.fire('Titel fehlt', 'Bitte geben Sie einen Titel ein.', 'warning');
        return;
    }
    if (!geom) {
        Swal.fire('Geometrie fehlt', 'Bitte zeichnen Sie zuerst ein Objekt auf der Karte.', 'warning');
        return;
    }

    apiCall({
        action: 'create',
        municipality_id: MUNICIPALITY.id,
        category: category,
        title: title,
        description: description,
        geom: geom,
        geom_type: geomType,
        author_name: currentUser
    }, function (response) {
        if (response.error) {
            Swal.fire('Fehler', response.error, 'error');
            return;
        }

        Swal.fire('Eingereicht!', 'Ihr Beitrag wurde erfolgreich eingereicht und wird nach Prüfung veröffentlicht.', 'success');
        closeCreateModal();
        loadContributions();
    });
}

// Cancel Create — close Modal and clear Form
function cancelCreate() {
    closeCreateModal();
}

function closeCreateModal() {
    document.getElementById('create-modal').style.display = 'none';
    document.getElementById('create-category').value = '';
    document.getElementById('create-title').value = '';
    document.getElementById('create-description').value = '';
    document.getElementById('create-geom').value = '';
    document.getElementById('create-geom-type').value = '';
    drawnGeometry = null;
    drawnGeomType = null;
}

// UPDATE — Edit an existing Contribution
function editContribution(contributionId) {
    // Find Contribution in local Data
    var contribution = contributionsData.find(function (f) {
        return f.properties.contribution_id === contributionId;
    });

    if (!contribution) return;

    var props = contribution.properties;

    Swal.fire({
        title: 'Beitrag bearbeiten',
        html:
            '<div style="text-align:left;">' +
                '<label style="font-weight:600;font-size:0.85rem;">Titel</label>' +
                '<input id="swal-title" class="swal2-input" value="' + escapeHtml(props.title) + '">' +
                '<label style="font-weight:600;font-size:0.85rem;">Beschreibung</label>' +
                '<textarea id="swal-description" class="swal2-textarea">' + escapeHtml(props.description || '') + '</textarea>' +
            '</div>',
        showCancelButton: true,
        confirmButtonText: 'Speichern',
        cancelButtonText: 'Abbrechen',
        confirmButtonColor: MUNICIPALITY.primaryColor,
        preConfirm: function () {
            return {
                title: document.getElementById('swal-title').value.trim(),
                description: document.getElementById('swal-description').value.trim()
            };
        }
    }).then(function (result) {
        if (!result.isConfirmed) return;

        apiCall({
            action: 'update',
            contribution_id: contributionId,
            title: result.value.title,
            description: result.value.description
        }, function (response) {
            if (response.error) {
                Swal.fire('Fehler', response.error, 'error');
                return;
            }
            Swal.fire('Gespeichert!', 'Der Beitrag wurde aktualisiert.', 'success');
            loadContributions();
        });
    });
}

// DELETE — Delete a Contribution
function deleteContribution(contributionId) {
    Swal.fire({
        title: 'Beitrag löschen?',
        text: 'Diese Aktion kann nicht rückgängig gemacht werden.',
        icon: 'warning',
        showCancelButton: true,
        confirmButtonText: 'Löschen',
        cancelButtonText: 'Abbrechen',
        confirmButtonColor: '#c62828'
    }).then(function (result) {
        if (!result.isConfirmed) return;

        apiCall({
            action: 'delete',
            contribution_id: contributionId
        }, function (response) {
            if (response.error) {
                Swal.fire('Fehler', response.error, 'error');
                return;
            }
            Swal.fire('Gelöscht!', 'Der Beitrag wurde entfernt.', 'success');
            map.closePopup();
            loadContributions();
        });
    });
}

// VOTE — Like or Dislike a Contribution
function voteContribution(contributionId, voteType) {
    if (!currentUser) {
        Swal.fire('Bitte anmelden', 'Sie müssen sich anmelden, um abzustimmen.', 'info');
        showLoginModal();
        return;
    }

    apiCall({
        action: 'vote',
        contribution_id: contributionId,
        voter_name: currentUser,
        vote_type: voteType
    }, function (response) {
        if (response.error) {
            Swal.fire('Hinweis', response.error, 'info');
            return;
        }

        // Update Vote Counts in the Popup without reloading everything
        loadContributions();
    });
}


// =====================================================================
// Block 11: Sidebar — Contributions List
// =====================================================================

function updateContributionsList() {
    var container = document.getElementById('contributions-list');
    var searchInput = document.getElementById('list-search-input');
    var searchTerm = searchInput ? searchInput.value.toLowerCase() : '';

    // Filter by active Categories and Search Term
    var filtered = contributionsData.filter(function (f) {
        var props = f.properties;
        var matchesCategory = activeFilters.indexOf(props.category) !== -1;
        var matchesSearch = !searchTerm ||
            props.title.toLowerCase().indexOf(searchTerm) !== -1 ||
            (props.description && props.description.toLowerCase().indexOf(searchTerm) !== -1) ||
            props.author_name.toLowerCase().indexOf(searchTerm) !== -1;
        return matchesCategory && matchesSearch;
    });

    // Sort by Date (newest first)
    filtered.sort(function (a, b) {
        return new Date(b.properties.created_at) - new Date(a.properties.created_at);
    });

    // Build HTML
    if (filtered.length === 0) {
        container.innerHTML = '<p style="text-align:center;color:#999;padding:20px;">Keine Beiträge gefunden.</p>';
        return;
    }

    var html = '';
    filtered.forEach(function (f) {
        var props = f.properties;
        var cat = CATEGORIES[props.category] || CATEGORIES.other;
        var date = new Date(props.created_at).toLocaleDateString('de-DE');

        html += '' +
            '<div class="contribution-card" onclick="flyToContribution(' + props.contribution_id + ')">' +
                '<div class="contribution-card-header">' +
                    '<span class="contribution-card-category">' + cat.icon + ' ' + cat.label + '</span>' +
                '</div>' +
                '<div class="contribution-card-title">' + escapeHtml(props.title) + '</div>' +
                '<div class="contribution-card-meta">' +
                    '<span>' + escapeHtml(props.author_name) + ' · ' + date + '</span>' +
                    '<span class="contribution-card-votes">' +
                        '<span title="Likes"><i class="fa-solid fa-thumbs-up"></i> ' + props.likes_count + '</span>' +
                        '<span title="Dislikes"><i class="fa-solid fa-thumbs-down"></i> ' + props.dislikes_count + '</span>' +
                    '</span>' +
                '</div>' +
            '</div>';
    });

    container.innerHTML = html;
}

// Fly to a Contribution on the Map and open its Popup
function flyToContribution(contributionId) {
    if (!contributionsLayer) return;

    contributionsLayer.eachLayer(function (layer) {
        if (layer.feature && layer.feature.properties.contribution_id === contributionId) {
            // Zoom to Feature
            if (layer.getLatLng) {
                // Point Feature
                map.flyTo(layer.getLatLng(), 17);
            } else if (layer.getBounds) {
                // Line or Polygon Feature
                map.flyToBounds(layer.getBounds(), { maxZoom: 17 });
            }
            // Open Popup
            layer.openPopup();
            // Close Sidebar on Mobile
            if (window.innerWidth < 769) {
                sidebar.close();
            }
        }
    });
}

// Search Input Event Listener
document.getElementById('list-search-input').addEventListener('input', function () {
    updateContributionsList();
});


// =====================================================================
// Block 12: Sidebar — Category Filter and Statistics
// =====================================================================

// Build Category Filter Checkboxes
function buildCategoryFilter() {
    var container = document.getElementById('category-filter');
    var html = '';

    for (var key in CATEGORIES) {
        var cat = CATEGORIES[key];
        var checked = activeFilters.indexOf(key) !== -1 ? 'checked' : '';

        html += '' +
            '<label style="display:flex;align-items:center;gap:8px;margin-bottom:6px;cursor:pointer;">' +
                '<input type="checkbox" value="' + key + '" ' + checked + ' onchange="toggleCategoryFilter(this)">' +
                '<span style="display:inline-block;width:12px;height:12px;border-radius:50%;background:' + cat.color + ';"></span>' +
                '<span>' + cat.icon + ' ' + cat.label + '</span>' +
            '</label>';
    }

    container.innerHTML = html;
}

// Toggle a Category Filter on/off
function toggleCategoryFilter(checkbox) {
    var category = checkbox.value;

    if (checkbox.checked) {
        if (activeFilters.indexOf(category) === -1) {
            activeFilters.push(category);
        }
    } else {
        activeFilters = activeFilters.filter(function (c) { return c !== category; });
    }

    // Re-filter the Map Layer
    if (contributionsLayer) {
        contributionsLayer.eachLayer(function (layer) {
            if (layer.feature) {
                var cat = layer.feature.properties.category;
                if (activeFilters.indexOf(cat) !== -1) {
                    layer.setStyle({ opacity: 1, fillOpacity: layer.feature.geometry.type === 'Point' ? 0.9 : 0.25 });
                    if (layer.setRadius) layer.setRadius(8);
                } else {
                    layer.setStyle({ opacity: 0, fillOpacity: 0 });
                    if (layer.setRadius) layer.setRadius(0);
                }
            }
        });
    }

    // Update List
    updateContributionsList();
}

// Update Statistics in Home Tab
function updateStatistics() {
    var container = document.getElementById('stats-container');
    var total = contributionsData.length;

    // Count per Category
    var counts = {};
    contributionsData.forEach(function (f) {
        var cat = f.properties.category;
        counts[cat] = (counts[cat] || 0) + 1;
    });

    var html = '<p style="font-size:0.9rem;"><strong>' + total + '</strong> Beiträge insgesamt</p>';

    for (var key in CATEGORIES) {
        var cat = CATEGORIES[key];
        var count = counts[key] || 0;
        if (count > 0) {
            html += '<div style="display:flex;align-items:center;gap:8px;margin:4px 0;font-size:0.85rem;">' +
                '<span style="display:inline-block;width:10px;height:10px;border-radius:50%;background:' + cat.color + ';"></span>' +
                cat.label + ': ' + count +
            '</div>';
        }
    }

    container.innerHTML = html;
}


// =====================================================================
// Block 13: Modals — Welcome, Login, Info, Privacy, Imprint
// =====================================================================

// Welcome Modal — show on first Visit
function checkWelcomeModal() {
    var hasVisited = localStorage.getItem('webgis_welcomed');
    if (!hasVisited) {
        document.getElementById('welcome-modal').style.display = 'flex';
    }
}

function closeWelcomeAndShowLogin() {
    localStorage.setItem('webgis_welcomed', 'true');
    document.getElementById('welcome-modal').style.display = 'none';
    showLoginModal();
}

// Login Modal
function showLoginModal() {
    document.getElementById('login-modal').style.display = 'flex';
    document.getElementById('user-name-input').value = currentUser;
    document.getElementById('user-name-input').focus();
}

function submitLogin() {
    var name = document.getElementById('user-name-input').value.trim();
    if (!name) {
        Swal.fire('Name eingeben', 'Bitte geben Sie Ihren Namen ein.', 'warning');
        return;
    }
    currentUser = name;
    sessionStorage.setItem('webgis_user', currentUser);
    document.getElementById('login-modal').style.display = 'none';
}

function skipLogin() {
    document.getElementById('login-modal').style.display = 'none';
}

// Info Modal
function showInfoModal() {
    Swal.fire({
        title: 'Über das Portal',
        html: '<p style="text-align:left;line-height:1.6;">Das Bürgerbeteiligungsportal ermöglicht es ' +
              'Bürgerinnen und Bürgern sowie der Stadtverwaltung, gemeinsam an der Gestaltung von ' +
              '<strong>' + MUNICIPALITY.name + '</strong> mitzuwirken.</p>' +
              '<p style="text-align:left;line-height:1.6;">Tragen Sie Hinweise, Ideen und Verbesserungsvorschläge ' +
              'direkt auf der Karte ein.</p>',
        confirmButtonColor: MUNICIPALITY.primaryColor
    });
}

// Privacy Modal
function showPrivacyModal() {
    Swal.fire({
        title: 'Datenschutz',
        html: '<p style="text-align:left;line-height:1.6;">Dieses Portal speichert die von Ihnen ' +
              'eingegebenen Daten (Name, Beiträge, Bewertungen) zur Durchführung der Bürgerbeteiligung.</p>' +
              '<p style="text-align:left;line-height:1.6;">Ihre Daten werden nicht an Dritte weitergegeben. ' +
              'Details entnehmen Sie bitte der vollständigen Datenschutzerklärung der Stadt ' +
              MUNICIPALITY.name + '.</p>',
        confirmButtonColor: MUNICIPALITY.primaryColor
    });
}

// Imprint Modal
function showImprintModal() {
    Swal.fire({
        title: 'Impressum',
        html: '<p style="text-align:left;line-height:1.6;">Stadt ' + MUNICIPALITY.name + '</p>' +
              '<p style="text-align:left;line-height:1.6;color:#777;">Die vollständigen Angaben gemäß § 5 TMG ' +
              'werden hier ergänzt, sobald das Portal in den Produktivbetrieb geht.</p>',
        confirmButtonColor: MUNICIPALITY.primaryColor
    });
}


// =====================================================================
// Block 14: Mobile Navigation
// =====================================================================

function toggleMobileNav() {
    var nav = document.querySelector('.header-nav');
    nav.classList.toggle('open');
}

// Close Mobile Nav when clicking outside
document.addEventListener('click', function (e) {
    var nav = document.querySelector('.header-nav');
    var toggle = document.querySelector('.header-menu-toggle');

    if (nav.classList.contains('open') && !nav.contains(e.target) && !toggle.contains(e.target)) {
        nav.classList.remove('open');
    }
});

// Close Modals on Escape Key
document.addEventListener('keydown', function (e) {
    if (e.key === 'Escape') {
        document.getElementById('welcome-modal').style.display = 'none';
        document.getElementById('login-modal').style.display = 'none';
        document.getElementById('create-modal').style.display = 'none';
    }
});


// =====================================================================
// Block 15: Utility Functions
// =====================================================================

// Escape HTML to prevent XSS in Popups and Lists
function escapeHtml(text) {
    if (!text) return '';
    var div = document.createElement('div');
    div.appendChild(document.createTextNode(text));
    return div.innerHTML;
}


// =====================================================================
// Block 16: Application Startup
// =====================================================================

// Initialize Category Filter in Sidebar
buildCategoryFilter();

// Load Contributions from API
loadContributions();

// Show Welcome Modal on first Visit
checkWelcomeModal();