// bs-cluster-co.js
import { handleCleaningsStatusAllCluster, willClusterSpiderfy } from './map-cluster-mgr.js';
import { getColorCodeAndText } from './marker-display-utils.js';
import { showToast, mylog } from './sc-utilities.js';
import { updateSearchFieldWithAddress } from './app-shell-co.js';
import { getLocationToggleState } from './sc-settings-location.js';
import { triggerMarkerClick } from './map-gen-mgr.js';
import { LocationTrackingCoordinator } from './loc-tracking-co.js';; // ⬅️ Singleton importiert

let currentMarkerIndex = -1;
let startX = 0;
let startY = 0;
let isSwiping = false;
let swipeStartTime = 0;
let clusterLinkHandlerReference = null;
let touchStartHandler = null;
let mouseDownHandler = null;
let touchEndHandler = null;
let mouseUpHandler = null;
let touchMoveHandler = null;
let mouseMoveHandler = null;

// --- Hilfsfunktionen ---

function getClusterContentHtml(childMarkers) {
    let clusterContent = `<div class="cluster-detail-list"style="font-size:1.2rem;">`;

    childMarkers.forEach(marker => {
        const data = marker.options.data;
        const color = getColorCodeAndText(data.last_cleaned).colorCode;
        const biographyUrl = data.url_kodb;
        const streetModified = data.street.slice(0, -1) + '*';
        const wikipediaSearchTerms = [
            'Stolperstein',
            data.first_name,
            data.last_name,
            data.year_of_birth,
            streetModified
        ];
        const wikipediaUrl = `https://de.wikipedia.org/wiki/Spezial:Suche?search=${wikipediaSearchTerms.map(term => encodeURIComponent(term)).join('+')}`;

        // 🟡 NEU: Prüfen, ob stone_position gesetzt ist
        const hasStonePosition = data.stone_position !== null && data.stone_position !== undefined && data.stone_position !== '';

        // 🟡 Name mit optionalem Sternchen
        const nameText = `${data.first_name || ''} ${data.last_name || ''}${hasStonePosition ? ' <span style="color:red;">→ Verlegeort</span>' : ''
            }`;
        clusterContent += `
            <div class="cluster-list-item ${color}-marker">
                <a href="#" class="cluster-marker-link" data-marker-id="${data.gid}">
                    ${nameText}
                </a>
            </div>
        `;
    });

    clusterContent += `</div>`;
    return clusterContent;
}


function getClusterUIConfig(cluster, getAdminModeStatus) { // ⬅️ locTrackingCoordinator entfernt
    const childMarkers = cluster.getAllChildMarkers();
    const latlng = cluster.getLatLng();
    const isAdmin = getAdminModeStatus();

    // ➡️ NEU: Abrufen der Singleton-Instanz
    const locTrackingCoordinator = LocationTrackingCoordinator.getInstance();;
    
    const isCloseEnough = (() => {
        if (!locTrackingCoordinator) return false;
        
        const currentUserPosition = locTrackingCoordinator.getUserPosition();
        const cleanButtonDistanceThreshold = 100;
        
        if (currentUserPosition && getLocationToggleState()) {
            const distance = L.latLng(currentUserPosition[0], currentUserPosition[1]).distanceTo(latlng);
            return distance <= cleanButtonDistanceThreshold;
        }
        return false;
    })();

    const showExtendedActions = isCloseEnough || isAdmin;
    const showAddAction = isCloseEnough || isAdmin;
    const showActiveState = showExtendedActions;
    const showFallback = !showExtendedActions;

    const actionsConfig = {
        showCaretaker: false,
        showAddButton: showAddAction,
        showEditButton: false,
        showMainActionDiv: showActiveState || showFallback,
        showFallbackButton: showFallback,
        fallbackButtonClass: "primary disabled",
    };

    // 🟡 NEU: Prüfen, ob mindestens ein Marker eine stone_position hat
    const hasStonePosition = childMarkers.some(marker => {
        const pos = marker.options.data?.stone_position;
        return pos !== null && pos !== undefined && pos !== '';
    });

    // 🟡 Headertext zusammensetzen
    let headerText = `${childMarkers.length} Stolpersteine`;
    if (hasStonePosition) {
        headerText += ',<span style="color: red;"> Verlegeort s.u.</span>';
    }

    return {
        headerText,
        contentHtml: getClusterContentHtml(childMarkers),
        coords: { lat: latlng.lat, lng: latlng.lng },
        actionsConfig: actionsConfig,
        showExtendedActions: showExtendedActions
    };
}


