import { getColorCodeAndText, getMarkerIcon } from './marker-display-utils.js';
import { showToast, mylog, wait } from './sc-utilities.js';
import { handleBsUpdate } from './bs-gen-co.js';
import { UpdateMarkerIcon } from './map-poi-mgr.js';
import { getCurrentUser } from './sc-utilities.js';
import { mapState, shouldPanToElement } from './map-gen-mgr.js';
import { demarcateElement } from './map-gen-mgr.js';
import { detachSwipeListeners, detachClusterBsListener } from './bs-cluster-co.js';
import {removeAddressMarker } from './gui-address-co.js';


/**
 * Aktualisiert den Reinigungsstatus aller Stolpersteine in einem Cluster 
 * auf dem Backend und aktualisiert die UI (Marker-Icons und Cluster-Layer)
 *
 * @param {L.MarkerClusterGroup} cluster - Das geklickte Cluster-Objekt, das die Kinder enthält.
 * @param {L.MarkerClusterGroup} markersLayer - Die Hauptmarker-Gruppe (zum Refresh der Cluster).
 * @param {*} backendServiceInstance - Der Backend-Service zur Durchführung der API-Aufrufe.
 * @param {boolean} needsCleaning - TRUE, um die Steine als schmutzig (needs_cleaning=true) zu markieren; FALSE, um sie als sauber (last_cleaned) zu markieren.
 * @returns {Promise<void>}
 */
export function handleCleaningsStatusAllCluster(cluster, markersLayer, backendServiceInstance, needsCleaning) {
    
    // needsCleaning: TRUE -> Steine als schmutzig markieren.
    // needsCleaning: FALSE -> Steine als sauber markieren.
    
    console.log("handleCleaningsStatusAllCluster aufgerufen für:", cluster.getChildCount(), "Stolpersteine.");
    const childMarkers = cluster.getAllChildMarkers();

    const username = getCurrentUser(); 

    const updatePromises = childMarkers.map(marker => {
        const poiId = marker.options.data.gid;

        // Der Status-Parameter, der an das Backend übergeben wird.
        const isDirtyStatus = needsCleaning; 

        const data = {
            gid: poiId,
            username: username,
            deviceInfo: {
                os: "Web",
                version: "1.0",
                model: "Browser",
            },
        };

        return backendServiceInstance.updateStoneCleaningStatus(data, isDirtyStatus)
            .then(response => {
                if (!response.success) {
                    throw new Error(response.error || `Unbekannter Fehler bei der Serverantwort für POI ${poiId}.`);
                }
                console.log(`POI ${poiId} erfolgreich aktualisiert:`, response);
                 return { 
                    id: poiId, 
                    success: true, 
                    last_cleaned: response.last_cleaned, 
                    needs_cleaning: response.needs_cleaning, 
                    markerInstance: marker 
                };
            })
            .catch(error => {
                console.error(`Fehler beim Aktualisieren von POI ${poiId}:`, error);
                showToast("Fehler", `Konnte POI ${poiId} nicht aktualisieren: ${error.message}`, 'error');
                return { id: poiId, success: false, error: error.message };
            });
    });

    Promise.all(updatePromises).then(results => {
        const successfulUpdates = results.filter(r => r.success);
        const failedUpdates = results.filter(r => !r.success).length;
        
        const actionText = needsCleaning ? "schmutzig markiert" : "gereinigt markiert";

        successfulUpdates.forEach(updateInfo => {
            const marker = updateInfo.markerInstance;
            
            if (marker) {
                // Lokale Daten aktualisieren
                marker.options.data.last_cleaned = updateInfo.last_cleaned;
                marker.options.data.needs_cleaning = updateInfo.needs_cleaning;
                
                // UI mit neuer Signatur aktualisieren
                UpdateMarkerIcon(marker, false);
            }
        });

        // Cluster-Refresh und Toast
        if (successfulUpdates.length > 0 && typeof markersLayer.refreshClusters === 'function') {
             markersLayer.refreshClusters();
             showToast(`${successfulUpdates.length} Stolpersteine wurden markiert.`);
        } else if (successfulUpdates.length > 0) {
             showToast(`${successfulUpdates.length} Stolpersteine wurden markiert.`);
        }

        if (failedUpdates > 0) {
            showToast("Warnung", `${failedUpdates} Stolpersteine konnten nicht markiert werden. Bitte wiederholen`);
        }
        if (successfulUpdates.length === 0 && failedUpdates === 0) {
            alert("App Fehler: keine Stolpersteine gefunden");
        }

    }).catch(overallError => {
        console.error("Ein unerwarteter Gesamtfehler beim Aktualisieren der Stolpersteine ist aufgetreten:", overallError);
        showToast("Schwerwiegender Fehler", "Ein unerwarteter Fehler ist beim Aktualisieren der Stolpersteine aufgetreten.", 'error');
    });
}

