/**
 * @fileoverview bs-cluster-co.js
 * Bereinigte Fassung: Texte werden getrennt gesetzt, Auge am Titel, Swipe aktiv.
 * Integration des IntroButton analog zu bs-poi-co.js.
 */

import { ApplicationCoordinator } from './app-gen-co.js';
import { getAdminMode } from './admin-mode-co.js';
import { getPoiData, getPoiStore } from './poi-store.js';
import { showToast, mylog, getColorCodeAndText } from './utilities.js';
import { getLocationToggleState } from './sc-settings-location.js';
import { LocationTrackingCoordinator } from './loc-tracking-co.js';
// --- NEU: IntroButton importieren ---
import { L } from './map-service.js';
import { ScIntroButton } from './intro-button.js';

// --- Modul-interne Zustände ---
let startX = 0;
let isSwiping = false;
let isProcessingSwipe = false;
let clusterLinkHandlerReference = null;
let currentSwipeGid = null;
let currentClusterGids = [];

/**
 * Führt die zirkuläre Navigation aus.
 */
function navigateCluster(direction) {
    if (currentClusterGids.length <= 1 || isProcessingSwipe) return;

    isProcessingSwipe = true;
    const currentIndex = currentClusterGids.indexOf(parseInt(currentSwipeGid, 10));

    const nextIndex = (direction === 'NEXT')
        ? (currentIndex + 1) % currentClusterGids.length
        : (currentIndex - 1 + currentClusterGids.length) % currentClusterGids.length;

    const nextGid = currentClusterGids[nextIndex];
    mylog(`Nav: ${direction} -> GID ${nextGid}`);

    requestPoiSelection(nextGid);
    setTimeout(() => { isProcessingSwipe = false; }, 400);
}

const swipeHandlers = {
    handleStart: (e) => {
        if (isProcessingSwipe) return;
        startX = e.touches ? e.touches[0].clientX : e.clientX;
        isSwiping = true;
    },
    handleEnd: (e) => {
        if (!isSwiping || isProcessingSwipe) return;
        const endX = e.changedTouches ? e.changedTouches[0].clientX : e.clientX;
        const diff = endX - startX;

        if (Math.abs(diff) > 50) {
            navigateCluster(diff < 0 ? 'NEXT' : 'PREVIOUS');
        }
        isSwiping = false;
    }
};

// --- Hilfsfunktionen ---

function getGidsInRange(lat, lng) {
    const searchLatLng = L.latLng(lat, lng);
    const nearby = [];
    for (const poi of getPoiStore().values()) {
        const poiPos = L.latLng(poi.lat, poi.lng);
        if (poiPos.distanceTo(searchLatLng) < 2) {
            nearby.push(parseInt(poi.gid, 10));
        }
    }
    return nearby.sort((a, b) => a - b);
}