// --- Handler-Funktionen ---
function handleClusterCleanAllClick(bottomSheetUI, cluster, markers, backendService) {
    const needsCleaning = false;
    handleCleaningsStatusAllCluster(cluster, markers, backendService, needsCleaning);
    updateSearchFieldWithAddress(null);
}

function handleClusterDirtyAllClick(bottomSheetUI, cluster, markers, backendService) {
    const needsCleaning = true;
    handleCleaningsStatusAllCluster(cluster, markers, backendService, needsCleaning);
    updateSearchFieldWithAddress(null);
}

function handleClusterFallbackClick() {
    showToast("Bitte nähere dich dem Stolperstein, um ihn zu markieren.");
}

function attachActionListeners(bottomSheetUI, cluster, markers, mapInstance, backendService, showExtendedActions) {
    const clusterCleanButton = bottomSheetUI._clusterCleanButton;
    const clusterDirtyButton = bottomSheetUI._clusterDirtyButton;
    const poiCleanButton = bottomSheetUI._poiCleanButton;
    const poiDirtyButton = bottomSheetUI._poiDirtyButton;
    const fallbackButton = bottomSheetUI._fallbackButton;
    const expandedActionsContainer = bottomSheetUI._expandedActionsContainer;
    if (!clusterCleanButton || !clusterDirtyButton || !fallbackButton || !expandedActionsContainer) {
        mylog("WARNUNG: Konnte notwendige Buttons/Container nicht finden.");
        return;
    }
    poiCleanButton.classList.add('hidden');
    poiDirtyButton.classList.add('hidden');
    clusterDirtyButton.classList.add('hidden');
    clusterCleanButton.classList.add('hidden');
    fallbackButton.classList.add('hidden');
    if (showExtendedActions) {
        expandedActionsContainer.classList.remove('hidden');
        clusterCleanButton.classList.remove('hidden');
        clusterCleanButton.textContent = `Alle sind in gutem Zustand ✅`;
        clusterDirtyButton.classList.remove('hidden');
        clusterDirtyButton.textContent = `Alle sind in schlechtem Zustand 🔴`;
        if (!clusterCleanButton._clusterCleanListener) {
            const cleanHandler = () => handleClusterCleanAllClick(bottomSheetUI, cluster, markers, backendService);
            clusterCleanButton.addEventListener('click', cleanHandler);
            clusterCleanButton._clusterCleanListener = cleanHandler;
        }
        if (!clusterDirtyButton._clusterDirtyListener) {
            const dirtyHandler = () => handleClusterDirtyAllClick(bottomSheetUI, cluster, markers, backendService);
            clusterDirtyButton.addEventListener('click', dirtyHandler);
            clusterDirtyButton._clusterDirtyListener = dirtyHandler;
        }
    } else {
        fallbackButton.classList.remove('hidden');
        fallbackButton.textContent = "Adresse aufsuchen, um den Zustand zu erfassen";
        if (!fallbackButton._clusterFallbackListener) {
            const fallbackHandler = () => handleClusterFallbackClick();
            fallbackButton.addEventListener('click', fallbackHandler);
            fallbackButton._clusterFallbackListener = fallbackHandler;
        }
    }
}

// --- Swipe-Logik ---
function handleSwipe(endX, cluster, allParams) {
    const threshold = 50;
    if (!allParams.mapState.activeMarkerOrCluster?.options?.data) return;
    let direction = null;
    if (endX < startX - threshold) direction = 'NEXT';
    else if (endX > startX + threshold) direction = 'PREVIOUS';
    else return;
    const childMarkers = cluster.getAllChildMarkers();
    const activeMarkerGid = allParams.mapState.activeMarkerOrCluster.options.data.gid;
    const currentIndex = childMarkers.findIndex(m => m.options.data.gid === activeMarkerGid);
    if (currentIndex === -1) return;
    const newIndex = direction === 'NEXT'
        ? (currentIndex + 1) % childMarkers.length
        : (currentIndex - 1 + childMarkers.length) % childMarkers.length;
 +    triggerMarkerClick(childMarkers[newIndex], allParams, cluster);
}

function handleHeaderSwipe(direction, cluster, allParams) {
    handleSwipe(direction === 'NEXT' ? startX - 51 : startX + 51, cluster, allParams);
}