/**
 * Speichert die aktuellen Inline-Styles eines Cluster-Elements, bevor sie geändert werden.
 * Die originalen Styles werden direkt am Cluster-Objekt unter `_originalStyles` gespeichert.
 * @param {HTMLElement} clusterElement - Das DOM-Element des Cluster-Icons.
 * @param {L.MarkerCluster} cluster - Das L.MarkerCluster Objekt.
 */
function saveClusterOriginalStyles(clusterElement, cluster) {
    if (!cluster._originalStyles) {
        cluster._originalStyles = {};
    }
    cluster._originalStyles.zIndex = clusterElement.style.zIndex;
    cluster._originalStyles.opacity = clusterElement.style.opacity;
    cluster._originalStyles.boxShadow = clusterElement.style.boxShadow;
    cluster._originalStyles.border = clusterElement.style.border;
    cluster._originalStyles.borderRadius = clusterElement.style.borderRadius; // Auch border-radius speichern
    console.log("DEBUG: Original Cluster-Styles gespeichert:", cluster._originalStyles);
}

/**
 * Wendet die Hervorhebungs-Stile auf ein Cluster-Element an.
 * @param {HTMLElement} clusterElement - Das DOM-Element des Cluster-Icons.
 */
function applyClusterHighlightStyles(clusterElement) {
    clusterElement.style.zIndex = '1000';
    clusterElement.style.opacity = '1';
    clusterElement.style.boxShadow = '0 0 20px rgba(0, 0, 0, 0.7)';
    clusterElement.style.border = '5px solid rgb(0, 0, 0)';
    clusterElement.style.borderRadius = '50%';
    console.log("DEBUG: Highlight-Styles angewendet.");
}


/**
 * Stellt die ursprünglichen Inline-Styles eines Cluster-Elements wieder her.
 * @param {HTMLElement} clusterElement - Das DOM-Element des Cluster-Icons.
 * @param {L.MarkerCluster} cluster - Das L.MarkerCluster Objekt.
 */
export function restoreClusterOriginalStyles(clusterElement, cluster) {
    if (cluster && clusterElement) {
        console.log("DEBUG restoreClusterOriginalStyles: Wiederherstellung gestartet für Cluster ID:", cluster._leaflet_id);
        clusterElement.style.removeProperty('z-index');
        clusterElement.style.removeProperty('opacity');
        clusterElement.style.removeProperty('box-shadow');
        clusterElement.style.removeProperty('border');
        clusterElement.style.removeProperty('border-radius');

        if (cluster._originalStyles) {
            delete cluster._originalStyles;
            console.log("DEBUG restoreClusterOriginalStyles: _originalStyles Objekt für Cluster ID:", cluster._leaflet_id, "gelöscht.");
        }
        console.log("DEBUG restoreClusterOriginalStyles: Alle potenziellen Highlight-Styles von Cluster ID:", cluster._leaflet_id, "entfernt.");
    } else {
        console.log("DEBUG restoreClusterOriginalStyles: Ungültiges Cluster/Element erhalten (ID:", cluster ? cluster._leaflet_id : 'N/A', ").");
    }
}

/**
 * Bestimmt den Kontext des Klicks/Swipes basierend auf dem aktiven Zustand der Karte.
 * @param {L.MarkerCluster|L.Marker} clickedCluster - Der Cluster oder Marker, der angeklickt/geswiped wurde.
 * @param {Object} mapState - Das Zustandsobjekt, das aktive Elemente und den Spiderfy-Status speichert.
 * @returns {string} Einer der 6 Kontext-Strings: 'SameClusterParent', 'SameClusterChild', 'OtherClusterParent', 'OtherClusterChild', 'SinglePOI', 'None'.
 */
