// addrs-co.js
// Dieses Modul koordiniert die Interaktion zwischen der Adress-UI (addrs-ui.js) 
// und der Karte (gui-address-co.js), indem es Suchanfragen durchführt und Events weiterleitet.

import { AddressSheetUI } from './addrs-ui.js';
import { showToast } from './sc-utilities.js';
import { BackendService } from './backend-poi.js';
import { fetchAdressesFromHere, fetchAdressesFromNominatim } from './backend-geo.js';

export class AddressSheetCoordinator {

    constructor(addressSheetUI, backendService) {
        this.addressSheetUI = addressSheetUI;
        this.backendService = backendService;
        this.searchTimeout = null;

        // Callbacks für die Events
        this.guiLocationRequestedCallbacks = [];
        this.currentLocationSelectedCallbacks = [];
        this.nextDirtyStoneSelectedCallbacks = []; // 🛑 NEU
        this.stateChangeCallbacks = [];
        this.sheetTriggeredCallbacks = [];

        this._addEventListeners();
        console.log("AddressSheetCoordinator initialisiert (volle Entkopplung).");
    }

    /**
     * Registriert alle notwendigen Event-Listener.
     * @private
     */
    _addEventListeners() {
        this.addressSheetUI.onSearchInput(this.handleSearchInput.bind(this));
        
        this.addressSheetUI.searchResultSelected(this._handleSearchResultSelected.bind(this));
        
        this.addressSheetUI.onCurrentLocationSelected(this._handleCurrentLocationSelectedFromUI.bind(this));

        // 🛑 NEU: Listener für den Pflegebedarf-Button in der UI
        this.addressSheetUI.onNextDirtyStoneSelected(this._handleNextDirtyStoneSelectedFromUI.bind(this));
    }

    /**
     * Handler für das UI-Event "addressSelected".
     */
    _handleSearchResultSelected(addressData) {
        console.log("DEBUG (Coordinator): Adresse vom UI ausgewählt, gebe 'GuiLocationRequested' Event weiter.", addressData);
        this.addressSheetUI.closeResults();
        this._emit('GuiLocationRequested', addressData);
    }

    /**
     * Handler für das UI-Event "currentLocationSelected".
     */
    _handleCurrentLocationSelectedFromUI() {
        console.log('DEBUG (Coordinator): "Aktueller Standort" vom UI ausgewählt, gebe "currentLocationSelected" Event weiter.');
        this.addressSheetUI.closeResults();
        this._emit('currentLocationSelected');
    }

    /**
     * Handler für das UI-Event "nextDirtyStoneSelected". 🛑 NEU
     */
    _handleNextDirtyStoneSelectedFromUI() {
        console.log('DEBUG (Coordinator): "Pflegebedarf" vom UI ausgewählt, gebe "nextDirtyStoneSelected" Event weiter.');
        this.addressSheetUI.closeResults();
        this._emit('nextDirtyStoneSelected');
    }

    /**
     * Löst manuell ein Coordinator-Event "sheetOpened" aus.
     */
    triggerSheetOpened() {
        console.log("DEBUG (Coordinator): 'Sheet Opened' von App-Shell empfangen, gebe Event weiter.");
        this._emit('sheetOpened');
    }

    /**
     * Registrierungsmethoden für externe Module (z.B. App-Logik)
     */
    onGuiLocationRequested(callback) {
        this.guiLocationRequestedCallbacks.push(callback);
    }

    onCurrentLocationSelected(callback) {
        this.currentLocationSelectedCallbacks.push(callback);
    }

    onNextDirtyStoneSelected(callback) { // 🛑 NEU
        this.nextDirtyStoneSelectedCallbacks.push(callback);
    }

    onSheetOpened(callback) {
        this.sheetTriggeredCallbacks.push(callback);
    }

    /**
     * Hilfsfunktion zum Auslösen von benutzerdefinierten Events.
     */
    _emit(eventName, data) {
        const callbacks = {
            'GuiLocationRequested': this.guiLocationRequestedCallbacks,
            'currentLocationSelected': this.currentLocationSelectedCallbacks,
            'sheetOpened': this.sheetTriggeredCallbacks,
            'nextDirtyStoneSelected': this.nextDirtyStoneSelectedCallbacks, // 🛑 NEU
        };

        if (callbacks[eventName]) {
            callbacks[eventName].forEach(cb => {
                try {
                    cb(data);
                } catch (e) {
                    console.error(`Fehler beim Ausführen des Event-Listeners für '${eventName}':`, e);
                }
            });
        }
    }