export function detachSwipeListeners(bottomSheetUI) {
    const sheetContent = bottomSheetUI.contentArea;
    const sheetHeader = bottomSheetUI.HeaderTextElement;
    if (touchStartHandler) {
        sheetContent.removeEventListener('touchstart', touchStartHandler);
        sheetHeader.removeEventListener('touchstart', touchStartHandler);
        touchStartHandler = null;
    }
    if (mouseDownHandler) {
        sheetContent.removeEventListener('mousedown', mouseDownHandler);
        sheetHeader.removeEventListener('mousedown', mouseDownHandler);
        mouseDownHandler = null;
    }
    if (touchEndHandler) {
        sheetContent.removeEventListener('touchend', touchEndHandler);
        sheetHeader.removeEventListener('touchend', touchEndHandler);
        touchEndHandler = null;
    }
    if (mouseUpHandler) {
        sheetContent.removeEventListener('mouseup', mouseUpHandler);
        sheetHeader.removeEventListener('mouseup', mouseUpHandler);
        mouseUpHandler = null;
    }
    if (touchMoveHandler) {
        sheetContent.removeEventListener('touchmove', touchMoveHandler);
        sheetHeader.removeEventListener('touchmove', touchMoveHandler);
        touchMoveHandler = null;
    }
    if (mouseMoveHandler) {
        sheetContent.removeEventListener('mousemove', mouseMoveHandler);
        sheetHeader.removeEventListener('mousemove', mouseMoveHandler);
        mouseMoveHandler = null;
    }
}

export function attachSwipeListeners(bottomSheetUI, cluster, allParams) {
    detachSwipeListeners(bottomSheetUI);
    bottomSheetUI.onHeaderSwipeHorizontal((direction) => handleHeaderSwipe(direction, cluster, allParams));

    const sheetContent = bottomSheetUI.contentArea;
    const sheetHeader = bottomSheetUI.HeaderTextElement;
    let swipeDirection = null;

    // Touch-Handler
    touchStartHandler = (e) => {
        startX = e.touches[0].clientX;
        startY = e.touches[0].clientY;
        isSwiping = true;
        swipeDirection = null;
    };

    touchMoveHandler = (e) => {
        if (!isSwiping) return;
        const currentX = e.touches[0].clientX;
        const currentY = e.touches[0].clientY;
        const deltaX = currentX - startX;
        const deltaY = currentY - startY;
        if (swipeDirection === null) {
            if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {
                swipeDirection = 'horizontal';
                e.preventDefault();
            } else if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > 10) {
                swipeDirection = 'vertical';
            }
        }
        if (swipeDirection === 'horizontal') e.preventDefault();
    };

    touchEndHandler = (e) => {
        if (!isSwiping) return;
        const endX = e.changedTouches[0].clientX;
        if (swipeDirection === 'horizontal') handleSwipe(endX, cluster, allParams);
        isSwiping = false;
    };

    // Mouse-Handler
    mouseDownHandler = (e) => {
        startX = e.clientX;
        startY = e.clientY;
        isSwiping = true;
        swipeDirection = null;
    };

    mouseMoveHandler = (e) => {
        if (!isSwiping) return;
        const currentX = e.clientX;
        const currentY = e.clientY;
        const deltaX = currentX - startX;
        const deltaY = currentY - startY;
        if (swipeDirection === null) {
            if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(deltaX) > 10) {
                swipeDirection = 'horizontal';
                e.preventDefault();
            } else if (Math.abs(deltaY) > Math.abs(deltaX) && Math.abs(deltaY) > 10) {
                swipeDirection = 'vertical';
            }
        }
        if (swipeDirection === 'horizontal') e.preventDefault();
    };

    mouseUpHandler = (e) => {
        if (!isSwiping) return;
        const endX = e.clientX;
        if (swipeDirection === 'horizontal') handleSwipe(endX, cluster, allParams);
        isSwiping = false;
    };

    // Event-Listener für Touch und Mouse registrieren
    sheetContent.addEventListener('touchstart', touchStartHandler, { passive: true });
    sheetContent.addEventListener('touchmove', touchMoveHandler, { passive: false });
    sheetContent.addEventListener('touchend', touchEndHandler);

    sheetContent.addEventListener('mousedown', mouseDownHandler);
    sheetContent.addEventListener('mousemove', mouseMoveHandler);
    sheetContent.addEventListener('mouseup', mouseUpHandler);

    sheetHeader.addEventListener('touchstart', touchStartHandler, { passive: true });
    sheetHeader.addEventListener('touchmove', touchMoveHandler, { passive: false });
    sheetHeader.addEventListener('touchend', touchEndHandler);

    sheetHeader.addEventListener('mousedown', mouseDownHandler);
    sheetHeader.addEventListener('mousemove', mouseMoveHandler);
    sheetHeader.addEventListener('mouseup', mouseUpHandler);
}


