/**
 * CastConductor Analytics Dashboard
 * 
 * Main entry point for the analytics dashboard UI.
 * Uses Vanilla ES6 + Chart.js for visualization.
 * 
 * @package CastConductor
 * @since 5.8.0
 */

// Dashboard state
const state = {
    period: '7d',
    startDate: null,
    endDate: null,
    charts: {},
    loading: false,
    contentExcludeTypes: JSON.parse(localStorage.getItem('cc_analytics_content_filters') || '[]'),
    contentSearchTerm: '',
    contentData: null, // Cache for client-side filtering
    geoData: null,     // Cache geo data for map
    geoMap: null,      // Inline map instance
    geoModalMap: null, // Modal fullscreen map instance
};

// API helper
const api = {
    baseUrl: window.ccAnalyticsConfig?.apiBase || '/wp-json/castconductor/v5/analytics',
    nonce: window.ccAnalyticsConfig?.nonce || '',
    
    async fetch(endpoint, options = {}) {
        const url = new URL(`${this.baseUrl}${endpoint}`, window.location.origin);
        
        // Add period params
        url.searchParams.set('period', state.period);
        if (state.period === 'custom' && state.startDate && state.endDate) {
            url.searchParams.set('start_date', state.startDate);
            url.searchParams.set('end_date', state.endDate);
        }
        
        const response = await fetch(url, {
            ...options,
            headers: {
                'Content-Type': 'application/json',
                'X-WP-Nonce': this.nonce,
                ...options.headers,
            },
        });
        
        if (!response.ok) {
            const error = await response.json().catch(() => ({}));
            throw new Error(error.message || `API error: ${response.status}`);
        }
        
        return response.json();
    },
    
    async get(endpoint) {
        return this.fetch(endpoint);
    },
    
    async post(endpoint, body) {
        return this.fetch(endpoint, {
            method: 'POST',
            body: JSON.stringify(body),
        });
    },
};

// UI Helpers
const ui = {
    formatNumber(num) {
        if (num >= 1000000) return (num / 1000000).toFixed(1) + 'M';
        if (num >= 1000) return (num / 1000).toFixed(1) + 'K';
        return num.toString();
    },
    
    formatDuration(seconds) {
        if (seconds < 60) return `${Math.round(seconds)}s`;
        if (seconds < 3600) return `${Math.round(seconds / 60)}m`;
        const hours = Math.floor(seconds / 3600);
        const mins = Math.round((seconds % 3600) / 60);
        return `${hours}h ${mins}m`;
    },
    
    truncate(str, maxLength) {
        if (!str) return '';
        if (str.length <= maxLength) return str;
        return str.substring(0, maxLength - 1) + '…';
    },
    
    showLoading(container) {
        container.innerHTML = '<p class="cc-loading">Loading...</p>';
    },
    
    showError(container, message) {
        container.innerHTML = `<p class="cc-error">Error: ${message}</p>`;
    },
};

// Chart configuration
const chartConfig = {
    defaultColors: [
        '#2271b1', // WordPress blue
        '#00a32a', // Green
        '#d63638', // Red
        '#dba617', // Yellow
        '#3582c4', // Light blue
        '#9b51e0', // Purple
        '#00d4aa', // Teal
        '#ff6b6b', // Coral
    ],
    
    getLineChartOptions(title) {
        return {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    display: false,
                },
                tooltip: {
                    mode: 'index',
                    intersect: false,
                },
            },
            scales: {
                x: {
                    grid: {
                        display: false,
                    },
                },
                y: {
                    beginAtZero: true,
                    grid: {
                        color: 'rgba(0, 0, 0, 0.05)',
                    },
                },
            },
        };
    },
    
    getDoughnutOptions() {
        return {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: {
                    position: 'right',
                    labels: {
                        usePointStyle: true,
                        padding: 15,
                    },
                },
            },
        };
    },
};

