/**
 * @fileoverview ApplicationCoordinator.js
 * Orchestriert die Initialisierung und delegiert Fachlogik an spezialisierte Manager.
 */

import { mylog, showToast } from './sc-utilities.js';
import { 
    fetchPOIs, 
    setupMapEventListeners, 
    centerMapOnBottomSheetContent, 
    setupAddrsCoordinatorListeners,
    addNewMarkerFromStore,
    handleMarkerSelection
} from "./map-gen-mgr.js";
import { setupClusterEventListeners } from "./map-cluster-mgr.js";
import { InsertPoiUI } from './insert-poi-ui.js';
import { UpdatePoiUI } from './update-poi-details-ui.js';
import { LocationTrackingCoordinator } from './loc-tracking-co.js';
import { MapMarkerClusterUI } from './map-markercluster-ui.js';
import { MapLocationUI } from './map-loc-ui.js'; 
import { BsUI } from './bs-gen-ui.js';
import { BackendService } from './backend-poi.js';
import { AddressSheetUI } from './addrs-ui.js';
import { AddressSheetCoordinator } from './addrs-co.js';
import { SettingsUI } from './sc-settings-ui.js';
import { SettingsCoordinator } from './sc-settings-co.js';
import { updateSearchFieldWithAddress } from './app-shell-co.js';
import { initAddStoneLogic, handleSaveStone } from './insert-poi-co.js';
import { setupGuiAddrsCoordinator } from './gui-address-co.js';
import { AppStartPageUI } from './app-startpage-ui.js'; 
import { AppStartPageCoordinator } from './app-startpage-co.js'; 
import { getAdminMode } from './admin-mode-co.js'; 

import { getMarkers, initMapMarkerService, mapState } from './map-markers-co.js'; 

export class ApplicationCoordinator {

    #AppShellUIClass;
    #AppShellCoordinatorClass;
    #appShellUI;
    #appShellCoordinator;
    #locationTracker; 
    #bottomSheetUI;
    #backendService;
    #insertPoiUI;
    #updatePoiUI;
    #addressSheetUI;
    #addrsCoordinator;
    #settingsCoordinator;
    #appStartPageCoordinator; 
    #mapLocationUI;
    #poisLoadPromise = null;
    #locationTrackingPromise = null;
    #preloadTimer = null; 

    constructor(AppShellUIClass, AppShellCoordinatorClass) {
        this.#AppShellUIClass = AppShellUIClass;
        this.#AppShellCoordinatorClass = AppShellCoordinatorClass;
    }

    async start() {
        mylog("ApplicationCoordinator: Bootstrapping gestartet.");
        
        const appShellUI = new this.#AppShellUIClass();
        appShellUI.injectIntoDOM(document.body, this.#handleAdminModeToggle.bind(this)); 
        this.#appShellUI = appShellUI;
        this.#appShellCoordinator = new this.#AppShellCoordinatorClass(appShellUI);

        initMapMarkerService();
        this.initializeApplication(); 
        
        this.#appShellCoordinator.showLoadingSpinner();
        this.#appShellCoordinator.updateLoadingText("Bereite Karte vor..."); 
        this.#appShellCoordinator.showLocationPermissionOverlay();

        this.preloadBackground(); 
    }
    
    initializeApplication() {
        mylog("ApplicationCoordinator: Initialisierung der Module.");

        this.#updatePoiUI = UpdatePoiUI.getInstance();
        this.#backendService = new BackendService();
        this.#bottomSheetUI = new BsUI('wrapper', 'bottom-sheet', 'bottom-sheet-content-area', 'bottom-sheet-actions-area');
        
        // Callback für Refresh-Anfragen (Delegation an Map-Manager)
        const onRefreshRequest = (focusData) => this.#handleRefreshRequest(focusData);

        this.#insertPoiUI = new InsertPoiUI('add-button', 'add-icon', {
            onSave: (stoneData) => handleSaveStone(stoneData, this.#bottomSheetUI, onRefreshRequest, this.#backendService)
        });

        this.#locationTracker = LocationTrackingCoordinator.getInstance();
        this.#mapLocationUI = new MapLocationUI(); 
        this.#addressSheetUI = new AddressSheetUI();
        this.#addrsCoordinator = new AddressSheetCoordinator(this.#addressSheetUI, this.#backendService);
        
        const mapMarkerClusterUI = new MapMarkerClusterUI();
        mapMarkerClusterUI.injectIntoDOM();
        
        const appStartPageUI = new AppStartPageUI();
        appStartPageUI.injectIntoDOM(); 
        this.#appStartPageCoordinator = new AppStartPageCoordinator(appStartPageUI, this.#handleStartPageDone.bind(this));
        this.#appStartPageCoordinator.start();
        
        const settingsUIInstance = new SettingsUI();
        this.#settingsCoordinator = new SettingsCoordinator(settingsUIInstance); 

        this.#setupAllListeners(onRefreshRequest);
        
        this.#preloadTimer = this.#startPreloadTimer();
        this.#locationTrackingPromise = this.#locationTracker.startTrackingAndHandlePermission().catch(() => {});
        
        this.#poisLoadPromise = fetchPOIs(
            this.#bottomSheetUI, this.#backendService, 
            this.#insertPoiUI, this.#updatePoiUI, this.#appShellCoordinator.updateLoadingText.bind(this.#appShellCoordinator) 
        ).then(() => {
            mylog("ApplicationCoordinator: POI-Daten geladen.");
            if (this.#preloadTimer) { clearInterval(this.#preloadTimer); this.#preloadTimer = null; }
            this.#appShellCoordinator.hideLoadingSpinner();
        }).catch(err => console.error("POI Fehler:", err));
    }