// --- Exportierte Funktionen ---
export function updateBsForCluster(cluster, mapInstance, bottomSheetUI, markers, backendService, getAdminModeStatus, mapState, insertPoiUI, updatePoiUI) { 
    detachClusterBsListener(bottomSheetUI);
    const childMarkers = cluster.getAllChildMarkers();
    if (!bottomSheetUI || !cluster || childMarkers.length === 0) {
        showToast('Keine POI verfügbar im Cluster');
        if (bottomSheetUI?.isOpen()) bottomSheetUI.close();
        return;
    }
    

    const uiConfig = getClusterUIConfig(cluster, getAdminModeStatus); 

    if (childMarkers.some(marker => marker.options.data?.stone_position)) {
        bottomSheetUI.setSheetState(true);
    }
    const addressHtml = `${childMarkers[0].options.data.street || ''} ${childMarkers[0].options.data.house_no || ''}`;
    updateSearchFieldWithAddress(addressHtml);
    try {
        bottomSheetUI.setBsHeaderText(uiConfig.headerText + ' ↗');
        bottomSheetUI.setCoords(uiConfig.coords);
        bottomSheetUI.setContent(uiConfig.contentHtml);
        bottomSheetUI.setActions(uiConfig.actionsConfig);
        bottomSheetUI.open(cluster);
        
        // allParams OHNE locTrackingCoordinator füllen
        const allParams = { bottomSheetUI, markers, map: mapInstance, backendService, getAdminModeStatus, mapState, insertPoiUI, updatePoiUI }; 
        
        attachSwipeListeners(bottomSheetUI, cluster, allParams);
        setTimeout(() => {
            attachActionListeners(bottomSheetUI, cluster, markers, mapInstance, backendService, uiConfig.showExtendedActions);
            attachClusterLinkListener(bottomSheetUI, allParams, cluster);
        }, 50);
    } catch (e) {
        console.error("FEHLER Cluster:", e);
        showToast("Fehler beim Anzeigen der Cluster-Details.");
    }
}

export function setClusterMarkerIndex(clickedMarker, cluster) {
    if (cluster && clickedMarker) {
        currentMarkerIndex = cluster.getAllChildMarkers().indexOf(clickedMarker);
    }
}

export function attachClusterLinkListener(bottomSheetUI, allParams, cluster) {
    if (clusterLinkHandlerReference) {
        bottomSheetUI.contentArea.removeEventListener('click', clusterLinkHandlerReference);
        clusterLinkHandlerReference = null;
    }
    clusterLinkHandlerReference = (event) => {
        const targetLink = event.target.closest('.cluster-marker-link');
        if (targetLink) {
            event.preventDefault();
            const markerId = parseInt(targetLink.dataset.markerId, 10);
            const markerToClick = allParams.markers.getLayers().find(layer => layer.options.data?.gid === markerId);
            if (markerToClick) triggerMarkerClick(markerToClick, allParams, cluster);
        }
    };
    bottomSheetUI.contentArea.addEventListener('click', clusterLinkHandlerReference);
}

export function detachClusterBsListener(bottomSheetUI) {
    if (clusterLinkHandlerReference) {
        bottomSheetUI.contentArea.removeEventListener('click', clusterLinkHandlerReference);
        clusterLinkHandlerReference = null;
    }
    const cleanButton = bottomSheetUI._clusterCleanButton;
    if (cleanButton?._clusterCleanListener) {
        cleanButton.removeEventListener('click', cleanButton._clusterCleanListener);
        delete cleanButton._clusterCleanListener;
    }
    const fallbackButton = bottomSheetUI._fallbackButton;
    if (fallbackButton?._clusterFallbackListener) {
        fallbackButton.removeEventListener('click', fallbackButton._clusterFallbackListener);
        delete fallbackButton._clusterFallbackListener;
    }
    detachSwipeListeners(bottomSheetUI);
}