// Initialize dashboard
async function init() {
    console.log('CastConductor Analytics Dashboard initializing...');
    
    // Setup event listeners
    setupEventListeners();
    
    // Initialize geo map functionality (if available)
    initGeoMap();
    
    // Load initial data
    await loadDashboard();
    
    // Load settings
    await loadSettings();
    
    // Auto-refresh active sessions every 30 seconds
    setInterval(async () => {
        try {
            const active = await api.get('/active');
            updateActiveSessions(active);
        } catch (e) {
            console.warn('Active sessions refresh failed:', e);
        }
    }, 30000);
}

// Setup event listeners
function setupEventListeners() {
    // Period selector buttons
    document.querySelectorAll('.cc-period-btn').forEach(btn => {
        btn.addEventListener('click', async (e) => {
            document.querySelectorAll('.cc-period-btn').forEach(b => b.classList.remove('active'));
            e.target.classList.add('active');
            
            state.period = e.target.dataset.period;
            
            // Show/hide custom date inputs
            const customDates = document.querySelector('.cc-custom-dates');
            if (state.period === 'custom') {
                customDates.style.display = 'flex';
            } else {
                customDates.style.display = 'none';
                await loadDashboard();
            }
        });
    });
    
    // Apply custom dates
    document.getElementById('cc-apply-dates')?.addEventListener('click', async () => {
        state.startDate = document.getElementById('cc-start-date').value;
        state.endDate = document.getElementById('cc-end-date').value;
        
        if (state.startDate && state.endDate) {
            await loadDashboard();
        }
    });
    
    // Refresh button
    document.getElementById('cc-refresh')?.addEventListener('click', () => {
        loadDashboard();
    });
    
    // Export CSV button
    document.getElementById('cc-export-csv')?.addEventListener('click', async () => {
        try {
            const data = await api.get('/export/csv?type=summary');
            if (data.success && data.content) {
                downloadCSV(data.content, data.filename);
            }
        } catch (error) {
            console.error('Export failed:', error);
            alert('Export failed: ' + error.message);
        }
    });
    
    // Run aggregation button
    document.getElementById('run-aggregation')?.addEventListener('click', async () => {
        const btn = document.getElementById('run-aggregation');
        btn.disabled = true;
        btn.textContent = 'Running...';
        
        try {
            await api.post('/aggregate', {});
            await loadSettings();
            alert('Aggregation completed successfully!');
        } catch (error) {
            alert('Aggregation failed: ' + error.message);
        } finally {
            btn.disabled = false;
            btn.innerHTML = '<span class="dashicons dashicons-update"></span> Run Aggregation Now';
        }
    });
    
    // Save retention settings
    document.getElementById('save-retention')?.addEventListener('click', async () => {
        const retention = {
            raw_events: parseInt(document.getElementById('retention-raw-events').value),
            sessions: parseInt(document.getElementById('retention-sessions').value),
            hourly: parseInt(document.getElementById('retention-hourly').value),
        };
        
        try {
            await api.post('/settings', { retention });
            alert('Retention settings saved!');
        } catch (error) {
            alert('Failed to save settings: ' + error.message);
        }
    });
    
    // Save collection settings
    document.getElementById('save-collection')?.addEventListener('click', async () => {
        const container = document.getElementById('collection-settings');
        if (!container) return;
        
        const collection = {};
        container.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
            collection[checkbox.dataset.type] = checkbox.checked;
        });
        
        try {
            await api.post('/settings', { collection });
            alert('Collection settings saved! Changes apply to new events only.');
        } catch (error) {
            alert('Failed to save settings: ' + error.message);
        }
    });
    
    // Tab switching removed - Promotional Performance widget consolidated into Content Performance
    // Content type filters now provide the same filtering capability
}