function determinePriorContext(clickedCluster, mapState) {
    const activeElement = mapState.activeMarkerOrCluster;
    // Prüft, ob es sich um ein Leaflet.MarkerCluster-Objekt handelt
    const isCluster = clickedCluster.getAllChildMarkers; 

    // -----------------------------------------------------------
    // 💡 LOG START: Initialer Zustand
    console.log("DEBUG Context Check: Starte Bestimmung des vorherigen Kontexts.");
    console.log(`DEBUG Context Check: clickedCluster ID (Child Count): ${isCluster ? clickedCluster._leaflet_id + ' (' + clickedCluster.getAllChildMarkers().length + ' children)' : clickedCluster._leaflet_id + ' (Marker)'}`);
    console.log(`DEBUG Context Check: mapState.activeMarkerOrCluster (Typ/ID): ${
        activeElement 
        ? (activeElement.getAllChildMarkers ? 'Cluster (' + activeElement.getAllChildMarkers().length + ' children)' : 'Marker (GID ' + activeElement.options.data.gid + ')') 
        : 'NULL'
    }`);
    // -----------------------------------------------------------

    // 6. NONE: Es war kein Element aktiv.
    if (!activeElement) {
        console.log("DEBUG Context Result: NONE - Kein aktives Element gefunden.");
        return 'None';
    }

    // 4. SAME CLUSTER PARENT: Der angeklickte Cluster ist bereits aktiv.
    // Kann nur passieren, wenn der aktive Marker selbst ein Cluster ist.
    if (activeElement === clickedCluster) {
        console.log("DEBUG Context Result: SAME CLUSTER PARENT - Cluster ist bereits aktiv.");
        return 'SameClusterParent';
    }

    // Ab hier ist activeElement != clickedCluster.

    // Wenn beide Elemente Cluster sind (und sie nicht identisch sind)
    if (activeElement.getAllChildMarkers && isCluster) {
        console.log("DEBUG Context Result: OTHER CLUSTER PARENT - Wechsel von Cluster A zu Cluster B.");
        return 'OtherClusterParent'; // ✅ Korrekter Wechsel von Cluster A zu Cluster B
    }

    // Wenn der aktive Zustand ein Kind-Marker (POI) ist:
    if (activeElement instanceof L.Marker) {
        
        // -----------------------------------------------------------------
        // 🔥 KRITISCHER FIX: Hier kommt die stabile Zustandsprüfung.
        // -----------------------------------------------------------------
        const storedParent = mapState.parentClusterOfActiveMarker;
        const parentOfActiveMarker = activeElement.__parent;

        const storedParentId = storedParent ? storedParent._leaflet_id : 'NULL';
        const clickedClusterId = clickedCluster._leaflet_id;
        const legacyParentId = parentOfActiveMarker ? parentOfActiveMarker._leaflet_id : 'NULL';

        console.log(`DEBUG Context Check POI: Aktiver Marker GID: ${activeElement.options.data.gid}`);
        console.log(`DEBUG Context Check POI: mapState.parentClusterOfActiveMarker ID: ${storedParentId}`);
        console.log(`DEBUG Context Check POI: Aktiver Marker __parent ID (Legacy): ${legacyParentId}`);
        console.log(`DEBUG Context Check POI: clickedCluster ID: ${clickedClusterId}`);


        let isSameClusterChild = false;
        
        // **5. SAME CLUSTER CHILD (ROBUST)**: Prüfe, ob der aktive Marker in diesem geklickten Cluster enthalten ist.
        if (isCluster && clickedCluster.getAllChildMarkers) {
            const activeMarkerGID = activeElement.options.data.gid;
            const clusterChildren = clickedCluster.getAllChildMarkers(); 
            
            isSameClusterChild = clusterChildren.some(childMarker => 
                childMarker.options.data && childMarker.options.data.gid === activeMarkerGID
            );
            
            console.log(`DEBUG Context Check GID: Aktiver GID (${activeMarkerGID}) in geklicktem Cluster enthalten? ${isSameClusterChild ? 'JA' : 'NEIN'}`);
        }
        
        if (isSameClusterChild) {
            console.log("DEBUG Context Result: SAME CLUSTER CHILD - Match über Child-Enthaltung erkannt. ✅");
            
            // Optional: Zustandskorrektur, falls die IDs (15347/15356) benötigt werden.
            // mapState.parentClusterOfActiveMarker = clickedCluster; 
            
            return 'SameClusterChild';
        }
        
        // 3. SINGLE POI (Anderer POI oder Cluster): 
        // Der Klick ist NICHT der Parent des aktiven Markers.
        console.log("DEBUG Context Result: SINGLE POI - Klick ist NICHT der Parent des aktiven Markers.");
        return 'SinglePOI';
    }

    // Wenn der aktive Zustand ein ANDERER Cluster ist:
    if (activeElement.getAllChildMarkers) { // activeElement ist ein MarkerCluster

        // Prüfen, ob der aktive Cluster gespidert ist.
        // WICHTIG: mapState.currentlySpiderfiedCluster MUSS die L.MarkerCluster-Instanz speichern.
        const activeClusterIsSpiderfied = mapState.currentlySpiderfiedCluster === activeElement;

        if (activeClusterIsSpiderfied) {
            console.log("DEBUG Context Result: OTHER CLUSTER CHILD - Wechsel von gespidertem Cluster zu neuem Cluster/POI.");
            return 'OtherClusterChild'; 
        }

        // 2. OTHER CLUSTER PARENT: Ein anderer, nicht gespiderter Cluster war aktiv.
        console.log("DEBUG Context Result: OTHER CLUSTER PARENT - Wechsel von Cluster A zu neuem Cluster/POI.");
        return 'OtherClusterParent';
    }

    // Fallback (sollte nicht erreicht werden)
    console.error('ERROR Context Result: Unbekannter oder unvollständiger Kontext-Fall ermittelt.');
    return 'None';
}


