// 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 { handleMarkerSelection } from './map-gen-mgr.js';
import { LocationTrackingCoordinator } from './loc-tracking-co.js';
import { getAdminMode } from './admin-mode-co.js';
import { getMarkers, getMap } from './map-markers-co.js';
import { detachAllBsListeners } from './bs-gen-co.js';


let currentMarkerIndex = -1;
let startX = 0;
let startY = 0;
let isSwiping = false;
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;

        // Markierung für Verlegeort prüfen
        const hasStonePosition = data.stone_position !== null && data.stone_position !== undefined && data.stone_position !== '';
        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) {
    const childMarkers = cluster.getAllChildMarkers();
    const latlng = cluster.getLatLng();

    const locTrackingCoordinator = LocationTrackingCoordinator.getInstance();
    const isAdmin = getAdminMode.getStatus();

    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 actionsConfig = {
        showCaretaker: false,
        showAddButton: isCloseEnough || isAdmin,
        showEditButton: false,
        showMainActionDiv: true,
        showFallbackButton: !showExtendedActions,
        fallbackButtonClass: "primary disabled",
    };

    const hasStonePosition = childMarkers.some(marker => {
        const pos = marker.options.data?.stone_position;
        return pos !== null && pos !== undefined && pos !== '';
    });

    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(cluster, backendService) {
    handleCleaningsStatusAllCluster(cluster, backendService, false);
    updateSearchFieldWithAddress(null);
}

function handleClusterDirtyAllClick(cluster, backendService) {
    handleCleaningsStatusAllCluster(cluster, backendService, true);
    updateSearchFieldWithAddress(null);
}

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

function attachActionListeners(bottomSheetUI, cluster, backendService, showExtendedActions) {
    const clusterCleanButton = bottomSheetUI._clusterCleanButton;
    const clusterDirtyButton = bottomSheetUI._clusterDirtyButton;
    const fallbackButton = bottomSheetUI._fallbackButton;
    const expandedActionsContainer = bottomSheetUI._expandedActionsContainer;

    if (!clusterCleanButton || !clusterDirtyButton || !fallbackButton || !expandedActionsContainer) return;

    bottomSheetUI._poiCleanButton.classList.add('hidden');
    bottomSheetUI._poiDirtyButton.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(cluster, backendService);
            clusterCleanButton.addEventListener('click', cleanHandler);
            clusterCleanButton._clusterCleanListener = cleanHandler;
        }
        if (!clusterDirtyButton._clusterDirtyListener) {
            const dirtyHandler = () => handleClusterDirtyAllClick(cluster, backendService);
            clusterDirtyButton.addEventListener('click', dirtyHandler);
            clusterDirtyButton._clusterDirtyListener = dirtyHandler;
        }
    } else {
        expandedActionsContainer.classList.add('hidden');
        fallbackButton.classList.remove('hidden');
        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.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;
    const targetMarker = childMarkers[newIndex];

    // In bs-cluster-co.js (innerhalb des Click-Handlers für POI-Links im Cluster)
    handleMarkerSelection(
        targetMarker.options.gid,
        allParams,
        cluster
    );
}

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

export function detachSwipeListeners(bottomSheetUI) {
    const elements = [bottomSheetUI.contentArea, bottomSheetUI.HeaderTextElement];
    elements.forEach(el => {
        if (!el) return;
        el.removeEventListener('touchstart', touchStartHandler);
        el.removeEventListener('touchmove', touchMoveHandler);
        el.removeEventListener('touchend', touchEndHandler);
        el.removeEventListener('mousedown', mouseDownHandler);
        el.removeEventListener('mousemove', mouseMoveHandler);
        el.removeEventListener('mouseup', mouseUpHandler);
    });
}

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

    touchStartHandler = mouseDownHandler = (e) => {
        startX = e.touches ? e.touches[0].clientX : e.clientX;
        startY = e.touches ? e.touches[0].clientY : e.clientY;
        isSwiping = true;
    };

    touchMoveHandler = mouseMoveHandler = (e) => {
        if (!isSwiping) return;
        const currentX = e.touches ? e.touches[0].clientX : e.clientX;
        const deltaX = currentX - startX;
        if (Math.abs(deltaX) > 10 && e.cancelable) e.preventDefault();
    };

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

    [bottomSheetUI.contentArea, bottomSheetUI.HeaderTextElement].forEach(el => {
        if (!el) return;
        el.addEventListener('touchstart', touchStartHandler, { passive: true });
        el.addEventListener('touchmove', touchMoveHandler, { passive: false });
        el.addEventListener('touchend', touchEndHandler);
        el.addEventListener('mousedown', mouseDownHandler);
        el.addEventListener('mousemove', mouseMoveHandler);
        el.addEventListener('mouseup', mouseUpHandler);
    });
}