// Load all dashboard data
async function loadDashboard() {
    state.loading = true;
    
    try {
        // Load summary
        const summary = await api.get('/summary');
        updateSummaryCards(summary);
        updateSessionsChart(summary.trends);
        
        // Load device breakdown
        const devices = await api.get('/devices');
        updateDevicesChart(devices);
        
        // Load content performance (with persisted filter preferences)
        const excludeParam = (state.contentExcludeTypes || []).join(',');
        const content = await api.get(`/content${excludeParam ? `?exclude_types=${excludeParam}` : ''}`);
        updateContentTable(content);
        
        // Load geo data if available
        if (window.ccAnalyticsConfig?.features?.includes('geo_heatmap')) {
            const geo = await api.get('/geo');
            updateGeoData(geo);
        }
        
        // Sponsor data loading removed - consolidated into Content Performance widget
        // Use type filters in Content Performance to view sponsors, promos, etc.
        
        // Load active sessions (always available)
        const active = await api.get('/active');
        updateActiveSessions(active);
        
    } catch (error) {
        console.error('Failed to load dashboard:', error);
    } finally {
        state.loading = false;
    }
}

// Update summary cards
function updateSummaryCards(data) {
    const summary = data.summary || {};
    
    document.getElementById('total-sessions').textContent = 
        ui.formatNumber(summary.total_sessions || 0);
    
    document.getElementById('unique-devices').textContent = 
        ui.formatNumber(summary.unique_devices || 0);
    
    document.getElementById('avg-duration').textContent = 
        ui.formatDuration(summary.avg_duration || 0);
    
    document.getElementById('total-views').textContent = 
        ui.formatNumber(summary.total_scene_views || 0);
}

// Update sessions chart
function updateSessionsChart(trends) {
    const canvas = document.getElementById('sessions-chart');
    if (!canvas) return;
    
    const sessions = trends?.sessions || [];
    
    // Destroy existing chart
    if (state.charts.sessions) {
        state.charts.sessions.destroy();
    }
    
    state.charts.sessions = new Chart(canvas, {
        type: 'line',
        data: {
            labels: sessions.map(s => s.date),
            datasets: [{
                label: 'Sessions',
                data: sessions.map(s => s.count_value || 0),
                borderColor: chartConfig.defaultColors[0],
                backgroundColor: chartConfig.defaultColors[0] + '20',
                fill: true,
                tension: 0.3,
            }],
        },
        options: chartConfig.getLineChartOptions('Sessions'),
    });
}

// Update devices chart
function updateDevicesChart(data) {
    const canvas = document.getElementById('devices-chart');
    if (!canvas) return;
    
    const devices = data?.devices || [];
    
    // Destroy existing chart
    if (state.charts.devices) {
        state.charts.devices.destroy();
    }
    
    // Limit to top 8 devices
    const topDevices = devices.slice(0, 8);
    
    state.charts.devices = new Chart(canvas, {
        type: 'doughnut',
        data: {
            labels: topDevices.map(d => d.device_model || 'Unknown'),
            datasets: [{
                data: topDevices.map(d => d.session_count || 0),
                backgroundColor: chartConfig.defaultColors,
            }],
        },
        options: chartConfig.getDoughnutOptions(),
    });
}