function getClusterContentHtml(childMarkers) {
    const poiList = childMarkers.map(marker => {
        const poiData = getPoiData(marker.options.gid);
        if (!poiData) return null;
        return {
            gid: marker.options.gid,
            data: poiData,
            firstName: (poiData.first_name || "").trim(),
            lastName: (poiData.last_name || "").trim()
        };
    }).filter(item => item !== null);

    poiList.sort((a, b) => {
        const firstCompare = a.firstName.localeCompare(b.firstName, 'de');
        if (firstCompare !== 0) return firstCompare;
        return a.lastName.localeCompare(b.lastName, 'de');
    });

    let clusterContent = `<div class="cluster-detail-list" style="font-size:1.2rem;">`;
    poiList.forEach(item => {
        const { colorCode } = getColorCodeAndText(item.data.last_cleaned);
        const nameText = `${item.firstName} ${item.lastName}`;
        clusterContent += `
            <div class="cluster-list-item">
                <a href="#" class="cluster-marker-link" data-marker-id="${item.gid}">
                    <span class="status-dot ${colorCode}"></span>
                    <span class="poi-name">${nameText}</span>
                </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();
        if (currentUserPosition && getLocationToggleState()) {
            const distance = L.latLng(currentUserPosition[0], currentUserPosition[1]).distanceTo(latlng);
            return distance <= 100;
        }
        return false;
    })();

    const showExtendedActions = isCloseEnough || isAdmin;

    let firstStonePosition = null;
    let personName = "";

    for (const marker of childMarkers) {
        const poiData = getPoiData(marker.options.gid);
        if (poiData?.stone_position) {
            firstStonePosition = poiData.stone_position;
            personName = `${poiData.first_name || ''} ${poiData.last_name || ''}`.trim();
            break;
        }
    }

    const titleText = `${childMarkers.length} Stolpersteine`;
    let locationText = "";
    if (firstStonePosition) {
        locationText = `<span style="color: red;">Verlegeort:</span> ${firstStonePosition} (s. ${personName})`;
    }

    return {
        titleText,
        locationText,
        contentHtml: getClusterContentHtml(childMarkers),
        coords: { lat: latlng.lat, lng: latlng.lng },
        actionsConfig: {
            showPoiPhotoStack: false,
            showAddButton: showExtendedActions,
            showCaretaker: false,
            showAddButton: showExtendedActions,
            showEditButton: false,
            showMainActionDiv: true,
            showFallbackButton: !showExtendedActions,
            showIntroButton: showExtendedActions, // --- NEU: Sichtbarkeit des IntroButtons ---
            fallbackButtonClass: "primary disabled",
        },
        showExtendedActions
    };
}

// --- Handler ---

export function requestPoiSelection(gid) {
    const numericGid = parseInt(gid, 10);
    ApplicationCoordinator.appEvents.dispatchEvent(new CustomEvent('poi:requestSelection', {
        detail: { gid: numericGid }
    }));
}
/**
 * Kontrolliert alle Klick-Aktionen im Bottom Sheet des Clusters.
 */

/**
 * Kontrolliert alle Klick-Aktionen im Bottom Sheet des Clusters.
 * Spezial-Buttons für User 'icke' integriert.
 */
/**
 * Kontrolliert alle Klick-Aktionen im Bottom Sheet des Clusters.
 * Enthält Spezial-Logik für User 'icke' und Cluster-Validierung.
 */
export function attachActionListeners(bottomSheetUI, cluster, showExtendedActions) {


    // Zuerst ALLES entfernen, was 'icke' dort hinterlassen hat
   bottomSheetUI.mainActionsContainer?.querySelectorAll('.special-status-btn').forEach(btn => btn.remove());
    const bus = ApplicationCoordinator.appEvents;
    const {
        addButton, poiCleanButton, poiDirtyButton,
        clusterCleanButton, clusterDirtyButton,
        fallbackButton, mainActionsContainer, introButton
    } = bottomSheetUI;

    // 1. ABSOLUTER RESET: Bestehende UI-Elemente verstecken und Stile zurücksetzen
    [poiCleanButton, poiDirtyButton, clusterCleanButton, clusterDirtyButton, introButton, fallbackButton]
        .forEach(btn => {
            if (btn) {
                btn.classList.add('hidden');
                btn.style.setProperty('display', 'none', 'important');
            }
        });

    // Alte Spezial-Buttons (Gelb/Orange) entfernen, um Duplikate zu vermeiden
    mainActionsContainer?.querySelectorAll('.special-status-btn').forEach(btn => btn.remove());

    if (showExtendedActions) {  
        if (mainActionsContainer) {
            mainActionsContainer.classList.remove('hidden');
            mainActionsContainer.style.setProperty('display', 'flex', 'important');
        }

        if (clusterCleanButton && clusterDirtyButton && introButton) {
            
            // --- GRÜNER BUTTON: Alle glänzend (Code 0) ---
            clusterCleanButton.classList.remove('hidden');
            clusterCleanButton.style.setProperty('display', 'flex', 'important');
            clusterCleanButton.style.order = "1";
            clusterCleanButton.textContent = "Alle glänzend";
            clusterCleanButton.onclick = (e) => {
                e.stopPropagation();
                mylog("[Cluster-CO] Update: Alle glänzend (Code 0)");
                bus.dispatchEvent(new CustomEvent('cluster:executeStatusUpdate', {
                    detail: { cluster, timeCode: 0 }
                }));
            };

            // Intro Button (Zentrum)
            introButton.classList.remove('hidden');
            introButton.style.setProperty('display', 'flex', 'important');
            introButton.style.order = "2";

            // --- ROTER BUTTON: Alle stumpf (Code 4: -12 Monate) ---
            clusterDirtyButton.classList.remove('hidden');
            clusterDirtyButton.style.setProperty('display', 'flex', 'important');
            clusterDirtyButton.style.order = "3";
            clusterDirtyButton.textContent = "Alle stumpf";
            clusterDirtyButton.onclick = (e) => {
                e.stopPropagation();
                mylog("[Cluster-CO] Update: Alle stumpf (Code 4)");
                bus.dispatchEvent(new CustomEvent('cluster:executeStatusUpdate', {
                    detail: { cluster, timeCode: 4 }
                }));
            };

            // --- SPEZIAL-LOGIK FÜR currentUser 'icke' IM CLUSTER-MODUS ---
            const currentUser = localStorage.getItem('currentUser');
            
            // Prüfung: Ist es ein echtes Cluster mit mehr als einem Stein?
            const childMarkers = (cluster && typeof cluster.getAllChildMarkers === 'function') 
                                 ? cluster.getAllChildMarkers() 
                                 : [];
            const isRealCluster = childMarkers.length > 1;

            if (currentUser === 'icke' && isRealCluster) {
                
                /**
                 * Hilfsfunktion zum Erstellen der runden Status-Buttons
                 */
                const createSpecialBtn = (color, code, order) => {
                    const btn = document.createElement('button');
                    btn.className = 'special-status-btn action-button'; 
                    btn.style.backgroundColor = color;
                    btn.style.order = order.toString();
                    btn.style.marginLeft = '6px';
                    btn.style.minWidth = '42px';
                    btn.style.display = 'flex';
                    btn.style.justifyContent = 'center';
                    btn.style.alignItems = 'center';
                    btn.style.border = '1px solid rgba(0,0,0,0.2)';
                    // Ein dezenter Punkt als Indikator
                    btn.innerHTML = '<span style="filter: contrast(0.5); font-size: 0.8rem;">●</span>';
                    
                    btn.onclick = (e) => {
                        e.stopPropagation();
                        mylog(`[Cluster-CO] Spezial-Update für ${currentUser}: Code ${code}`);
                        bus.dispatchEvent(new CustomEvent('cluster:executeStatusUpdate', {
                            detail: { cluster, timeCode: code }
                        }));
                    };
                    return btn;
                };

                // GELB (Code 1: -1 Monat) - Position hinter 'Alle stumpf'
                mainActionsContainer.appendChild(createSpecialBtn('yellow', 1, 4));
                
                // ORANGE (Code 2: -3 Monate) - Position ganz rechts
                mainActionsContainer.appendChild(createSpecialBtn('orange', 2, 5));
            }
        }

        // Deaktiviere Fallback-Button, wenn wir in Reichweite/Admin sind
        if (fallbackButton) {
            fallbackButton.classList.add('hidden');
            fallbackButton.style.setProperty('display', 'none', 'important');
        }

    } else {
        // Fallback (Lila Button) anzeigen, wenn zu weit entfernt
        if (fallbackButton) {
            fallbackButton.classList.remove('hidden');
            fallbackButton.style.setProperty('display', 'block', 'important');
        }
    }
}

/**
 * EXPORTIERT: Swipe Listener
 */
export function attachSwipeListeners(bottomSheetUI, activeMarkerGid) {
    //detachSwipeListeners(bottomSheetUI);

    const poi = getPoiData(activeMarkerGid);
    if (!poi || !bottomSheetUI) return;

    currentClusterGids = getGidsInRange(poi.lat, poi.lng);
    currentSwipeGid = activeMarkerGid;

    const hasMultiple = currentClusterGids.length > 1;
    bottomSheetUI.setNavButtonsState(hasMultiple, hasMultiple);

    if (hasMultiple) {
        bottomSheetUI.onHeaderSwipeHorizontal((direction) => {
            navigateCluster(direction);
        });
        mylog("[Cluster-CO] Swipe-Callback registriert.");
    }
}

/**
 * EXPORTIERT: Swipe detach
 */
export function detachSwipeListeners(bottomSheetUI) {
    bottomSheetUI.setNavButtonsState(false, false);
}

export function attachClusterLinkListener(bottomSheetUI) {
    if (clusterLinkHandlerReference) {
        bottomSheetUI.contentArea.removeEventListener('click', clusterLinkHandlerReference);
    }
    clusterLinkHandlerReference = (event) => {
        const targetLink = event.target.closest('.cluster-marker-link');
        if (targetLink) {
            event.preventDefault();
            requestPoiSelection(targetLink.dataset.markerId);
        }
    };
    bottomSheetUI.contentArea.addEventListener('click', clusterLinkHandlerReference);
}

export function handleClusterIconClick(cluster) {
    const childMarkers = cluster.getAllChildMarkers();
    const map = cluster._group._map;
    const currentZoom = map.getZoom();

    if (currentZoom < 18) {
        map.setView(cluster.getLatLng(), currentZoom + 2);
        return;
    }

    const firstMarker = childMarkers[0];
    if (firstMarker && firstMarker.options.gid) {
        requestPoiSelection(firstMarker.options.gid);
    }
}
/**
 * Aktualisiert den Inhalt des Bottom Sheets für einen Cluster.
 * Wir geben hier ein Promise zurück, falls asynchrone Komponenten (wie IntroButton) 
 * Zeit zum Rendern brauchen, primär aber für die Konsistenz.
 */
export async function updateBsForCluster(cluster, bottomSheetUI, activeMarkerGid, addDirectionHint) {
    if (!bottomSheetUI || !cluster) return;

    bottomSheetUI.setClickedObject(cluster);
    const uiConfig = getClusterUIConfig(cluster);
    bottomSheetUI.setCoords(uiConfig.coords);

    bottomSheetUI.setBsTitle(addDirectionHint(uiConfig.titleText));

    bottomSheetUI.setBsLocation(uiConfig.locationText);

    bottomSheetUI.setContent(uiConfig.contentHtml);
    bottomSheetUI.setActions(uiConfig.actionsConfig);

    // --- IntroButton-Komponente einbinden ---
    if (uiConfig.actionsConfig.showIntroButton && bottomSheetUI.introButton) {
        bottomSheetUI.introButton.innerHTML = '';
        const introBtn = new ScIntroButton('bs-cluster-intro-btn');
        bottomSheetUI.introButton.appendChild(introBtn.getElement());
    }

    const firstPoi = getPoiData(cluster.getAllChildMarkers()[0]?.options.gid);
    if (firstPoi) {
        bottomSheetUI.updateAddress(firstPoi.street || '', firstPoi.houseNr || '', firstPoi.localdistrict || '');
    }

    // Listener sofort attachen, nicht verzögert, damit sie beim Resolve bereit sind
    attachActionListeners(bottomSheetUI, cluster, uiConfig.showExtendedActions);
    attachSwipeListeners(bottomSheetUI, activeMarkerGid);
    attachClusterLinkListener(bottomSheetUI);

    return true;
}

/**
 * EXPORTIERT: Öffnet das BS und gibt ein Promise zurück, das erst nach 
 * Abschluss der Öffnen-Animation (Transition) aufgelöst wird.
 */
export async function handleClusterSelectionBs(clickedCluster, bottomSheetUI, activeMarkerGid,addDirectionHint) {
    // 1. Inhalt setzen
    await updateBsForCluster(clickedCluster, bottomSheetUI, activeMarkerGid, addDirectionHint);

    // 2. BS öffnen und auf die Transition warten
    // Hier wird vorausgesetzt, dass bottomSheetUI.open() ein Promise zurückgibt
    // oder du nutzt die waitForTransition() Methode deiner BsUI.
    await bottomSheetUI.open();

    mylog("[Cluster-CO] BS offen & stabil.");
}