/**
 * Führt die Hauptlogik für einen Klick auf einen Cluster oder Marker aus.
 * Diese Funktion wird sowohl vom 'clusterclick'-Event-Handler als auch 
 * von der Swipe-Funktionalität aufgerufen.
 *
 * @param {L.MarkerCluster|L.Marker} clickedElement - Der geklickte/ausgewählte Cluster oder Marker.
 * @param {L.MarkerClusterGroup} markers - Die Haupt-Marker-Gruppe.
 * @param {L.Map} map - Die Leaflet-Karteninstanz.
 * @param {Object} bottomSheetUI - Die Instanz des Bottom Sheet UI.
 * @param {Object} backendService - Die Instanz des Backend Service.
 * @param {function(): boolean} getAdminModeStatus - Funktion zum Abfragen des Admin-Modus-Status.
 * @param {Object} mapState - Das globale Zustandsobjekt der Karte.
 * @returns {Promise<void>}
 */
export async function handleClusterClickLogic(clickedElement, markers, map, bottomSheetUI, backendService, getAdminModeStatus, mapState) {
    
    const clickedCluster = clickedElement; // Benutzen Sie weiterhin den alten Namen für die Logik

    removeAddressMarker(map); 
    
    // Annahme: determinePriorContext() gibt einen String zurück (z.B. 'SameClusterChild', 'OtherClusterParent' etc.)
    const priorContext = determinePriorContext(clickedCluster, mapState);
    const activeElement = mapState.activeMarkerOrCluster;

    // Hilfs-Variablen für die Steuerung der Phasen 2 & 3
    let shouldSpiderfy = false;

    // Definition der Fälle, die eine Karten-Navigation (Zoom/Pan/Spiderfy) benötigen (Fälle 1, 2, 3, 6)
    // Jetzt inklusive Fall 2 ('OtherClusterParent') und Fall 3 ('SinglePOI'), wie gewünscht.
    const needsNavigation = ['OtherClusterChild', 'OtherClusterParent', 'SinglePOI', 'None'].includes(priorContext);

    // Definition der Fälle, die den alten Zustand aufräumen müssen (alle außer Fall 4 und 6)
    const needsCleanup = ['OtherClusterChild', 'OtherClusterParent', 'SinglePOI', 'SameClusterChild'].includes(priorContext);

    // ====================================================================
    // 💥 PHASE 1: AUFRÄUMEN (Demarkieren & ggf. Unspiderfy)
    // ====================================================================

    // Demarkieren des zuvor aktiven Elements, falls nötig
    if (activeElement && needsCleanup) {
        demarcateElement(activeElement, mapState);
    }

    // Unspiderfy nur, wenn wir zu einem NEUEN Cluster (Fälle 1, 2, 3) wechseln, 
    // um den alten gespiderten Zustand zu entfernen.
    if (priorContext === 'OtherClusterChild' || priorContext === 'OtherClusterParent' || priorContext === 'SinglePOI') {
        unspiderfyCluster(markers, mapState);
    }

    // Fall 4 ('SameClusterParent') führt direkt zur Markierung und BS-Aktualisierung (Phase 3/4)
    if (priorContext !== 'SameClusterParent') {
        // Active State für NEUE Klicks setzen (Fälle 1, 2, 3, 5, 6)
        mapState.activeMarkerOrCluster = clickedCluster;

        // ====================================================================
        // 🗺️ PHASE 2: NAVIGIEREN (ggf. Zoomen & Pannen)
        // ====================================================================
        if (needsNavigation) {
            // willClusterSpiderfy gibt true für Spiderfy, false für fitBounds zurück
            shouldSpiderfy = willClusterSpiderfy(clickedCluster);

            if (!shouldSpiderfy) {
                // Wenn willClusterSpiderfy FALSE zurückgibt: Zoom/Pan zur Bounds
                // (Marker liegen weit auseinander oder > 50 Marker)
                /* map.fitBounds(clickedCluster.getBounds(),   {            // Begrenzt den Zoom auf maximal Level 16, selbst wenn Marker extrem nah liegen.
                        maxZoom: 17 }); */
                map.fitBounds(clickedCluster.getBounds());
                bottomSheetUI.close(); // BS schließen
                mapState.activeMarkerOrCluster = null; // Den aktiven Zustand zurücksetzen
                console.log("DEBUG: Nur Zoom-Navigation durchgeführt, Bottom Sheet geschlossen.");
                return; // Beendet den Handler, da Phase 3/4 nicht relevant sind
            }

            // Wenn shouldSpiderfy TRUE ist, passiert die Navigation erst in Phase 3
            // über den Aufruf von clickedCluster.spiderfy().
        }

        // ====================================================================
        // 📍 PHASE 3: INITIALISIEREN (ggf. Spiderfy & Markieren)
        // ====================================================================

        // Markieren des neuen/geänderten aktiven Elements
        if (clickedCluster._icon) {
            highlightCluster(clickedCluster._icon, clickedCluster, mapState);
        }

        if (shouldSpiderfy) {
            // Wenn willClusterSpiderfy TRUE war: Spiderfy ausführen
            setTimeout(() => {
                clickedCluster.spiderfy();
                mapState.currentlySpiderfiedCluster = clickedCluster;
                console.log(`DEBUG Spiderfy: Cluster gespidert (mit Delay).`);
            }, 200);
        }
        // Fall 5 ('SameClusterChild'): Kein erneutes Spiderfy und kein Zoom (Phase 2 ist 'needsNavigation'=false),
        // da der Zustand beibehalten wird und die Position bereits optimal ist.

    } else {
        // 📍 PHASE 3 (für Fall 4: SameClusterParent)
        // Das Element ist bereits aktiv, wir aktualisieren nur das Highlight.
        if (clickedCluster._icon) {
            highlightCluster(clickedCluster._icon, clickedCluster, mapState);
        }
    }

    // ====================================================================
    // 📜 PHASE 4: BOTTOM SHEET AKTUALISIEREN
    // ====================================================================
    // Wird in allen 6 Fällen aufgerufen, um den Inhalt des Bottom Sheets zu aktualisieren
    handleBsUpdate(
        clickedCluster,
        bottomSheetUI,
        mapState,
        getAdminModeStatus,
        markers,
        map,
        backendService  
    );
}