// Update content table with filter toggles and search
function updateContentTable(data) {
    const tbody = document.getElementById('content-table-body');
    const filtersContainer = document.getElementById('content-type-filters');
    const searchInput = document.getElementById('content-search');
    const clearButton = document.getElementById('content-search-clear');
    
    // Cache the full data for client-side filtering
    state.contentData = data;
    
    // Set up search functionality
    if (searchInput && !searchInput.hasAttribute('data-initialized')) {
        searchInput.setAttribute('data-initialized', 'true');
        
        // Debounced search
        let searchTimeout;
        searchInput.addEventListener('input', (e) => {
            clearTimeout(searchTimeout);
            searchTimeout = setTimeout(() => {
                state.contentSearchTerm = e.target.value.toLowerCase().trim();
                if (clearButton) clearButton.style.display = state.contentSearchTerm ? 'inline-block' : 'none';
                applyContentFilters();
            }, 200);
        });
        
        // Clear button
        if (clearButton) {
            clearButton.addEventListener('click', () => {
                searchInput.value = '';
                state.contentSearchTerm = '';
                clearButton.style.display = 'none';
                applyContentFilters();
            });
        }
    }
    
    // Build filter toggles from available types
    if (filtersContainer) {
        const availableTypes = data?.available_types || [];
        const excludedTypes = state.contentExcludeTypes || [];
        
        if (availableTypes.length > 0) {
            filtersContainer.innerHTML = availableTypes.map(type => {
                const isChecked = !excludedTypes.includes(type);
                const label = type.replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());
                return `
                    <label class="cc-filter-toggle">
                        <input type="checkbox" data-type="${type}" ${isChecked ? 'checked' : ''}>
                        ${label}
                    </label>
                `;
            }).join('');
            
            // Add event listeners for filter toggles
            filtersContainer.querySelectorAll('input[type="checkbox"]').forEach(checkbox => {
                checkbox.addEventListener('change', async () => {
                    // Update excluded types
                    const type = checkbox.dataset.type;
                    if (checkbox.checked) {
                        state.contentExcludeTypes = (state.contentExcludeTypes || []).filter(t => t !== type);
                    } else {
                        state.contentExcludeTypes = [...(state.contentExcludeTypes || []), type];
                    }
                    
                    // Persist filter preferences to localStorage
                    localStorage.setItem('cc_analytics_content_filters', JSON.stringify(state.contentExcludeTypes));
                    
                    // Apply filters client-side (faster)
                    applyContentFilters();
                });
            });
        } else {
            filtersContainer.innerHTML = '<span class="cc-filter-hint">No filter options available yet</span>';
        }
    }
    
    applyContentFilters();
}

// Apply both type and search filters to content data
function applyContentFilters() {
    if (!state.contentData) return;
    
    let content = state.contentData?.top_content || [];
    
    // Filter by excluded types
    if (state.contentExcludeTypes.length > 0) {
        content = content.filter(item => !state.contentExcludeTypes.includes(item.content_type));
    }
    
    // Filter by search term
    if (state.contentSearchTerm) {
        content = content.filter(item => {
            const name = (item.content_name || '').toLowerCase();
            const type = (item.content_type || '').toLowerCase();
            return name.includes(state.contentSearchTerm) || type.includes(state.contentSearchTerm);
        });
    }
    
    updateContentTableRowsFiltered(content);
}

// Helper to update just the table rows with pre-filtered data
function updateContentTableRowsFiltered(content) {
    const tbody = document.getElementById('content-table-body');
    if (!tbody) return;
    
    if (content.length === 0) {
        tbody.innerHTML = '<tr><td colspan="5">No matching content found</td></tr>';
        return;
    }
    
    tbody.innerHTML = content.slice(0, 50).map(item => {
        const displayName = item.content_name || item.content_type || `Content #${item.content_id}`;
        const typeLabel = (item.content_type || 'unknown').replace(/_/g, ' ');
        const qrScans = item.total_qr_scans || 0;
        const searchTerm = state.contentSearchTerm;
        
        // Highlight search match
        let highlightedName = ui.truncate(displayName, 40);
        if (searchTerm && displayName.toLowerCase().includes(searchTerm)) {
            const regex = new RegExp(`(${searchTerm})`, 'gi');
            highlightedName = highlightedName.replace(regex, '<mark>$1</mark>');
        }
        
        return `
            <tr>
                <td title="${displayName}">${highlightedName}</td>
                <td><span class="cc-type-badge cc-type-${item.content_type || 'unknown'}">${typeLabel}</span></td>
                <td>${ui.formatNumber(item.total_impressions || item.total_plays || 0)}</td>
                <td>${ui.formatNumber(item.unique_viewers || 0)}</td>
                <td>${qrScans > 0 ? ui.formatNumber(qrScans) : '—'}</td>
            </tr>
        `;
    }).join('');
}

