// gui-address-co.js

import { showToast, wait, mylog } from './sc-utilities.js';
import { handleBsUpdate } from './bs-gen-co.js';
import { getMap, getMarkers, mapState } from './map-markers-co.js';
import { handleClusterSelection } from './map-cluster-mgr.js';
import { handleMarkerSelection } from './map-gen-mgr.js';
import { demarcate_route } from './map-poi-navigation.js';

let currentAddressMarker = null;

// --- 1. HILFSFUNKTIONEN ---

function findMarkerByGid(gid, markersLayer) {
    let found = null;
    markersLayer.eachLayer(layer => {
        if (!found && layer instanceof L.Marker && layer.options?.data?.gid?.toString() === gid.toString()) {
            found = layer;
        }
    });
    return found;
}

/**
 * Validiert die Adress-Präzision via Backend.
 */
async function validateAddressPrecision(addressResult) {
    const isPreValidated = addressResult.source === 'HERE' || addressResult.source === 'POI';
    if (isPreValidated || !addressResult.houseNr) {
        return { data: addressResult, isValid: isPreValidated };
    }
    try {
        const response = await fetch(`./validate_address.php?q=${encodeURIComponent(addressResult.displayName + ', Berlin')}`);
        const validationData = await response.json();
        if (validationData?.[0]) {
            const finalData = { ...addressResult, ...validationData[0] };
            const isValid = (finalData.precision === 'precise' || finalData.precision === 'interpolated');
            return { data: finalData, isValid };
        }
    } catch (e) { mylog("Validierungsfehler", e); }
    return { data: addressResult, isValid: false };
}

// --- 2. KARTEN-STEUERUNG ---

export function removeAddressMarker() {
    const map = getMap();
    if (currentAddressMarker) {
        map.removeLayer(currentAddressMarker);
        currentAddressMarker = null;
    }
}

/**
 * Adress-Modus: Wenn kein POI/Stein gefunden wurde, wird ein blauer Pin gesetzt.
 */
function handleNewAddressMode(addressData, bottomSheetUI, backendService) {
    const map = getMap();
    const pos = [addressData.lat, addressData.lng];
    
    map.setView(pos, 19);
    currentAddressMarker = L.marker(pos).addTo(map);

    // Virtuellen Marker für das Bottom-Sheet erstellen
    const tempMarker = L.marker(pos);
    tempMarker.options = { isNewAddressMode: true, addressData };
    
    if (mapState) {
        mapState.activeMarkerOrCluster = tempMarker;
    }
    
    handleBsUpdate(tempMarker, bottomSheetUI, mapState, backendService);
}

/**
 * Haupt-Logik für die Anzeige der Adresse/des POI auf der Karte.
 */
export async function handleFoundAddressOnGui(bottomSheetUI, addressData, isValid, backendService) {
    const markers = getMarkers();
    const map = getMap();
    

    if (!isValid) {
        map.setView([addressData.lat, addressData.lng], 15);
        return;
    }

    // 2. Suche nach Steinen im 2m Umkreis
    const nearbyMarkers = [];
    const searchLatLng = L.latLng(addressData.lat, addressData.lng);

    markers.eachLayer(layer => {
        if (layer instanceof L.Marker && layer.options?.data) {
            if (layer.getLatLng().distanceTo(searchLatLng) < 2) {
                nearbyMarkers.push(layer);
            }
        }
    });

    const nearbyMarkerCount = nearbyMarkers.length;

    if (nearbyMarkerCount > 0) {
        const targetMarker = nearbyMarkers[0];
        
        // 3. Robuster Fokus via Leaflet.markercluster
        markers.zoomToShowLayer(targetMarker, async () => {
            const cluster = targetMarker.__parent;

            if (nearbyMarkerCount > 1 && cluster) {
                mylog(`DEBUG: Gruppe mit ${nearbyMarkerCount} POIs erkannt.`);
                await handleClusterSelection(cluster, bottomSheetUI, backendService, mapState);
                
                if (mapState?.setClusterMarkerIndex) {
                    mapState.setClusterMarkerIndex(targetMarker, cluster);
                }
            } else {
                mylog("DEBUG: Einzel-POI erkannt.");
                handleMarkerSelection(targetMarker.options.gid, { mapState, bottomSheetUI, backendService });
            }
        });

    } else {
        // 4. Keine Steine gefunden -> Adress-Pin
        handleNewAddressMode(addressData, bottomSheetUI, backendService);
    }
}

// --- 3. COORDINATOR SETUP ---

export function setupGuiAddrsCoordinator(addrsCoordinator, dependencies) {
    const { bottomSheetUI, backendService } = dependencies;

    addrsCoordinator.onGuiLocationRequested(async (addressResult) => {


        // Falls bereits eine GID vorliegt (Suche nach Name)
        if (addressResult.source === 'POI' && addressResult.gid) {
            const markers = getMarkers();
            const target = findMarkerByGid(addressResult.gid, markers);
            if (target) {
                // Erst zum Marker zoomen, dann Selektion triggern
                markers.zoomToShowLayer(target, () => {
                    handleMarkerSelection(target.options.gid, { mapState, bottomSheetUI, backendService }, null, addressResult);
                });
                return;
            }
        }

        const { data, isValid } = await validateAddressPrecision(addressResult);
        await handleFoundAddressOnGui(bottomSheetUI, data, isValid, backendService);
    });
}