//map-markers-co.js
/**
 * @fileoverview Zentrales Modul für die Verwaltung der Leaflet-Karte (mapInstance)
 * und der MarkerClusterGroup (markersInstance) als Modul-Scope-Singletons.
 * * Dieses Design vermeidet die Klassen-Struktur und nutzt die JavaScript-Modul-Kapselung
 * für eine bessere Testbarkeit und direkteren Zugriff.
 */

// Importe der Hilfsfunktionen
import { calculateClusterColor } from './marker-display-utils.js';
import { mylog } from './sc-utilities.js';
// L ist global oder muss, falls nicht global verfügbar, importiert werden.
// Angenommen, Leaflet (L) ist in Ihrer Umgebung verfügbar. 

// ===============================================
// 1. GLOBALER KARTENZUSTAND (mapState)
// ===============================================

// mapState ist weiterhin exportiert, da es ein *veränderbarer* Zustand ist,
// auf den andere Module direkt zugreifen dürfen (Achtung: dies ist der
// verbleibende "globale" Zustand).
export const mapState = {
    currentlySpiderfiedCluster: null, 
    activeMarkerOrCluster: null, 
    activeMarkerOrClusterGID: null, 
    originalActiveMarkerSize: [24, 24],
    parentClusterOfActiveMarker: null, 
};


// ===============================================
// 2. MODUL-SCOPE SINGLETON-INSTANZEN (Privat)
// ===============================================

/** @type {L.Map} Die einzige Instanz der Leaflet Map. */
let mapInstance = null;
/** @type {L.MarkerClusterGroup} Die einzige Instanz der MarkerClusterGroup. */
let markersInstance = null;


// ===============================================
// 3. INTERNE INITIALISIERUNGSFUNKTION (Privat)
// ===============================================

/**
 * Führt die eigentliche Initialisierung der Leaflet-Objekte durch.
 * Diese Funktion sollte nur einmal aufgerufen werden.
 * @private
 */
function initializeMap() {
    if (mapInstance) {
        mylog("Achtung: Karte wurde bereits initialisiert. Initialisierung abgebrochen.");
        return; 
    }

    // --- 1. Map Instanz erzeugen ---
    // Hier verwenden wir einen festen Container-Namen, da dieser Service die Map verwaltet.
    const map = L.map("map").setView([52.469, 13.4249], 10);

    L.tileLayer('https://{s}.basemaps.cartocdn.com/rastertiles/voyager/{z}/{x}/{y}{r}.png', {
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors &copy; <a href="https://carto.com/attributions">CARTO</a>',
        subdomains: 'abcd',
        maxZoom: 20
    }).addTo(map);

    // --- 2. MarkerClusterGroup Instanz erzeugen ---
    let markers = L.markerClusterGroup({
        maxZoom: 19,
        zoomToBoundsOnClick: false,
        spiderfyOnClick: false,
        spiderfyOnMaxZoom: false,
        maxClusterRadius: function (zoom) {
            return zoom < 19 ? 60 : 10;
        },
        spiderfyCompareFn: (a, b) => { 
            const gidA = a.options.data.gid;
            const gidB = b.options.data.gid;
            return gidA < gidB ? -1 : (gidA > gidB ? 1 : 0);
        },
        spiderfyDistanceMultiplier: 3,
        iconCreateFunction: function (cluster) {
            const markersCount = cluster.getChildCount();
            const dominantColor = calculateClusterColor(cluster); 
            const clusterHtml = `
                    <div class="marker-cluster-style ${dominantColor}-cluster">
                        ${markersCount}
                    </div>
                    `;
            return new L.DivIcon({
                html: clusterHtml,
                className: "leaflet-marker-cluster",
                iconSize: new L.Point(40, 39),
            });
        },
    });

    map.addLayer(markers);
    mylog("MapService: Modul-Scope-Karte und MarkerClusterGroup initialisiert.");
    
    // Speichern der Instanzen im privaten Modul-Scope
    mapInstance = map;
    markersInstance = markers;
    mylog(markersInstance);
     mylog("test");
}


// ===============================================
// 4. ÖFFENTLICHE SCHNITTSTELLE (Exports)
// ===============================================

/**
 * Startet den Karten-Service und initialisiert die Leaflet-Objekte.
 * Muss einmalig vor der Nutzung von getMap() oder getMarkers() aufgerufen werden.
 */
export function initMapMarkerService() {
    initializeMap();
}

/**
 * Gibt die Leaflet Map Instanz zurück.
 * Wirft einen Fehler, wenn der Service noch nicht initialisiert wurde.
 * @returns {L.Map}
 */
export function getMap() {
    if (!mapInstance) {
        throw new Error("MapService wurde noch nicht initialisiert. Bitte initService() aufrufen.");
    }
    return mapInstance;
}

/**
 * Gibt die Leaflet MarkerClusterGroup Instanz zurück.
 * Wirft einen Fehler, wenn der Service noch nicht initialisiert wurde.
 * @returns {L.MarkerClusterGroup}
 */
export function getMarkers() {
    if (!markersInstance) {
        throw new Error("MapService wurde noch nicht initialisiert. Bitte initService() aufrufen.");
    }
    return markersInstance;
}

// Exportiert: mapState, initService, getMap, getMarkers.