// Update geographic data with proper tables and map
function updateGeoData(data) {
    // Store geo data for map use
    state.geoData = data;
    
    // Update countries table
    const countriesBody = document.getElementById('geo-countries-body');
    if (countriesBody) {
        const countries = data?.countries || [];
        if (countries.length === 0) {
            countriesBody.innerHTML = '<tr><td colspan="3" class="cc-empty-state">No country data yet</td></tr>';
        } else {
            countriesBody.innerHTML = countries.slice(0, 10).map(c => `
                <tr>
                    <td><span class="cc-country-flag">${getCountryFlag(c.country_code)}</span> ${getCountryName(c.country_code)}</td>
                    <td>${ui.formatNumber(c.session_count || 0)}</td>
                    <td>${ui.formatNumber(c.unique_devices || 0)}</td>
                </tr>
            `).join('');
        }
    }
    
    // Update cities table
    const citiesBody = document.getElementById('geo-cities-body');
    if (citiesBody) {
        const cities = data?.cities || [];
        if (cities.length === 0) {
            citiesBody.innerHTML = '<tr><td colspan="3" class="cc-empty-state">No city data yet</td></tr>';
        } else {
            citiesBody.innerHTML = cities.slice(0, 10).map(c => `
                <tr>
                    <td>${c.city || 'Unknown'}</td>
                    <td><span class="cc-country-flag">${getCountryFlag(c.country_code)}</span> ${c.country_code || '—'}</td>
                    <td>${ui.formatNumber(c.session_count || 0)}</td>
                </tr>
            `).join('');
        }
    }
    
    // Update DMA table
    const dmasBody = document.getElementById('geo-dmas-body');
    if (dmasBody) {
        const dmas = data?.dmas || [];
        if (dmas.length === 0) {
            dmasBody.innerHTML = '<tr><td colspan="3" class="cc-empty-state">No DMA data yet</td></tr>';
        } else {
            dmasBody.innerHTML = dmas.slice(0, 10).map(d => `
                <tr>
                    <td>${getDmaName(d.dma_code)}</td>
                    <td>${ui.formatNumber(d.session_count || 0)}</td>
                    <td>${ui.formatNumber(d.unique_devices || 0)}</td>
                </tr>
            `).join('');
        }
    }
}

// Get country flag emoji from country code
function getCountryFlag(code) {
    if (!code || code.length !== 2) return '🌍';
    const codePoints = code.toUpperCase().split('').map(c => 127397 + c.charCodeAt(0));
    return String.fromCodePoint(...codePoints);
}

// Get country name from code (common countries, fallback to code)
function getCountryName(code) {
    const countries = {
        'US': 'United States', 'CA': 'Canada', 'GB': 'United Kingdom', 'UK': 'United Kingdom',
        'DE': 'Germany', 'FR': 'France', 'AU': 'Australia', 'JP': 'Japan', 'BR': 'Brazil',
        'MX': 'Mexico', 'IN': 'India', 'IT': 'Italy', 'ES': 'Spain', 'NL': 'Netherlands',
        'PL': 'Poland', 'SE': 'Sweden', 'CH': 'Switzerland', 'AT': 'Austria', 'BE': 'Belgium',
    };
    return countries[code?.toUpperCase()] || code || 'Unknown';
}

// Get DMA market name from code (top US markets)
function getDmaName(code) {
    const dmas = {
        '501': 'New York, NY', '803': 'Los Angeles, CA', '602': 'Chicago, IL',
        '504': 'Philadelphia, PA', '807': 'San Francisco, CA', '623': 'Dallas, TX',
        '511': 'Washington, DC', '539': 'Tampa, FL', '528': 'Miami, FL',
        '524': 'Atlanta, GA', '506': 'Boston, MA', '753': 'Phoenix, AZ',
        '819': 'Seattle, WA', '505': 'Detroit, MI', '613': 'Minneapolis, MN',
        '534': 'Orlando, FL', '751': 'Denver, CO', '510': 'Cleveland, OH',
        '618': 'Houston, TX', '641': 'San Antonio, TX', '825': 'San Diego, CA',
    };
    return dmas[code] || `DMA ${code}`;
}