    // ... (Rest der Hilfsfunktionen wie _extractNameComponents, _extractAddressComponents und handleSearchInput bleiben unverändert)
    
    // ====================================================================
    // HILFSFUNKTIONEN FÜR POI-NAMENSSUCHE (Name/Jahr)
    // ====================================================================
    _extractNameComponents(query) {
        /* ... wie im Original ... */
        let yearOfBirth = null;
        const rawParts = query.split(/\s+/).map(p => p.trim()).filter(Boolean);
        const nameParts = [];
        const nameRegex = /^[a-zA-ZäöüÄÖÜß\-]+$/;
        for (const token of rawParts) {
            if (/^\d{4}$/.test(token)) {
                const yr = parseInt(token, 10);
                if (yr >= 1840 && yr <= 1945) {
                    yearOfBirth = yearOfBirth ?? yr;
                    continue;
                }
                return { invalid: true, nameParts: [], yearOfBirth: null };
            }
            if (nameRegex.test(token)) {
                nameParts.push(token);
                continue;
            }
            return { invalid: true, nameParts: [], yearOfBirth: null };
        }
        return { invalid: false, nameParts, yearOfBirth };
    }

    _extractAddressComponents(query) {
        /* ... wie im Original ... */
        const components = { street: null, houseNr: null };
        const streetAndNumberPart = query.split(',')[0].trim(); 
        const firstDigitMatch = streetAndNumberPart.match(/(\s*\d+)/); 
        if (firstDigitMatch && firstDigitMatch.index > 0) {
            let streetRaw = streetAndNumberPart.substring(0, firstDigitMatch.index);
            let houseNrRaw = streetAndNumberPart.substring(firstDigitMatch.index);
            components.street = streetRaw.trim();
            components.houseNr = houseNrRaw.trim(); 
        } else {
            components.street = streetAndNumberPart.trim();
            components.houseNr = null;
        }
        return components;
    }

    async handleSearchInput(query) {
        /* ... Logik für Suche wie im Original ... */
        if (query.length < 3) {
            clearTimeout(this.searchTimeout);
            this.addressSheetUI.setInitialResultsContent();
            return;
        }
        clearTimeout(this.searchTimeout);
        this.searchTimeout = setTimeout(async () => {
            const html = '<p style="--status-color: #888; --status-padding: 20px; text-align: center; color: var(--status-color); padding: var(--status-padding);"><i class="fas fa-spinner fa-spin"></i> Suchen...</p>';
            this.addressSheetUI.renderResults([{ display_name: html, source: 'status', lat: 0, lng: 0 }]);
            
            let finalResults = [];
            const hausnummerRegex = /[.\s]\d{1,5}[a-zA-Z]?/;
            const isHouseNrQuery = hausnummerRegex.test(query);

            const nameComponents = this._extractNameComponents(query);
            const { nameParts, yearOfBirth, invalid } = nameComponents;
            if (!invalid) {
                const hasYear = yearOfBirth !== null;
                const caseA = (nameParts.length > 0 && hasYear); 
                const caseB = (nameParts.length > 1 && !hasYear);
                if (caseA || caseB) {
                    try {
                        const poiNameResults = await this.backendService.fetchPoisByName(nameParts, yearOfBirth);
                        finalResults.push(...poiNameResults);
                    } catch (e) { console.error(e); }
                }
            }

            const addressComponents = this._extractAddressComponents(query);
            if (isHouseNrQuery && addressComponents.street && addressComponents.houseNr) {
                try {
                    const poiAddressResults = await this.backendService.fetchPoisByAddress(addressComponents.street, addressComponents.houseNr);
                    if (poiAddressResults) finalResults.push(...poiAddressResults);
                } catch (e) { console.error(e); }
            }

            try {
                const nominatimResults = await fetchAdressesFromNominatim(query);
                finalResults.push(...nominatimResults);
                
                const nominatimFoundHouseNr = nominatimResults.some(item => item.houseNr && item.source === 'OSM');
                if (isHouseNrQuery && !nominatimFoundHouseNr) {
                    const hereResults = await fetchAdressesFromHere(query);
                    if (hereResults) finalResults.push(...hereResults);
                }
            } catch (e) { console.error(e); }

            if (finalResults.length > 0) {
                this.addressSheetUI.renderResults(finalResults);
            } else {
                this.addressSheetUI.renderResults([]);
                showToast(`Keine Treffer für "${query}" gefunden.`, 'Information');
            }
        }, 500);
    }
}