/**
 * Richtet Event-Listener für Marker und Cluster auf der Karte ein.
 * @param {L.Map} map - Die Leaflet-Karteninstanz.
 * @param {L.MarkerClusterGroup} markers - Die Marker-Cluster-Gruppe.
 * @param {Object} bottomSheetUI - Die Instanz des Bottom Sheet UI.
 * @param {Object} backendService - Die Instanz des Backend Service.
 * @param {function(): boolean} getAdminModeStatus - Funktion zum Abfragen des Admin-Modus-Status.
 */

export function setupClusterEventListeners(map, markers, bottomSheetUI, backendService, getAdminModeStatus) {

    markers.on('spiderfied', function (event) {
        const cluster = event.cluster;
        const clusterElement = cluster._icon;
        const childMarkers = cluster.getAllChildMarkers();

        // 1. Markierung des zuvor aktiven Elements entfernen
        // Hier wird sichergestellt, dass die Markierung nur entfernt wird, wenn ein aktives Element existiert
        // und dieses Element nicht das aktuelle Cluster ist.
        if (mapState.activeMarkerOrCluster) {
            const wasCluster = mapState.activeMarkerOrCluster.getAllChildMarkers;

            if (wasCluster) {
                if (mapState.activeMarkerOrCluster._icon) {
                    restoreClusterOriginalStyles(mapState.activeMarkerOrCluster._icon, mapState.activeMarkerOrCluster);
                }
            } else {
                const previousMarkerData = mapState.activeMarkerOrCluster.options.data;
                const previousMarkerColorCode = getColorCodeAndText(previousMarkerData.last_cleaned).colorCode;
                const originalIcon = L.divIcon({
                    className: "poi-icon " + previousMarkerColorCode,
                    html: getMarkerIcon(previousMarkerData.caretaker, previousMarkerColorCode),
                    iconSize: mapState.originalActiveMarkerSize || [24, 24],
                });
                mapState.activeMarkerOrCluster.setIcon(originalIcon);
            }
        }

        // 2. Den korrekten Marker finden und hervorheben
        const foundMarker = childMarkers.find(m => m.options.data && m.options.data.gid === mapState.activeMarkerOrClusterGID);

        if (foundMarker) {
            const currentIconSize = foundMarker.options.icon && foundMarker.options.icon.options ?
                foundMarker.options.icon.options.iconSize : [24, 24];
            const newIconSize = [currentIconSize[0] * 2, currentIconSize[1] * 2];
            const currentMarkerData = foundMarker.options.data;
            const currentMarkerColorCode = getColorCodeAndText(currentMarkerData.last_cleaned).colorCode;
            const newIcon = L.divIcon({
                className: "poi-icon " + currentMarkerColorCode + " active-marker",
                html: getMarkerIcon(currentMarkerData.caretaker, currentMarkerColorCode),
                iconSize: newIconSize,
            });
            foundMarker.setIcon(newIcon);
            mapState.activeMarkerOrCluster = foundMarker;

        } else {
            // Fallback: Wenn kein Marker-GID gespeichert ist oder gefunden wird, das Cluster hervorheben
            if (clusterElement) {
                saveClusterOriginalStyles(clusterElement, cluster);
                applyClusterHighlightStyles(clusterElement);
                mapState.activeMarkerOrCluster = cluster;
                mapState.activeMarkerOrClusterGID = cluster._leaflet_id;
            }
        }

        // 3. Statusvariablen aktualisieren
        cluster._isUserSpiderfied = true;
        mapState.currentlySpiderfiedCluster = cluster;
        console.log('DEBUG spiderfied-Event: Cluster wurde gespiderfied und Markierung angewendet. _isUserSpiderfied = true für:', cluster);
    });


    markers.on('unspiderfied', function (event) {
        const cluster = event.cluster;
        const clusterElement = cluster._icon;

        if (clusterElement) {
            restoreClusterOriginalStyles(clusterElement, cluster);
        }
        cluster._isUserSpiderfied = false;

        if (mapState.currentlySpiderfiedCluster === cluster) {
            mapState.currentlySpiderfiedCluster = null;
        }

    });

    markers.on('clusterclick', async function (event) {
        const clickedCluster = event.layer;
        
        // Ruft die extrahierte Logik auf
        await handleClusterClickLogic(
            clickedCluster, 
            markers, 
            map, 
            bottomSheetUI, 
            backendService, 
            getAdminModeStatus, 
            mapState
        );
    });

    bottomSheetUI.onClose(() => {
        console.log('DEBUG: bottomSheetUI.onClose-Callback ausgelöst.');

        // 1. Highlight vom aktiven Element entfernen
        if (mapState.activeMarkerOrCluster && mapState.activeMarkerOrCluster._icon) {
            console.log('DEBUG: mapState.activeMarkerOrCluster ist gesetzt. Wiederherstellung des Icons/Styles.');
            const isMarker = mapState.activeMarkerOrCluster.options && mapState.activeMarkerOrCluster.options.data;
            if (isMarker) {
                const markerData = mapState.activeMarkerOrCluster.options.data;
                if (markerData && typeof markerData.last_cleaned !== 'undefined' && typeof markerData.caretaker !== 'undefined') {
                    const colorCode = getColorCodeAndText(markerData.last_cleaned).colorCode;
                    const originalIcon = L.divIcon({
                        className: "poi-icon " + colorCode,
                        html: getMarkerIcon(markerData.caretaker, colorCode),
                        iconSize: mapState.originalActiveMarkerSize,
                    });
                    mapState.activeMarkerOrCluster.setIcon(originalIcon);
                } else {
                    console.warn('WARNUNG: Marker-Daten fehlen im aktiven Marker beim Versuch, das Original-Icon wiederherzustellen.');
                }
            } else {
                restoreClusterOriginalStyles(mapState.activeMarkerOrCluster._icon, mapState.activeMarkerOrCluster);
            }
        } else {
            console.log('DEBUG: Kein activeMarkerOrCluster oder Icon beim Schließen des Bottom Sheets.');
        }
        // 2. 🔥 WICHTIG: Swipe- und Link-Listener entfernen
        detachSwipeListeners(bottomSheetUI);
        detachClusterBsListener(bottomSheetUI);
        console.log('DEBUG: Swipe- und Link-Listener entfernt.');
        // 3. Globale mapState-Referenzen zurücksetzen
        mapState.activeMarkerOrCluster = null;
        mapState.activeMarkerOrClusterGID = null; 
        mapState.currentlySpiderfiedCluster = null;
        mapState.currentBottomSheetContentRef = null;
        console.log('DEBUG: mapState Referenzen zurückgesetzt.');
    });

    console.log("Map event listeners configured.");
}