// Initialize map functionality
function initGeoMap() {
    if (typeof L === 'undefined') return; // Leaflet not loaded
    
    const mapToggle = document.getElementById('cc-geo-map-toggle');
    const mapContainer = document.getElementById('cc-geo-map-container');
    const fullscreenBtn = document.getElementById('cc-geo-fullscreen');
    const modal = document.getElementById('cc-geo-modal');
    const modalClose = document.getElementById('cc-geo-modal-close');
    
    if (!mapToggle || !mapContainer) return;
    
    // Toggle map visibility
    mapToggle.addEventListener('click', () => {
        const isHidden = mapContainer.style.display === 'none';
        mapContainer.style.display = isHidden ? 'block' : 'none';
        mapToggle.innerHTML = isHidden 
            ? '<span class="dashicons dashicons-location-alt"></span> Hide Map'
            : '<span class="dashicons dashicons-location-alt"></span> Show Map';
        
        if (isHidden && !state.geoMap) {
            initMapInstance('cc-geo-map', false);
        }
    });
    
    // Fullscreen button
    if (fullscreenBtn && modal) {
        fullscreenBtn.addEventListener('click', () => {
            modal.style.display = 'flex';
            document.body.style.overflow = 'hidden';
            if (!state.geoModalMap) {
                setTimeout(() => initMapInstance('cc-geo-modal-map', true), 100);
            } else {
                state.geoModalMap.invalidateSize();
                updateMapPins(state.geoModalMap, true);
            }
        });
    }
    
    // Close modal
    if (modalClose && modal) {
        modalClose.addEventListener('click', closeGeoModal);
        modal.addEventListener('click', (e) => {
            if (e.target === modal) closeGeoModal();
        });
    }
    
    // ESC key to close modal
    document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape' && modal?.style.display === 'flex') {
            closeGeoModal();
        }
    });
    
    // Overlay toggles
    setupOverlayToggles();
}

function closeGeoModal() {
    const modal = document.getElementById('cc-geo-modal');
    if (modal) {
        modal.style.display = 'none';
        document.body.style.overflow = '';
    }
}

function initMapInstance(containerId, isModal) {
    const container = document.getElementById(containerId);
    if (!container) return;
    
    // Fullscreen modal: world view (zoom 2), inline: US view (zoom 4)
    const defaultZoom = isModal ? 2 : 4;
    const defaultCenter = isModal ? [30, 0] : [39.8283, -98.5795]; // World center vs US center
    
    const map = L.map(containerId, {
        minZoom: 2,
        maxZoom: 18,
        worldCopyJump: true,
    }).setView(defaultCenter, defaultZoom);
    
    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap contributors',
        maxZoom: 18,
    }).addTo(map);
    
    if (isModal) {
        state.geoModalMap = map;
    } else {
        state.geoMap = map;
    }
    
    updateMapPins(map, isModal);
}