    #setupAllListeners(onRefreshRequest) {
        setupMapEventListeners(this.#bottomSheetUI, this.#backendService, this.#insertPoiUI, this.#updatePoiUI); 
        setupClusterEventListeners(this.#bottomSheetUI, this.#backendService); 
        
        this.#bottomSheetUI.onClose(() => { updateSearchFieldWithAddress(null); });
   //     this.#bottomSheetUI.onHeaderClick((zoom) => centerMapOnBottomSheetContent(this.#bottomSheetUI, zoom));

    
this.#bottomSheetUI.onHeaderClick(() => {
    const currentObject = this.#bottomSheetUI.getDisplayedObject();
    
    // Prüfen, ob wir eine GID haben (Stolperstein)
    if (currentObject && currentObject.options && currentObject.options.data) {
        const gid = currentObject.options.gid;
        
        // Aufruf deiner stabilen Selektions-Funktion
        handleMarkerSelection(gid, {
            bottomSheetUI: this.#bottomSheetUI,
            backendService: this.#backendService, // Instanz übergeben
            mapState: mapState              // Instanz übergeben
        });
    } else {
        // Fallback für Cluster ohne spezifische Marker-Selektion
        centerMapOnBottomSheetContent(this.#bottomSheetUI);
    }
}); 
        this.#bottomSheetUI.onResize(() => centerMapOnBottomSheetContent(this.#bottomSheetUI));

        // Übergabe des Refresh-Callbacks an Sub-Koordinatoren
        initAddStoneLogic(this.#bottomSheetUI, this.#insertPoiUI, onRefreshRequest, this.#backendService);
        
        setupGuiAddrsCoordinator(this.#addrsCoordinator, { 
            bottomSheetUI: this.#bottomSheetUI, 
            backendService: this.#backendService 
        });
        setupAddrsCoordinatorListeners(this.#addrsCoordinator, this.#bottomSheetUI, this.#mapLocationUI); 

        this.#addrsCoordinator.onNextDirtyStoneSelected(() => {
            this.#locationTracker.navigateToNextCareNeed({
                bottomSheetUI: this.#bottomSheetUI,
                backendService: this.#backendService,
                mapState: mapState
            });
        });

        this.#appShellCoordinator.onSearchTriggered(() => {
            this.#addrsCoordinator.triggerSheetOpened(); 
            this.#addressSheetUI.openResults();
        });
        this.#appShellCoordinator.onSettingsClicked(() => {
            this.#settingsCoordinator.toggleSettings();
        });
    }

// Innerhalb der Klasse ApplicationCoordinator

/**
 * Zentraler Einstiegspunkt für Refresh-Anfragen.
 * Basis: Daten sind bereits im Store (durch insert-poi-co).
 */
#handleRefreshRequest(focusData) {
    if (focusData && focusData.newGid) {
        // Parameter-Paket für die Klick-Events schnüren
        const uiParams = {
            bottomSheetUI: this.#bottomSheetUI,
            backendService: this.#backendService,
            mapState: mapState,
            insertPoiUI: this.#insertPoiUI,
            updatePoiUI: this.#updatePoiUI
        };

        // Effizientes Hinzufügen statt fetchPOIs()
        addNewMarkerFromStore(focusData.newGid, uiParams);
        
        mylog(`ApplicationCoordinator: Marker für GID ${focusData.newGid} inkrementell hinzugefügt.`);
    }
}

    async #handleStartPageDone() {
        this.#appShellCoordinator.hideLocationPermissionOverlay();
        const bgContainer = document.getElementById('background-image-container');
        if (bgContainer) bgContainer.classList.add('fade-out'); 

        this.#appShellCoordinator.showLoadingSpinner();
        await Promise.allSettled([this.#locationTrackingPromise, this.#poisLoadPromise]);
        
        this.#appShellCoordinator.hideLoadingSpinner();
        this.#appShellCoordinator.showMapAndControls();

        if (this.#locationTracker.isTrackingActive() && this.#insertPoiUI.buttonElement) {
            this.#insertPoiUI.buttonElement.classList.remove("hidden");
        }
        this.#settingsCoordinator.initializeSettingsState();
    }

    #startPreloadTimer() {
        let seconds = 0;
        return setInterval(() => {
            seconds++;
            this.#appShellCoordinator.updateLoadingText(`Ladezeit: ${seconds} Sekunde(n)...`); 
        }, 1000);
    }

    async preloadBackground() {
        const BG_IMAGE_URL = 'StolperCleanBackground.jpg?v=' + Date.now();
        const bgContainer = document.getElementById('background-image-container'); 
        try {
            const response = await fetch(BG_IMAGE_URL);
            const blob = await response.blob();
            const imgElement = new Image();
            imgElement.src = URL.createObjectURL(blob);
            imgElement.style.cssText = "width:100%; height:100%; object-fit:cover;";
            if(bgContainer) bgContainer.appendChild(imgElement);
        } catch (e) { if(bgContainer) bgContainer.style.opacity = 1; }
    }

    #handleAdminModeToggle() {
        const newState = !getAdminMode.getStatus();
        showToast(newState ? "Zusatzfunktionen aktiviert" : "Standard-Modus aktiv", "");
        getAdminMode.dispatchStatusChange(newState);
    }
}