/**
 * Entscheidet auf basis der marker-eck-koordinaten, ob ein Cluster bei einem Klick gespidert werden soll.
 * @param {L.MarkerCluster} cluster - Das Cluster-Objekt.
 * @returns {boolean} True, wenn der Cluster gespidert wird, ansonsten false.
 */
export function willClusterSpiderfy(cluster) {
    const childMarkers = cluster.getAllChildMarkers();

    if (childMarkers.length < 50 && childMarkers.length > 1) {

        // 1. Hole die Bounds des Clusters
        const bounds = cluster.getBounds();

        // 2. Erhalte die NW- und SO-Ecken der Bounds (Bounds-Diagonale)
        const nwCorner = bounds.getNorthWest(); // L.LatLng-Objekt (lat, lng)
        const seCorner = bounds.getSouthEast(); // L.LatLng-Objekt (lat, lng)

        // 3. Leaflet's eigene Methode zur Distanzberechnung verwenden (gibt Meter zurück)
        const distanceInMeters = nwCorner.distanceTo(seCorner);

        console.log(`DEBUG: Cluster Diagonale Distanz: ${distanceInMeters.toFixed(2)} Meter`);

        if (distanceInMeters > 5) { // Beispiel: wenn Diagonale größer als 5 Meter
            return false; // Marker sind zu weit auseinander, nicht spiderfyen
        } else {
            return true; // Marker liegen nah beieinander: Spiderfyen.
        }

    } else if (childMarkers.length >= 50) {
        return false;
    }

    return true; // Fallback
}