function updateMapPins(map, isModal = false) {
    if (!map || !state.geoData) return;
    
    // Clear existing layers (markers, labels)
    map.eachLayer(layer => {
        if (layer instanceof L.Marker || layer instanceof L.CircleMarker || layer._isStatLabel) {
            map.removeLayer(layer);
        }
    });
    
    const cities = state.geoData.cities || [];
    const bounds = [];
    
    // Check if stat labels should be shown (modal only, or toggle enabled)
    const showStatLabels = isModal || document.getElementById('cc-overlay-sessions')?.checked;
    
    // Simple city-to-coordinate lookup (expandable)
    const cityCoords = {
        'Los Angeles': [34.0522, -118.2437],
        'New York': [40.7128, -74.0060],
        'Chicago': [41.8781, -87.6298],
        'Houston': [29.7604, -95.3698],
        'Phoenix': [33.4484, -112.0740],
        'Philadelphia': [39.9526, -75.1652],
        'San Antonio': [29.4241, -98.4936],
        'San Diego': [32.7157, -117.1611],
        'Dallas': [32.7767, -96.7970],
        'San Jose': [37.3382, -121.8863],
        'Austin': [30.2672, -97.7431],
        'San Francisco': [37.7749, -122.4194],
        'Seattle': [47.6062, -122.3321],
        'Denver': [39.7392, -104.9903],
        'Miami': [25.7617, -80.1918],
        'Atlanta': [33.7490, -84.3880],
        'Boston': [42.3601, -71.0589],
        'Las Vegas': [36.1699, -115.1398],
        'Portland': [45.5152, -122.6784],
        'Detroit': [42.3314, -83.0458],
        // International cities
        'London': [51.5074, -0.1278],
        'Paris': [48.8566, 2.3522],
        'Berlin': [52.5200, 13.4050],
        'Tokyo': [35.6762, 139.6503],
        'Sydney': [-33.8688, 151.2093],
        'Toronto': [43.6532, -79.3832],
        'Vancouver': [49.2827, -123.1207],
        'Mexico City': [19.4326, -99.1332],
        'São Paulo': [-23.5505, -46.6333],
        'Mumbai': [19.0760, 72.8777],
    };
    
    // Find max sessions for scaling
    const maxSessions = Math.max(...cities.map(c => c.session_count || 1), 1);
    
    cities.forEach(city => {
        const coords = cityCoords[city.city];
        if (coords) {
            // Scale marker size based on sessions (min 8, max 30)
            const scale = (city.session_count || 1) / maxSessions;
            const radius = Math.max(8, Math.min(30, 8 + scale * 22));
            
            const marker = L.circleMarker(coords, {
                radius: radius,
                fillColor: '#0073aa',
                color: '#005a87',
                weight: 2,
                opacity: 0.9,
                fillOpacity: 0.6,
            }).addTo(map);
            
            marker.bindPopup(`
                <strong>${city.city}</strong><br>
                ${getCountryFlag(city.country_code)} ${city.country_code}<br>
                <b>Sessions:</b> ${ui.formatNumber(city.session_count || 0)}<br>
                <b>Devices:</b> ${ui.formatNumber(city.unique_devices || 0)}
            `);
            
            // Add stat label overlay for infographic view
            if (showStatLabels && (city.session_count || 0) > 0) {
                const label = L.divIcon({
                    className: 'cc-map-stat-label',
                    html: `<div class="cc-stat-bubble">
                        <span class="cc-stat-city">${city.city}</span>
                        <span class="cc-stat-count">${ui.formatNumber(city.session_count || 0)}</span>
                    </div>`,
                    iconSize: [100, 40],
                    iconAnchor: [50, -5], // Position above the marker
                });
                const labelMarker = L.marker(coords, { icon: label }).addTo(map);
                labelMarker._isStatLabel = true; // Tag for cleanup
            }
            
            bounds.push(coords);
        }
    });
    
    // For inline map, fit to markers with constrained zoom
    // For modal (world view), keep the wide view unless only 1 city
    if (bounds.length > 0 && !isModal) {
        map.fitBounds(bounds, { padding: [50, 50], maxZoom: 6 });
    } else if (bounds.length === 1 && isModal) {
        // Single city: zoom in a bit
        map.setView(bounds[0], 5);
    }
    // For modal with multiple cities, keep the world/country view for infographic effect
}

function setupOverlayToggles() {
    // Inline map overlay toggles
    const sessionsToggle = document.getElementById('cc-overlay-sessions');
    const heatmapToggle = document.getElementById('cc-overlay-heatmap');
    
    if (sessionsToggle) {
        sessionsToggle.addEventListener('change', () => {
            if (state.geoMap) updateMapPins(state.geoMap, false);
        });
    }
    
    if (heatmapToggle) {
        heatmapToggle.addEventListener('change', () => {
            // Heatmap toggle - future enhancement
            console.log('Heatmap toggle:', heatmapToggle.checked);
        });
    }
    
    // Modal overlay toggles
    const modalSessionsToggle = document.getElementById('cc-modal-overlay-sessions');
    const modalHeatmapToggle = document.getElementById('cc-modal-overlay-heatmap');
    
    if (modalSessionsToggle) {
        modalSessionsToggle.addEventListener('change', () => {
            if (state.geoModalMap) updateMapPins(state.geoModalMap, true);
        });
    }
}

