/**
 * @fileoverview map-poi-mgr.js
 * Verwalten von Darstellung und Verhalten der POIs (= Stolpersteine)) auf der Karte.
 * Das Modul kümmert sich um Folgendes:
 * Marker-Interaktion: Es behandelt Klicks auf Marker oder Cluster.
 * Karten-UI: Es aktualisiert die visuelle Darstellung der Marker (z. B. Farbwechsel nach einer
 * Reinigung) und passt die Kartenzentrierung an.
 * Kommunikation: Es fungiert als Schnittstelle zwischen der Kartenansicht und den
 * Koordinatoren, die für die Inhalte des Bottom Sheets zuständig sind.
 */

import { getColorCodeAndText, getMarkerIcon } from './marker-display-utils.js';
// shouldPanToElement wird von der Map-Instanz abhängig sein
import { shouldPanToElement } from './map-gen-mgr.js'; 
import {  determinePriorContext} from './map-cluster-mgr.js';
import { mylog,showToast } from './sc-utilities.js';
import { fetchCoordForAddress } from './validate_address.js';
import { demarcateElement } from './map-gen-mgr.js';
// 🔥 NEU: Import der zentralen Map-Instanz aus dem Singleton-Modul
import { getMap } from './map-markers-co.js';



// Globale Variable für den temporären Vorschlagsmarker
let tempMarker;

// endscheidet, ob ein marker highlisted werden soll auf basis
// gid = gid des markers der zu ändern ist
// gid des aktiven Elements(wenn das ein cluster ist muss activeMarkerOrClusterGID auf null gesetzt sein)
export function isMarkerHighlighted(gid, mapState) {
    if (mapState.activeMarkerOrClusterGID !== mapState.activeMarkerOrCluster.options.data.gid) {
        console.warn("mapstate Fehler: marker.gid ungeleich mapstate gid");
    }

    return (gid === mapState.activeMarkerOrClusterGID)
}

/**
 * Aktualisiert das Icon eines Markers, basierend auf den bereits im Marker-Objekt
 * gespeicherten Daten lastCleaned und caretaker (marker.options.data) und dem übergebenen highligting-flag
 *
 * @param {L.Marker} marker - Die zu aktualisierende Marker-Instanz.
 * @param {boolean} isHighlighted - Sollen die 'active-marker' Styles angewendet werden?
 */
export function UpdateMarkerIcon(marker, isHighlighted) {
    // mapState ist hier nicht verfügbar, daher wird die Originalgröße hart codiert oder aus einer Konstante bezogen
    // Da Sie in der Originaldatei mapState.originalActiveMarkerSize verwendet hatten, 
    // sollte diese Konstante zentralisiert sein, aber hier zur Vereinfachung hart codiert:
    const originalSize = [24, 24]; 
    const scaledSize = [
        originalSize[0] * 2, // z.B. 48
        originalSize[1] * 2, // z.B. 48
    ];

    // Die tatsächliche Größe des DIV-Containers, die wir setzen wollen
    const iconSize = isHighlighted ? scaledSize : originalSize; 

    // Die notwendigen Daten abrufen
    const markerData = marker.options.data;
    const colorCode = getColorCodeAndText(markerData.last_cleaned).colorCode;
    const className = isHighlighted 
        ? "poi-icon " + colorCode + " active-marker" 
        : "poi-icon " + colorCode;
    
    // Icon neu erstellen und setzen
    const newIcon = L.divIcon({
        className: className,
        html: getMarkerIcon(markerData.caretaker, colorCode),
        iconSize: iconSize, // <-- WICHTIG: Setzt die Größe des .poi-icon DIVs!
        iconAnchor: [iconSize[0] / 2, iconSize[1]/2], // Ankerpunkt anpassen
    });
    
    marker.setIcon(newIcon);
}

    /**
     * Zeigt die aktuelle POI-Position und einen Marker für die vorgeschlagene neue Koordinate an.
     * Bricht OHNE FEEDBACK ab, wenn die Abweichung unter 2 Meter liegt (fachliche Vorgabe: "hält den Schnabel komplett").
     * Zentriert die Karte so, dass beide Punkte sichtbar sind.
     * * @param {number} oldLat - Gespeicherter Breitengrad.
     * @param {number} oldLng - Gespeicherter Längengrad.
     * @param {number} newLat - Neuer Breitengrad vom Backend.
     * @param {number} newLng - Neuer Längengrad vom Backend.
     * @param {string} poiId - ID des POI.
     * ❌ L.Map map Parameter ENTFERNT
     */
    function showMapWithNewSuggestion(oldLat, oldLng, newLat, newLng, poiId) {
        
        // 🔥 Map Instanz über Getter abrufen
        const map = getMap();

        const oldCoords = L.latLng(oldLat, oldLng); 
        const newCoords = L.latLng(newLat, newLng);
        
        // Distanz in Metern berechnen
        const distance = oldCoords.distanceTo(newCoords); 
        const distanceFormatted = distance.toFixed(1);

        // ⬅️ PRÜFUNG: Wenn die Abweichung zu gering ist, komplett abbrechen (kein Toast, kein Log).
        if (distance < 2) {
            // Aufräumen (entfernt nur den tempMarker, falls er aus einem vorherigen Klick noch da war)
            if (tempMarker) {
                map.removeLayer(tempMarker);
            }
            return; // Kompletter Abbruch ohne jegliche Ausgabe
        }
        
        // --- Nur wenn distance >= 2m, wird die Anzeige fortgesetzt ---
        
        mylog(`DEBUG: Koordinate wird vorgeschlagen. Abweichung: ${distanceFormatted}m.`);
        
        // 1. Karte zentrieren und auf beide Punkte fokussieren
        const bounds = L.latLngBounds(oldCoords, newCoords);
        map.fitBounds(bounds.pad(0.5), { maxZoom: 22 }); 

        // 2. Temporären Marker für den Vorschlag setzen (vorherigen Marker entfernen)
        if (tempMarker) {
            map.removeLayer(tempMarker);
        }
        
        // Marker für neuen Vorschlag
        tempMarker = L.marker([newLat, newLng]).addTo(map)
            .bindPopup(`**NEUER VORSCHLAG**<br>Abweichung: ${distanceFormatted} Meter`)
            .openPopup();
            
        // 3. Toast-Nachricht, da die Abweichung relevant ist
        showToast(`Koordinate gefunden. Abweichung: ${distanceFormatted} Meter. Bitte prüfen!`);
    }

