<div xmlns:th="http://www.thymeleaf.org" th:fragment="configuration-preview" class="settings-card" id="configuration-preview">
    <h3 th:text="#{visit.sensitivity.preview.title}">Configuration Preview</h3>
    
    <div class="preview-controls">
        <div class="toggle-buttons">
            <button id="current-data-btn" class="btn btn-primary active" onclick="showCurrentData()">
                <span th:text="#{visit.sensitivity.preview.current}">Current Data</span>
            </button>
            <button id="preview-data-btn" class="btn btn-secondary" onclick="showPreviewData()">
                <span th:text="#{visit.sensitivity.preview.new}">Preview Data</span>
                <span id="preview-status" class="status-indicator">
                   <i class="lni lni-is-spinning lni-spinner-2-sacle"></i>
                    <span th:text="#{visit.sensitivity.preview.calculating}">Calculating...</span>
                </span>
            </button>
        </div>
        <div class="date-selection">
            <label for="preview-date" th:text="#{visit.sensitivity.preview.date}">Preview Date:</label>
            <input type="date" 
                   id="preview-date" 
                   th:value="${previewDate}" 
                   hx-post="/settings/visit-sensitivity/preview"
                   hx-vals='js:{"timezone": getUserTimezone()}'
                   hx-target="#preview-area"
                   hx-include="#configuration-form"
                   hx-trigger="change[target.value != '']"
                   name="previewDate">
        </div>
    </div>
    
    <div class="preview-maps">
        <!-- Current Data Map -->
        <div id="current-map-container" class="map-container active">
            <div class="map-with-timeline">
                <div id="current-timeline" class="timeline-sidebar">
                    <div id="current-timeline-content" class="timeline-content">
                        <div class="loading">Loading timeline...</div>
                    </div>
                </div>
                <div id="current-map" class="map"></div>
            </div>
        </div>
        
        <!-- Preview Data Map -->
        <div id="preview-map-container" class="map-container">
            <div class="map-with-timeline">
                <div id="preview-timeline" class="timeline-sidebar">
                    <div id="preview-timeline-content" class="timeline-content">
                        <div class="loading">Loading preview...</div>
                    </div>
                </div>
                <div id="preview-map" class="map"></div>
            </div>
        </div>
    </div>
    
    <div class="preview-info">
        <h4 th:text="#{visit.sensitivity.preview.config.details}">Configuration Details</h4>
        <div class="config-details">
            <div class="detail-group">
                <h4 th:text="#{visit.sensitivity.visit.detection}">Visit Detection</h4>
                <p><strong th:text="#{visit.sensitivity.min.stay.time}">Minimum Stay Time:</strong>
                   <span th:text="${previewConfig.visitDetection.minimumStayTimeInSeconds}"></span>s</p>
            </div>
            <div class="detail-group">
                <h4 th:text="#{visit.sensitivity.visit.merging}">Visit Merging</h4>
                <p><strong th:text="#{visit.sensitivity.search.duration}">Search Duration:</strong> 
                   <span th:text="${previewConfig.visitMerging.searchDurationInHours}"></span>h</p>
                <p><strong th:text="#{visit.sensitivity.max.merge.time}">Max Merge Time:</strong> 
                   <span th:text="${previewConfig.visitMerging.maxMergeTimeBetweenSameVisits}"></span>s</p>
                <p><strong th:text="#{visit.sensitivity.min.distance}">Min Distance:</strong> 
                   <span th:text="${previewConfig.visitMerging.minDistanceBetweenVisits}"></span>m</p>
            </div>
        </div>
    </div>
    
    <script th:inline="javascript">
        (function() {
            let previewId = /*[[${previewId}]]*/ '';
            let previewDate = /*[[${previewDate}]]*/ '';
            let currentMap = null;
            let previewMap = null;
            let currentMapInitialized = false;
            let previewMapInitialized = false;
            let previewReady = false;
            let eventSource = null;
            let reconnectTimeoutId = null;
            
            window.showCurrentData = function() {
                document.getElementById('current-data-btn').classList.add('active');
                document.getElementById('preview-data-btn').classList.remove('active');
                document.getElementById('current-map-container').classList.add('active');
                document.getElementById('preview-map-container').classList.remove('active');
                
                if (!currentMapInitialized) {
                    initCurrentMap();
                }
            };
            
            window.showPreviewData = function() {
                document.getElementById('current-data-btn').classList.remove('active');
                document.getElementById('preview-data-btn').classList.add('active');
                document.getElementById('current-map-container').classList.remove('active');
                document.getElementById('preview-map-container').classList.add('active');
                
                if (!previewMapInitialized && previewReady) {
                    initPreviewMap();
                } else if (previewMapInitialized && previewReady) {
                    // Reload data in case it was updated while tab was inactive
                    loadPreviewMapData();
                }
            };
            
            function initCurrentMap() {
                if (currentMapInitialized) return;
                
                // Initialize Leaflet map for current data
                currentMap = L.map('current-map', {zoomControl: false, attributionControl: false})
                    .setView([window.userSettings?.homeLatitude || 60.1699, window.userSettings?.homeLongitude || 24.9384], 12);
                
                // Add tile layer
                const tilesUrl = window.userSettings?.tiles?.service || 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
                const tilesAttribution = window.userSettings?.tiles?.attribution || '© OpenStreetMap contributors';
                
                const tileLayer = window.userSettings?.preferColoredMap ? L.tileLayer : L.tileLayer.grayscale;
                tileLayer(tilesUrl, {
                    maxZoom: 19,
                    attribution: tilesAttribution
                }).addTo(currentMap);
                
                // Load current data for the selected date
                loadCurrentMapData();
                currentMapInitialized = true;
            }
            
            function initPreviewMap() {
                if (previewMapInitialized) return;
                
                // Initialize Leaflet map for preview data
                previewMap = L.map('preview-map', {zoomControl: false, attributionControl: false})
                    .setView([window.userSettings?.homeLatitude || 60.1699, window.userSettings?.homeLongitude || 24.9384], 12);
                
                // Add tile layer
                const tilesUrl = window.userSettings?.tiles?.service || 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
                const tilesAttribution = window.userSettings?.tiles?.attribution || '© OpenStreetMap contributors';
                
                const tileLayer = window.userSettings?.preferColoredMap ? L.tileLayer : L.tileLayer.grayscale;
                tileLayer(tilesUrl, {
                    maxZoom: 19,
                    attribution: tilesAttribution
                }).addTo(previewMap);
                
                // Load preview data
                loadPreviewMapData();
                previewMapInitialized = true;
            }
            
            function loadCurrentMapData() {
                if (!currentMap) return;
                
                // Fetch current processed visits/trips for the selected date
                fetch(`/api/v1/timeline?date=${previewDate}&timezone=${getUserTimezone()}`)
                    .then(response => response.json())
                    .then(data => {
                        updateTimelineContent('current-timeline-content', data);
                        updateMapWithData(currentMap, data, '#ff6c00');
                        loadRawLocationData(currentMap, data, '#ff6c00');
                    })
                    .catch(error => {
                        console.error('Error loading current map data:', error);
                        document.getElementById('current-timeline-content').innerHTML = '<div class="error">Error loading timeline</div>';
                    });
            }
            
            function loadPreviewMapData() {
                if (!previewMap || !previewReady) return;
                
                // Fetch preview processed visits/trips
                fetch(`/api/v1/preview/${previewId}/timeline?date=${previewDate}&timezone=${getUserTimezone()}`)
                    .then(response => response.json())
                    .then(data => {
                        updateTimelineContent('preview-timeline-content', data);
                        updateMapWithData(previewMap, data, '#4CAF50');
                        loadRawLocationData(previewMap, data, '#4CAF50');
                    })
                    .catch(error => {
                        console.error('Error loading preview map data:', error);
                        document.getElementById('preview-timeline-content').innerHTML = '<div class="error">Error loading preview</div>';
                    });
            }
            
            function updateMapWithData(map, data, color) {
                // Clear existing layers (except tile layer)
                map.eachLayer(layer => {
                    if (!layer._url) {
                        map.removeLayer(layer);
                    }
                });
                
                const bounds = L.latLngBounds();
                let hasValidCoords = false;
                
                // Group places by coordinates to avoid duplicate markers
                const placeGroups = new Map();

                // Process timeline data (similar to index.html)
                if (data && data.length > 0) {
                    data.forEach(element => {
                        if (element.type === 'VISIT') {
                            const visit = element;
                            const lat = visit.place?.latitudeCentroid;
                            const lng = visit.place?.longitudeCentroid;
                            
                            if (lat && lng) {
                                const coordKey = `${lat.toFixed(6)},${lng.toFixed(6)}`;
                                
                                if (!placeGroups.has(coordKey)) {
                                    placeGroups.set(coordKey, {
                                        lat: lat,
                                        lng: lng,
                                        totalDurationMs: 0,
                                        visits: [],
                                        place: visit.place
                                    });
                                }
                                const group = placeGroups.get(coordKey);
                                group.totalDurationMs += parseDurationText(element.formattedDuration);
                                group.visits.push(visit);
                                
                                bounds.extend([lat, lng]);
                                hasValidCoords = true;
                            }
                        }
                    });
                }
                
                // Draw markers for grouped places
                placeGroups.forEach((group) => {
                    const { lat, lng, totalDurationMs, visits, place } = group;
                    
                    // Calculate radius using logarithmic scale
                    const durationHours = totalDurationMs / (1000 * 60 * 60);
                    const baseRadius = 15;
                    const maxRadius = 100;
                    const minRadius = 15;

                    const logScale = Math.log(1 + durationHours) / Math.log(1 + 24);
                    const radius = Math.min(maxRadius, Math.max(minRadius, baseRadius + (logScale * (maxRadius - baseRadius))));
                    
                    // Create marker
                    L.circleMarker([lat, lng], {
                        radius: 5,
                        fillColor: color,
                        color: '#fff',
                        weight: 1,
                        opacity: 1,
                        fillOpacity: 0.8
                    }).addTo(map);
                    
                    // Create circle with calculated radius
                    const circle = L.circle([lat, lng], {
                        color: color,
                        fillColor: color,
                        fillOpacity: 0.1,
                        radius: radius
                    }).addTo(map);
                    
                    const totalDurationText = humanizeDuration(totalDurationMs, {units: ["h", "m"], round: true});
                    const visitCount = visits.length;
                    const visitText = visitCount === 1 ? 'visit' : 'visits';
                    
                    const tooltip = L.tooltip([lat, lng], {
                        content: `<div style="font-size: 1.4rem; color: wheat">${place.name || 'Unknown Place'}</div>
                         <div style="margin-top: 4px; font-weight: bold;">
                             ${visitCount} ${visitText} - Total: ${totalDurationText}
                         </div>`,
                        className: 'visit-popup',
                        permanent: false
                    });
                    
                    circle.bindTooltip(tooltip);
                });
                
                // Store bounds for later use
                if (hasValidCoords && bounds.isValid()) {
                    map._previewBounds = bounds;
                }
            }
            
            function updateTimelineContent(containerId, data) {
                const container = document.getElementById(containerId);
                if (!container) return;
                
                let html = '';

                if (data.length > 0) {
                    data.forEach(element => {
                        if (element.type === 'TRIP') {
                            const trip = element;
                            const timeRange = trip.formattedTimeRange;
                            const duration = trip.formattedDuration;
                            const distance = trip.formattedDistance;
                            const mode = trip.transportMode || 'Unknown';

                            html += `
                                <div class="timeline-entry trip">
                                    <div class="place-name">Trip</div>
                                    <div class="entry-time">${timeRange}</div>
                                    <div class="trip-info">
                                        <span class="transport-mode">${mode}</span>
                                        ${distance ? `<span class="distance">${distance}</span>` : ''}
                                    </div>
                                    <div class="entry-duration">${duration}</div>
                                </div>
                            `;
                        } else if (element.type === 'VISIT') {
                            const visit = element;
                            const timeRange = visit.formattedTimeRange;
                            const duration = visit.formattedDuration;
                            const placeName = visit.place?.name || 'Unknown Place';

                            html += `
                            <div class="timeline-entry visit" data-lat="${visit.place?.latitudeCentroid}" data-lng="${visit.place?.longitudeCentroid}">
                                <div class="place-name">${placeName}</div>
                                <div class="entry-time">${timeRange}</div>
                                <div class="entry-duration">${duration}</div>
                            </div>
                        `;
                        }
                    });
                }
                
                if (html === '') {
                    html = '<div class="no-data">No timeline data for this date</div>';
                }
                
                container.innerHTML = html;
            }
            
            function loadRawLocationData(map, timelineData, color) {
                // Extract raw location points URL from timeline data
                let rawLocationPointsUrl = null;
                // Look for raw location points URL in the timeline data
                if (timelineData && timelineData.length > 0) {
                    const firstUserSection = timelineData.find(item => item.rawLocationPointsUrl);
                    if (firstUserSection) {
                        rawLocationPointsUrl = firstUserSection.rawLocationPointsUrl;
                    }
                }
                
                if (!rawLocationPointsUrl) {
                    // Construct URL based on current date and user
                    rawLocationPointsUrl = `/api/v1/raw-location-points?date=${previewDate}&timezone=${getUserTimezone()}`;
                }
                
                // Fetch and display raw location points
                fetch(rawLocationPointsUrl)
                    .then(response => {
                        if (!response.ok) {
                            console.warn('Could not fetch raw location points');
                            return { points: [] };
                        }
                        return response.json();
                    })
                    .then(rawPointsData => {
                        updateMapWithRawPoints(map, rawPointsData, color);
                    })
                    .catch(error => {
                        console.warn('Error fetching raw location points:', error);
                    });
            }
            
            function updateMapWithRawPoints(map, rawPointsData, color) {
                const bounds = L.latLngBounds();
                
                const rawPointsPath = L.geodesic([], {
                    color: color,
                    weight: 2,
                    opacity: 0.9,
                    lineJoin: 'round',
                    lineCap: 'round',
                    steps: 2
                });

                if (rawPointsData && rawPointsData.segments && rawPointsData.segments.length > 0) {
                    for (const segment of rawPointsData.segments) {
                        const rawPointsCoords = segment.points.map(point => [point.latitude, point.longitude]);
                        bounds.extend(rawPointsCoords);
                        rawPointsPath.setLatLngs(rawPointsCoords);
                        rawPointsPath.addTo(map);

                        // Combine with existing bounds if they exist
                        if (map._previewBounds && map._previewBounds.isValid()) {
                            bounds.extend(map._previewBounds);
                        }

                        // Fit map to combined bounds
                        if (bounds.isValid()) {
                            map.fitBounds(bounds, {
                                paddingTopLeft: [20, 20],
                                paddingBottomRight: [20, 20],
                                maxZoom: 15
                            });
                        }
                    }

                }

            }
            
            function getUserTimezone() {
                if (window.userSettings?.timezoneOverride) {
                    return window.userSettings.timezoneOverride;
                } else {
                    return Intl.DateTimeFormat().resolvedOptions().timeZone;
                }
            }
            const locale =  {
                preview: {
                    ready: /*[[#{visit.sensitivity.preview.ready}]]*/ 'Ready',
                    error: /*[[#{visit.sensitivity.preview.error}]]*/ 'Error',
                }
            }
            function checkPreviewStatus() {
                fetch(`/api/v1/preview/${previewId}/status`)
                    .then(response => response.json())
                    .then(data => {
                        if (data.ready) {
                            previewReady = true;
                            document.getElementById('preview-status').innerHTML = 
                                `<i class="lni lni-checkmark-circle"></i><span>${locale.preview.ready}</span>`;
                            document.getElementById('preview-data-btn').disabled = false;
                            
                            // If preview tab is active, initialize the map
                            if (document.getElementById('preview-data-btn').classList.contains('active')) {
                                initPreviewMap();
                            } else if (previewMapInitialized) {
                                // If map is already initialized, just load the data
                                loadPreviewMapData();
                            }
                        } else {
                            // Continue polling
                            setTimeout(checkPreviewStatus, 2000);
                        }
                    })
                    .catch(error => {
                        console.error('Error checking preview status:', error);
                        document.getElementById('preview-status').innerHTML = 
                            `<i class="lni lni-warning"></i><span>${locale.preview.error}</span>`;
                    });
            }

            // Helper function to parse duration text (simple implementation)
            function parseDurationText(durationText) {
                // Extract numbers followed by 'h' or 'm'
                const hours = (durationText.match(/(\d+)h/) || [0, 0])[1];
                const minutes = (durationText.match(/(\d+)m/) || [0, 0])[1];
                return (parseInt(hours) * 60 + parseInt(minutes)) * 60 * 1000; // Convert to milliseconds
            }
            
            function connectSSE() {
                console.log('Configuration Preview: Connecting to SSE...');
                eventSource = new EventSource('/events');

                eventSource.onopen = function() {
                    console.log('Configuration Preview: SSE connection opened.');
                    
                    // Clear any pending reconnect timeout since we're connected
                    if (reconnectTimeoutId) {
                        clearTimeout(reconnectTimeoutId);
                        reconnectTimeoutId = null;
                    }
                };

                eventSource.onerror = function(error) {
                    console.error('Configuration Preview: EventSource failed:', error);
                    
                    // Close the current connection
                    if (eventSource) {
                        eventSource.close();
                        eventSource = null;
                    }
                    
                    // Schedule reconnection after 5 seconds
                    if (!reconnectTimeoutId) {
                        console.log('Configuration Preview: Scheduling SSE reconnection in 5 seconds...');
                        reconnectTimeoutId = setTimeout(() => {
                            reconnectTimeoutId = null;
                            connectSSE();
                        }, 5000);
                    }
                };

                eventSource.onmessage = function(event) {
                    console.log('Configuration Preview: Received SSE event:', event.data);
                    
                    // Clear any pending reconnect timeout since we're receiving messages
                    if (reconnectTimeoutId) {
                        clearTimeout(reconnectTimeoutId);
                        reconnectTimeoutId = null;
                    }
                    
                    // Parse the event data
                    try {
                        const eventData = JSON.parse(event.data);
                        
                        // Check if this event is for our preview
                        if (eventData.previewId && eventData.previewId === previewId) {
                            console.log('Configuration Preview: Received event for our preview, reloading data');
                            // Check if the event date matches our preview date
                            if (eventData.type === 'PLACE' || (eventData.date && eventData.date === previewDate)) {
                                // Reload preview data if preview is ready and visible
                                if (previewReady) {
                                    if (document.getElementById('preview-data-btn').classList.contains('active')) {
                                        // Preview tab is active, reload immediately
                                        loadPreviewMapData();
                                    } else {
                                        // Preview tab is not active, just mark that data needs refresh
                                        console.log('Configuration Preview: Preview data updated, will refresh when tab becomes active');
                                    }
                                }
                                
                                // Also reload current data to show the difference
                                if (currentMapInitialized) {
                                    loadCurrentMapData();
                                }
                            }
                        }
                    } catch (error) {
                        console.warn('Configuration Preview: Could not parse SSE event data:', error);
                    }
                };
            }
            
            function disconnectSSE() {
                if (eventSource) {
                    console.log('Configuration Preview: Disconnecting SSE...');
                    eventSource.close();
                    eventSource = null;
                }
                
                if (reconnectTimeoutId) {
                    clearTimeout(reconnectTimeoutId);
                    reconnectTimeoutId = null;
                }
            }

            // Initialize current map by default
            initCurrentMap();
            
            
            // Start polling for preview status
            checkPreviewStatus();
            
            // Connect to SSE for real-time updates
            connectSSE();
            
            // Cleanup function for when the fragment is removed/replaced
            window.addEventListener('beforeunload', function() {
                disconnectSSE();
            });
            
            // Listen for htmx beforeSwap event to cleanup before DOM replacement
            document.addEventListener('htmx:beforeSwap', function(event) {
                // Check if the target contains our preview area
                if (event.detail.target && (
                    event.detail.target.id === 'preview-area' || 
                    event.detail.target.closest('#preview-area')
                )) {
                    console.log('Configuration Preview: Cleaning up SSE before DOM swap');
                    disconnectSSE();
                }
            });
            
            // Also disconnect when the page is hidden (e.g., tab switch)
            document.addEventListener('visibilitychange', function() {
                if (document.hidden) {
                    disconnectSSE();
                } else {
                    // Reconnect when page becomes visible again
                    connectSSE();
                }
            });
        })();
    </script>
    
    <style>
        .preview-controls {
            margin-bottom: 20px;
            display: flex;
            justify-content: space-between;
            align-items: center;
        }
        
        .date-selection {
            display: flex;
            align-items: center;
            gap: 8px;
        }
        
        .date-selection label {
            font-weight: 500;
            margin: 0;
        }
        
        .date-selection input[type="date"] {
            padding: 6px 10px;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-size: 0.9em;
        }
        
        .map-container {
            display: none;
        }
        
        .map-container.active {
            display: block;
        }
        
        .config-details {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
            margin-top: 10px;
        }
        
        .detail-group h5 {
            margin-bottom: 10px;
            color: #333;
        }
        
        .detail-group p {
            margin: 5px 0;
            font-size: 0.9em;
        }
        
        .map-with-timeline {
            display: flex;
            height: 600px;
        }
        
        .timeline-sidebar {
            width: 300px;
            border-right: none;
            overflow-y: auto;
            padding: 10px;
            flex-shrink: 0;
        }
        
        .map {
            flex: 1;
            border: 1px solid #ddd;
        }
        
        .timeline-content {
            font-size: 0.9em;
        }
        
        .timeline-entry {
            padding: 8px;
        }
        
        .timeline-entry:hover {
        }
        
        .entry-time {
            font-weight: bold;
            margin-bottom: 4px;
        }
        
        .place-name {
            margin-bottom: 2px;
        }
        
        .trip-info {
            margin-bottom: 2px;
        }
        
        .transport-mode {
            font-style: italic;
        }
        
        .distance {
            margin-left: 8px;
            font-weight: 500;
        }
        
        .entry-duration {
            font-size: 0.8em;
        }
        
        .loading, .error, .no-data {
            text-align: center;
            font-style: italic;
            padding: 20px;
        }
        
        .error {
            color: #d32f2f;
        }
    </style>
</div>