// Update active sessions table
function updateActiveSessions(data) {
    const tbody = document.getElementById('active-sessions-body');
    const badge = document.getElementById('active-count-badge');
    
    if (badge) {
        badge.textContent = data?.active_count || 0;
    }
    
    if (!tbody) return;
    
    const sessions = data?.sessions || [];
    
    if (sessions.length === 0) {
        tbody.innerHTML = '<tr><td colspan="7" class="cc-empty-state">No active sessions</td></tr>';
        return;
    }
    
    // Use server time for accurate duration (avoids client timezone issues)
    const serverTime = data?.server_time ? new Date(data.server_time) : new Date();
    
    tbody.innerHTML = sessions.map(s => {
        // Calculate live duration - started_at is UTC, append Z if missing
        const startedAtUtc = s.started_at.includes('Z') || s.started_at.includes('+') 
            ? s.started_at 
            : s.started_at.replace(' ', 'T') + 'Z';
        const startTime = new Date(startedAtUtc);
        const durationMs = serverTime - startTime;
        const durationMins = Math.floor(durationMs / 60000);
        const durationSecs = Math.floor((durationMs % 60000) / 1000);
        const durationStr = durationMins > 0 
            ? `${durationMins}m ${durationSecs}s` 
            : `${durationSecs}s`;
        
        return `
            <tr>
                <td title="${s.device_id_hash}">${(s.device_id_hash || '').substring(0, 8)}…</td>
                <td>${s.device_model || 'Unknown'}</td>
                <td>${s.city || '—'}</td>
                <td>${s.country_code || '—'}</td>
                <td>${s.zip_code || '—'}</td>
                <td>${durationStr}</td>
                <td>${s.current_scene_name || '—'}</td>
            </tr>
        `;
    }).join('');
}

// updateSponsorsTable removed in v5.8.0
// Promotional Performance widget consolidated into Content Performance
// All content blocks (sponsors, promos, shoutouts) now shown in unified table with type filters

// Load settings
async function loadSettings() {
    try {
        const settings = await api.get('/settings');
        
        // Update retention dropdowns
        const rawEvents = document.getElementById('retention-raw-events');
        const sessions = document.getElementById('retention-sessions');
        const hourly = document.getElementById('retention-hourly');
        
        if (rawEvents) rawEvents.value = settings.retention?.raw_events || 7;
        if (sessions) sessions.value = settings.retention?.sessions || 30;
        if (hourly) hourly.value = settings.retention?.hourly || 90;
        
        // Update collection settings toggles
        const collectionContainer = document.getElementById('collection-settings');
        if (collectionContainer && settings.collection) {
            const types = Object.entries(settings.collection);
            if (types.length > 0) {
                collectionContainer.innerHTML = types.map(([type, info]) => `
                    <label class="cc-collection-toggle">
                        <input type="checkbox" data-type="${type}" ${info.enabled ? 'checked' : ''}>
                        <span class="cc-toggle-label">${info.label}</span>
                        <span class="cc-toggle-desc">${info.description}</span>
                    </label>
                `).join('');
            } else {
                collectionContainer.innerHTML = '<p>No content types configured</p>';
            }
        }
        
        // Update status
        document.getElementById('last-hourly').textContent = 
            settings.last_hourly_aggregation || 'Never';
        document.getElementById('last-daily').textContent = 
            settings.last_daily_aggregation || 'Never';
        document.getElementById('last-prune').textContent = 
            settings.last_prune || 'Never';
            
    } catch (error) {
        console.error('Failed to load settings:', error);
    }
}

// Download CSV helper
function downloadCSV(base64Content, filename) {
    const content = atob(base64Content);
    const blob = new Blob([content], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
}

// Initialize on DOM ready
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
} else {
    init();
}