/* Exportierte Funktion: Verarbeitet den Klick auf einen bestehenden POI (Stein).
 * Holt die aktuellen Backend-Koordinaten und zeigt den Unterschied (den Marker).
 * @param {Object} poiData - Die Daten des angeklickten Steins (vom Marker: options.data).
 * ❌ L.Map map Parameter ENTFERNT
 */
 async function handlePoiMarkerClick(poiData) {
    
    // 🔥 Map Instanz über Getter abrufen (wird nur für showMapWithNewSuggestion benötigt)
    // const map = getMap(); 
    
    // 1. Query-String montieren
    // poiData enthält: street, house_no, localdistrict
    mylog (`Prüfe aktuelle Koordinaten für "${poiData.street} ${poiData.house_no} ${poiData.localdistrict}"...`);

    try {
        // 2. Neue Funktion aufrufen (liefert Koords oder null)
        // fetchCoordForAddress erwartet das poiData-Objekt, was sauber ist
       const coords = await fetchCoordForAddress(poiData); 
        
        if (coords) {
            // 3. Marker setzen
            showMapWithNewSuggestion(
                poiData.lat,       // Alte lat
                poiData.lng,       // Alte lng
                coords.lat,        // Neue lat
                coords.lng,        // Neue lng
                poiData.gid
                // ❌ map Parameter entfernt
            );
        } else {
             showToast("Keine eindeutige neue Koordinate für diese Adresse gefunden (0 oder >1 Treffer).");
        }
    } catch (e) {
        // Der Fehler wird bereits in fetchCoordForAddress behandelt
        mylog("POI Klick Verarbeitung (Koord. Abruf) abgebrochen.");
    }
}
// Diese Funktion kümmert sich ausschließlich um die Aktionen auf der Karte, wie das Zurücksetzen von Stilen,
// das Hervorheben des neuen Markers und die Anpassung des Kartenausschnitts

/**
 * @param {L.Marker} clickedMarker - Der angeklickte Marker.
 * ❌ L.Map map Parameter ENTFERNT
 * @param {Object} mapState - Der globale Karten-Zustand.
 */
