// gui-address-co.js

import { ApplicationCoordinator } from './app-gen-co.js';
import { findMarkerByGid, getNearbyGids } from './map-gen-mgr.js';
import { mylog } from './utilities.js';
import { validateAddress } from './backend-geo.js'; 
import { getMap } from './map-service.js';


// --- 1. INTERNE HILFSFUNKTIONEN ---

/**
 * Validiert die Adress-Präzision via Backend-Zentralfunktion.
 * @param {Object} addressResult - Das rohe Ergebnis aus der Suche.
 * @returns {Promise<{data: Object, isValid: boolean}>}
 */
async function validateAddressPrecision(addressResult) {
    // Prüfen, ob die Quelle bereits als sicher gilt (z.B. HERE-API oder interner POI)
    const isPreValidated = addressResult.source === 'HERE' || addressResult.source === 'POI';
    
    // Wenn vorvalidiert oder keine Hausnummer vorhanden (zu ungenau für neue POIs)
    if (isPreValidated || !addressResult.houseNr) {
        return { data: addressResult, isValid: isPreValidated };
    }

    // Aufruf der extrahierten Backend-Funktion (fetch-Logik ist dort gekapselt)
    const vData = await validateAddress(addressResult.displayName);

    if (vData) {
        // Mapping: Stadtteil (District) sicher im Objekt verankern
        const district = vData.district || vData.localdistrict || vData.suburb || "";
        addressResult.localDistrict = district; 

        // Daten zusammenführen (Backend-Daten überschreiben Such-Metadaten für höhere Präzision)
        const finalData = { ...addressResult, ...vData };
        
        // Validitäts-Check: Reicht die Genauigkeit für einen Stolperstein?
        const isValid = (finalData.precision === 'precise' || finalData.precision === 'interpolated');
        return { data: finalData, isValid };
    }
    
    // Fallback, wenn Backend keine Daten liefert
    return { data: addressResult, isValid: false };
}

// --- 2. KARTEN-STEUERUNG & EVENT-DISPATCHING ---

/**
 * Zentrale Entscheidungslogik für gefundene Orte.
 * Verarbeitet eine erfolgreich selektierte Adresse aus der Suche.
 * Trennung der Events für Einzel-POI, Cluster oder Neuanlage.
 * @param {Object} bottomSheetUI - UI-Instanz für das Bottom-Sheet.
 * @param {Object} addressData - Das validierte Adress-Objekt.
 * @param {boolean} isValid - Ob die Adresse für eine Neuanlage präzise genug ist.
 */
/**
 * Zentrale Entscheidungslogik für gefundene Orte auf der GUI.
 * Erweitert um die strenge postalische Dublettenprüfung.
 */
export async function handleFoundAddressOnGui(addressData, isValid) {
    if (!isValid) {
        getMap().setView([addressData.lat, addressData.lng], 15);
        return;
    }

    // --- A. PRIORITÄT: Direkter Treffer (z.B. Personensuche via POI-Store) ---
    if (addressData.gid) {
        ApplicationCoordinator.appEvents.dispatchEvent(new CustomEvent('poi:requestSelection', {
            detail: { gid: addressData.gid, origin: 'search' }
        }));
        return;
    }

    // --- B. PRIORITÄT: Dubletten-Prüfung (Geografisch + Postalisch) ---
    
    // 1. Geografische Prüfung (Radius-Suche)
    let foundGids = getNearbyGids({ lat: addressData.lat, lng: addressData.lng });

    // Wenn GIDs gefunden wurden (egal ob via Radius oder Adresse)
    if (foundGids.length > 0) {
        const firstGid = foundGids[0];
        const marker = findMarkerByGid(firstGid);
        const parentCluster = marker ? marker.__parent : null;

        // Fall 1: Mehrere Steine an der Adresse -> Cluster-Event
        if (foundGids.length > 1) {
            ApplicationCoordinator.appEvents.dispatchEvent(new CustomEvent('cluster:requestSelection', {
                detail: { 
                    gid: firstGid, 
                    firstGid: firstGid, 
                    cluster: parentCluster, 
                    origin: 'search' 
                }
            }));
            return;
        } 
        
        // Fall 2: Exakt ein Stein an der Adresse -> Einzel-POI Event
        ApplicationCoordinator.appEvents.dispatchEvent(new CustomEvent('poi:requestSelection', {
            detail: { 
                gid: firstGid, 
                parentCluster: parentCluster, 
                origin: 'search' 
            }
        }));
        return;
    }

    // --- C. PRIORITÄT: Definition (Neuanlage eines neuen POI) ---
    // Dieser Block wird nur erreicht, wenn weder geografisch noch postalisch ein Stein existiert.
    
    // Optional: Hier den blauen Marker für die Neuanlage setzen
    // handlePoilessSelectionMap(addressData); 

    ApplicationCoordinator.appEvents.dispatchEvent(new CustomEvent('poiless:requestSelection', {
        detail: { 
            addressData: addressData,
            origin: 'search' 
        }
    }));
}
// --- 3. COORDINATOR SETUP ---

/**
 * Initialisiert das Zusammenspiel zwischen Adress-Suche und GUI-Aktionen.
 */

export function setupGuiAddrsCoordinator(addrsCoordinator, dependencies) {
    addrsCoordinator.onGuiLocationRequested(async (locationData) => {
        
        // 1. Weiche: POIs vs. rohe Adressen
        if (locationData.source === 'POI') {
            mylog("DEBUG: POI erkannt. Überspringe Adressvalidierung.", locationData);
            
            // Ein POI ist per Definition "valide" (Punkt existiert in DB).
            // Wir schicken ihn direkt an die Karte.
            await handleFoundAddressOnGui(locationData, true);
        } 
        else {
            mylog("DEBUG: Adresse (OSM/HERE) erkannt. Starte Validierung.", locationData);
            
            // Rohe Adressen müssen geprüft werden (Hausnummer vorhanden?).
            // Hier nutzen wir nur die strukturierten Daten (street, houseNr).
            const { data, isValid } = await validateAddressPrecision(locationData);
            
            await handleFoundAddressOnGui(data, isValid);
        }
    });
}