/**
 * Führt ein Unspiderfy des zuvor gespiderfied Clusters durch und setzt den zustandsrelevanten Teil im mapState zurück.
 * @param {L.MarkerClusterGroup} markers - Die Hauptmarker-Gruppe.
 * @param {object} mapState - Der globale Karten-Zustand.
 */
export function unspiderfyCluster(markers, mapState) {
    if (mapState.currentlySpiderfiedCluster) {
        // Im Gegensatz zur automatischen Bereinigung MUSS dies hier explizit ausgeführt werden,
        // um das alte Cluster VOR dem Öffnen des neuen zu bereinigen.
        markers.unspiderfy();
        mapState.currentlySpiderfiedCluster = null;
        console.log("DEBUG Unspiderfy: Altes Cluster bereinigt.");
    }
}
/**
 * Wendet Highlight-Styles auf das geklickte Cluster an.
 * @param {HTMLElement} clusterElement - Das DOM-Element des Clusters.
 * @param {L.MarkerCluster} clickedCluster - Das geklickte Cluster-Objekt.
 * @param {object} mapState - Der globale Karten-Zustand.
 */
export function highlightCluster(clusterElement, clickedCluster, mapState) {
    // Ihre Logik zum Speichern der Original-Styles und Anwenden des Highlight-Styles
    saveClusterOriginalStyles(clusterElement, clickedCluster);
    applyClusterHighlightStyles(clusterElement);
    console.log("DEBUG Highlight: Styles für neuen Cluster angewendet.");
}