export function updateMapOnMarkerClick(clickedMarker, mapState) {
    
    // 🔥 Map Instanz über Getter abrufen
    const map = getMap();
    
    mylog("DEBUG: --- updateMapOnMarkerClick START ---");

    // 1. Markierung eines zuvor aktiven Elements entfernen (Marker oder Cluster)
    /*
    if (mapState.activeMarkerOrCluster && mapState.activeMarkerOrCluster !== clickedMarker) {
        
        const previousActive = mapState.activeMarkerOrCluster;
        const wasCluster = !previousActive.options || !previousActive.options.data;

        if (wasCluster) {
            // Logik für Cluster-Markierung bleibt HIER
            mylog('DEBUG: Das zuvor aktive Element war ein Cluster. Markierung wird entfernt.');
            const clusterElement = previousActive._icon;
            if (clusterElement) {
                restoreClusterOriginalStyles(clusterElement, previousActive);
            }
        } else {
            mylog('DEBUG: Das zuvor aktive Element war ein Marker. Highlight wird entfernt (false).');
            UpdateMarkerIcon(previousActive, false); 
        }
    }*/
   // 1. ZENTRALE BEREINIGUNG (Nutzt jetzt die Cluster-Manager Logik)
    const priorContext = determinePriorContext(clickedMarker, mapState);
    const activeElement = mapState.activeMarkerOrCluster;

    // Wenn ein anderes Element aktiv ist, entfernen wir dessen Highlight konsequent
    if (activeElement && activeElement !== clickedMarker) {
        mylog(`DEBUG: Entferne Highlight von Kontext: ${priorContext}`);
        
        // Nutzt die zentrale Funktion, die intern UpdateMarkerIcon(..., false) 
        // oder restoreClusterOriginalStyles aufruft
        demarcateElement(activeElement, mapState);
    }

    // === Logik zur Behandlung des neuen Zustands ===
    // 2. Neuen Marker als aktiv setzen und visuell hervorheben (highlight)
    if (clickedMarker !== mapState.activeMarkerOrCluster) {
        mapState.activeMarkerOrCluster = clickedMarker;
        mapState.activeMarkerOrClusterGID = clickedMarker.options.data.gid;

        mylog('DEBUG: Neuen Marker als aktiv gesetzt. Highlight wird angewendet (true).');
        UpdateMarkerIcon(clickedMarker, true);
    } 

    // 3. "Unspiderfy" Logik für Cluster (bleibt unverändert)
    if (mapState.currentlySpiderfiedCluster) {
        const isChildOfCurrentSpiderfy = mapState.currentlySpiderfiedCluster
            .getAllChildMarkers()
            .some(marker => marker.options.data.gid === clickedMarker.options.data.gid);

        if (!isChildOfCurrentSpiderfy) {
            mylog("DEBUG Markerclick: Unspiderfying zuvor gespiderfiedes Cluster (Klick außerhalb).");
            mapState.currentlySpiderfiedCluster.unspiderfy();
            mapState.currentlySpiderfiedCluster = null;
        } else {
            mylog("DEBUG Markerclick: Geklickter Marker gehört zum gespiderfied Cluster, kein Unspiderfy.");
        }
    }

    // 4. Kartenausschnitt anpassen (map wird lokal genutzt)
    const clusterLatLng = clickedMarker.getLatLng();
    if (shouldPanToElement( clusterLatLng)) {
        map.panTo(clusterLatLng);
        mylog('DEBUG: Karte auf POI zentriert.');
    } else {
        mylog('DEBUG: Karte NICHT zentriert, POI bereits gut sichtbar.');
    }
    
    // ⬅️ NEUE LOGIK: Nach der visuellen Hervorhebung die Koordinate prüfen
    const poiData = clickedMarker.options.data;
    handlePoiMarkerClick(poiData); // ❌ map Parameter entfernt
    
// === NEUE LOGIK FÜR BOTTOM SHEET NAVIGATION PFEILE ===
    // ...

    mylog("DEBUG: --- updateMapOnMarkerClick END ---");
}


export function handleMarkerSelectionMap(marker, allParams) {
    const { mapState } = allParams;
    
    // NEU: Map direkt über den Service beziehen
    const map = getMap();

    if (!map) {
        console.error("handleMarkerSelectionMap: Map-Instanz konnte nicht über getMap() bezogen werden.");
        return;
    }

    // Icon-Update (Gold setzen, alten Marker normalisieren)
    updateMapOnMarkerClick(marker, mapState);

    // Zentrierung mit Versatz (Offset)
    const latLng = marker.getLatLng();
    
    // Die Berechnung nutzt nun sicher das Map-Objekt vom Service
    const point = map.latLngToContainerPoint(latLng);
    
    // Verschiebt den Fokuspunkt nach unten (damit der Marker im sichtbaren Bereich über dem BS bleibt)
    const newPoint = L.point(point.x, point.y + 150); 
    const newLatLng = map.containerPointToLatLng(newPoint);
        if (shouldPanToElement(latLng))
    map.panTo(newLatLng, { animate: true });
}