// --- Exportierte Funktionen ---
export function updateBsForCluster(cluster, bottomSheetUI, backendService, mapState) {
    detachAllBsListeners(bottomSheetUI);
    detachClusterBsListener(bottomSheetUI);
    bottomSheetUI.setClickedObject(cluster);

    const childMarkers = cluster.getAllChildMarkers();

    if (!bottomSheetUI || !cluster || childMarkers.length === 0) {
        if (bottomSheetUI?.isOpen()) bottomSheetUI.close();
        return;
    }

    const uiConfig = getClusterUIConfig(cluster);

    // 1. Erst die Basidaten setzen
    const firstPoiData = childMarkers[0].options.data || childMarkers[0].stone;
    if (firstPoiData && typeof bottomSheetUI.updateAddress === 'function') {
        bottomSheetUI.updateAddress(
            firstPoiData.street || '',
            firstPoiData.house_no || firstPoiData.house_number || '',
            firstPoiData.localdistrict || firstPoiData.local_district || ''
        );
    }

    // 2. Sheet öffnen (Das bereitet oft das DOM vor und setzt Standard-Sichtbarkeiten)
    // bottomSheetUI.open(cluster); 

    // 3. JETZT die spezifischen Cluster-Inhalte und Buttons setzen
    try {
        bottomSheetUI.setBsHeaderText(uiConfig.headerText + ' ↗');
        bottomSheetUI.setCoords(uiConfig.coords);
        bottomSheetUI.setContent(uiConfig.contentHtml);
        
        // Buttons explizit nach dem Öffnen setzen
        bottomSheetUI.setActions(uiConfig.actionsConfig);
/*
        if (childMarkers.some(marker => marker.options.data?.stone_position)) {
            bottomSheetUI.setSheetState(true);
        }
        */
/*
        const addressHtml = `${firstPoiData.street || ''} ${firstPoiData.house_no || ''}`;
        updateSearchFieldWithAddress(addressHtml);
        */

        const allParams = {
            bottomSheetUI,
            backendService,
            mapState
        };

        // 4. Listener mit leichtem Delay binden, um sicherzugehen, dass Buttons im DOM sind
        setTimeout(() => {
            attachActionListeners(bottomSheetUI, cluster, backendService, uiConfig.showExtendedActions);
            attachSwipeListeners(bottomSheetUI, cluster, allParams);
            attachClusterLinkListener(bottomSheetUI, allParams, cluster);
        }, 60); // Etwas großzügigerer Timeout
        
    } catch (e) {
        console.error("FEHLER Cluster UI Update:", e);
    }
}


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

function attachClusterLinkListener(bottomSheetUI, allParams, cluster) {
    if (clusterLinkHandlerReference) {
        bottomSheetUI.contentArea.removeEventListener('click', clusterLinkHandlerReference);
    }
    clusterLinkHandlerReference = (event) => {
        const targetLink = event.target.closest('.cluster-marker-link');
        if (targetLink) {
            event.preventDefault();
            const markerId = parseInt(targetLink.dataset.markerId, 10);
            const markers = getMarkers();
            const markerToClick = markers.getLayers().find(layer => layer.options.data?.gid === markerId);
            if (markerToClick) handleMarkerSelection(
                markerToClick.options.gid,
                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 dirtyButton = bottomSheetUI._clusterDirtyButton;
    if (dirtyButton?._clusterDirtyListener) {
        dirtyButton.removeEventListener('click', dirtyButton._clusterDirtyListener);
        delete dirtyButton._clusterDirtyListener;
    }
    const fallbackButton = bottomSheetUI._fallbackButton;
    if (fallbackButton?._clusterFallbackListener) {
        fallbackButton.removeEventListener('click', fallbackButton._clusterFallbackListener);
        delete fallbackButton._clusterFallbackListener;
    }
    detachSwipeListeners(bottomSheetUI);
}

export function handleClusterSelectionBs( clickedCluster, bottomSheetUI, backendService, mapState) {

    updateBsForCluster(clickedCluster, 
        bottomSheetUI,
        backendService,
        mapState 
    );

    bottomSheetUI.open(clickedCluster);
}