// Mapbox Globe 6: Global University Rankings with Interactive Filtering
// Web-enhanced learning from: https://docs.mapbox.com/mapbox-gl-js/example/filter-markers/

// Mapbox access token
mapboxgl.accessToken = 'pk.eyJ1IjoibGludXhpc2Nvb2wiLCJhIjoiY2w3ajM1MnliMDV4NDNvb2J5c3V5dzRxZyJ9.wJukH5hVSiO74GM_VSJR3Q';

// Initialize map with globe projection
const map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/dark-v11',
    projection: 'globe',
    center: [0, 20],
    zoom: 1.5,
    pitch: 0
});

// Auto-rotation state
let userInteracting = false;
let rotationPaused = false;

// Current filter state
let currentFilters = {
    regions: ['all'],
    rankingRange: [1, 120],
    minPublications: 0,
    minCitations: 0,
    minFunding: 0,
    minNobelPrizes: 0
};

// Map load event
map.on('load', () => {
    // Configure globe atmosphere
    map.setFog({
        color: 'rgba(8, 16, 32, 0.95)',
        'high-color': 'rgba(25, 60, 120, 0.5)',
        'horizon-blend': 0.3,
        'space-color': '#000510',
        'star-intensity': 0.7
    });

    // Add data source
    map.addSource('universities', {
        type: 'geojson',
        data: universitiesData
    });

    // Layer 1: University circles (main visualization)
    map.addLayer({
        id: 'universities-layer',
        type: 'circle',
        source: 'universities',
        paint: {
            // Circle color based on research score (data-driven)
            'circle-color': [
                'interpolate',
                ['linear'],
                ['get', 'researchScore'],
                55, '#8b0000',    // Deep red - Lower scores
                65, '#dc143c',    // Crimson
                75, '#ff6347',    // Tomato red
                80, '#ffa500',    // Orange
                85, '#ffd700',    // Gold
                90, '#32cd32',    // Lime green
                95, '#00bfff',    // Deep sky blue
                99, '#0066ff'     // Royal blue - Top scores
            ],
            // Circle radius based on ranking (inverse - better rank = larger)
            'circle-radius': [
                'interpolate',
                ['linear'],
                ['get', 'ranking'],
                1, 18,      // Top rank = largest
                10, 14,
                25, 11,
                50, 9,
                75, 7,
                100, 5,
                120, 4      // Lower rank = smallest
            ],
            'circle-opacity': 0.85,
            'circle-stroke-width': 2,
            'circle-stroke-color': [
                'interpolate',
                ['linear'],
                ['get', 'researchScore'],
                55, '#ff4444',
                80, '#ffaa00',
                95, '#00ffff'
            ],
            'circle-stroke-opacity': 0.6
        }
    });

    // Layer 2: University labels (for top 30)
    map.addLayer({
        id: 'universities-labels',
        type: 'symbol',
        source: 'universities',
        filter: ['<=', ['get', 'ranking'], 30],  // Only show labels for top 30
        layout: {
            'text-field': ['get', 'name'],
            'text-font': ['Open Sans Regular'],
            'text-size': [
                'interpolate',
                ['linear'],
                ['get', 'ranking'],
                1, 13,
                10, 11,
                30, 9
            ],
            'text-offset': [0, 1.5],
            'text-anchor': 'top',
            'text-allow-overlap': false,
            'text-optional': true
        },
        paint: {
            'text-color': '#ffffff',
            'text-halo-color': '#000000',
            'text-halo-width': 2,
            'text-opacity': 0.9
        }
    });

    // Add navigation control
    map.addControl(new mapboxgl.NavigationControl(), 'bottom-right');

    // Setup popups
    setupPopups();

    // Setup filter controls
    setupFilterControls();

    // Start auto-rotation
    startAutoRotation();

    // Update statistics
    updateStatistics();
});

// Setup popup interactions
function setupPopups() {
    // Create popup
    const popup = new mapboxgl.Popup({
        closeButton: false,
        closeOnClick: false
    });

    // Mouse enter
    map.on('mouseenter', 'universities-layer', (e) => {
        map.getCanvas().style.cursor = 'pointer';

        const coords = e.features[0].geometry.coordinates.slice();
        const props = e.features[0].properties;

        const html = `
            <div style="padding: 8px; min-width: 250px;">
                <h3 style="margin: 0 0 8px 0; font-size: 14px; color: #00bfff;">
                    ${props.name}
                </h3>
                <div style="font-size: 12px; line-height: 1.6;">
                    <strong>Country:</strong> ${props.country}<br>
                    <strong>Region:</strong> ${props.region}<br>
                    <strong>Global Ranking:</strong> #${props.ranking}<br>
                    <strong>Research Score:</strong> ${props.researchScore}/100<br>
                    <hr style="margin: 6px 0; border: none; border-top: 1px solid #333;">
                    <strong>Publications:</strong> ${props.publications.toLocaleString()}<br>
                    <strong>Citations:</strong> ${props.citations.toLocaleString()}<br>
                    <strong>Research Funding:</strong> $${props.funding}M<br>
                    <strong>Nobel Prizes:</strong> ${props.nobelPrizes}
                </div>
            </div>
        `;

        popup.setLngLat(coords).setHTML(html).addTo(map);
    });

    // Mouse leave
    map.on('mouseleave', 'universities-layer', () => {
        map.getCanvas().style.cursor = '';
        popup.remove();
    });
}

// Setup filter controls (Web-enhanced from Mapbox filter-markers example)
function setupFilterControls() {
    // Region filter checkboxes
    const regionFilters = document.getElementById('region-filters');
    const regions = ['All', 'North America', 'Europe', 'Asia-Pacific', 'Middle East', 'Africa', 'Latin America'];

    regions.forEach((region, index) => {
        const checkbox = document.createElement('input');
        checkbox.type = 'checkbox';
        checkbox.id = `region-${index}`;
        checkbox.value = region;
        checkbox.checked = region === 'All';

        const label = document.createElement('label');
        label.htmlFor = `region-${index}`;
        label.textContent = region;

        const wrapper = document.createElement('div');
        wrapper.className = 'filter-item';
        wrapper.appendChild(checkbox);
        wrapper.appendChild(label);
        regionFilters.appendChild(wrapper);

        // Event listener using visibility control pattern from web source
        checkbox.addEventListener('change', () => {
            if (region === 'All') {
                // If "All" is checked, uncheck others
                if (checkbox.checked) {
                    regions.slice(1).forEach((_, i) => {
                        document.getElementById(`region-${i + 1}`).checked = false;
                    });
                }
            } else {
                // If any specific region is checked, uncheck "All"
                document.getElementById('region-0').checked = false;
            }
            applyFilters();
        });
    });

    // Ranking range slider
    const rankingSlider = document.getElementById('ranking-slider');
    const rankingValue = document.getElementById('ranking-value');

    rankingSlider.addEventListener('input', (e) => {
        currentFilters.rankingRange = [1, parseInt(e.target.value)];
        rankingValue.textContent = `Top ${e.target.value}`;
        applyFilters();
    });

    // Publications slider
    const pubsSlider = document.getElementById('publications-slider');
    const pubsValue = document.getElementById('publications-value');

    pubsSlider.addEventListener('input', (e) => {
        currentFilters.minPublications = parseInt(e.target.value);
        pubsValue.textContent = `≥${(parseInt(e.target.value) / 1000).toFixed(0)}K`;
        applyFilters();
    });

    // Citations slider
    const citationsSlider = document.getElementById('citations-slider');
    const citationsValue = document.getElementById('citations-value');

    citationsSlider.addEventListener('input', (e) => {
        currentFilters.minCitations = parseInt(e.target.value);
        citationsValue.textContent = `≥${(parseInt(e.target.value) / 1000).toFixed(0)}K`;
        applyFilters();
    });

    // Funding slider
    const fundingSlider = document.getElementById('funding-slider');
    const fundingValue = document.getElementById('funding-value');

    fundingSlider.addEventListener('input', (e) => {
        currentFilters.minFunding = parseInt(e.target.value);
        fundingValue.textContent = `≥$${e.target.value}M`;
        applyFilters();
    });

    // Nobel prize slider
    const nobelSlider = document.getElementById('nobel-slider');
    const nobelValue = document.getElementById('nobel-value');

    nobelSlider.addEventListener('input', (e) => {
        currentFilters.minNobelPrizes = parseInt(e.target.value);
        nobelValue.textContent = `≥${e.target.value}`;
        applyFilters();
    });

    // Reset button
    document.getElementById('reset-filters').addEventListener('click', () => {
        // Reset all checkboxes
        document.getElementById('region-0').checked = true;
        regions.slice(1).forEach((_, i) => {
            document.getElementById(`region-${i + 1}`).checked = false;
        });

        // Reset sliders
        rankingSlider.value = 120;
        pubsSlider.value = 0;
        citationsSlider.value = 0;
        fundingSlider.value = 0;
        nobelSlider.value = 0;

        // Reset filter state
        currentFilters = {
            regions: ['all'],
            rankingRange: [1, 120],
            minPublications: 0,
            minCitations: 0,
            minFunding: 0,
            minNobelPrizes: 0
        };

        // Update displays
        rankingValue.textContent = 'Top 120';
        pubsValue.textContent = '≥0K';
        citationsValue.textContent = '≥0K';
        fundingValue.textContent = '≥$0M';
        nobelValue.textContent = '≥0';

        applyFilters();
    });
}

// Apply filters using Mapbox filter expressions (learned from web source)
function applyFilters() {
    // Get selected regions
    const selectedRegions = [];
    const checkboxes = document.querySelectorAll('#region-filters input[type="checkbox"]:checked');

    checkboxes.forEach(cb => {
        if (cb.value === 'All') {
            selectedRegions.push('all');
        } else {
            selectedRegions.push(cb.value);
        }
    });

    // Build filter expression using 'all' operator to combine conditions
    let filterExpression = ['all'];

    // Region filter (using 'in' operator for multiple values)
    if (!selectedRegions.includes('all') && selectedRegions.length > 0) {
        filterExpression.push([
            'in',
            ['get', 'region'],
            ['literal', selectedRegions]
        ]);
    }

    // Ranking range filter
    filterExpression.push([
        '<=',
        ['get', 'ranking'],
        currentFilters.rankingRange[1]
    ]);

    // Publications filter
    if (currentFilters.minPublications > 0) {
        filterExpression.push([
            '>=',
            ['get', 'publications'],
            currentFilters.minPublications
        ]);
    }

    // Citations filter
    if (currentFilters.minCitations > 0) {
        filterExpression.push([
            '>=',
            ['get', 'citations'],
            currentFilters.minCitations
        ]);
    }

    // Funding filter
    if (currentFilters.minFunding > 0) {
        filterExpression.push([
            '>=',
            ['get', 'funding'],
            currentFilters.minFunding
        ]);
    }

    // Nobel prizes filter
    if (currentFilters.minNobelPrizes > 0) {
        filterExpression.push([
            '>=',
            ['get', 'nobelPrizes'],
            currentFilters.minNobelPrizes
        ]);
    }

    // Apply filter to layer using setFilter method (from web source)
    map.setFilter('universities-layer', filterExpression);

    // Also update labels layer to match
    const labelFilter = ['all', filterExpression, ['<=', ['get', 'ranking'], 30]];
    map.setFilter('universities-labels', labelFilter);

    // Update statistics with filtered data
    updateStatistics();
}

// Update statistics display
function updateStatistics() {
    // Get currently visible features
    const features = map.queryRenderedFeatures({ layers: ['universities-layer'] });

    if (features.length > 0) {
        const count = features.length;
        const avgResearch = (features.reduce((sum, f) => sum + f.properties.researchScore, 0) / count).toFixed(1);
        const totalPubs = features.reduce((sum, f) => sum + f.properties.publications, 0);
        const totalCitations = features.reduce((sum, f) => sum + f.properties.citations, 0);
        const totalNobel = features.reduce((sum, f) => sum + f.properties.nobelPrizes, 0);

        document.getElementById('stat-total').textContent = count;
        document.getElementById('stat-research').textContent = avgResearch;
        document.getElementById('stat-publications').textContent = (totalPubs / 1000).toFixed(1) + 'K';
        document.getElementById('stat-citations').textContent = (totalCitations / 1000000).toFixed(1) + 'M';
        document.getElementById('stat-nobel').textContent = totalNobel;
    }
}

// Auto-rotation logic
function startAutoRotation() {
    map.on('mousedown', () => { userInteracting = true; });
    map.on('mouseup', () => { userInteracting = false; });
    map.on('dragstart', () => { userInteracting = true; });
    map.on('dragend', () => { userInteracting = false; });
    map.on('pitchstart', () => { userInteracting = true; });
    map.on('pitchend', () => { userInteracting = false; });

    function rotateGlobe() {
        if (!userInteracting && !rotationPaused) {
            const center = map.getCenter();
            center.lng += 0.05;
            if (center.lng > 180) center.lng = -180;
            map.setCenter(center);
        }
        requestAnimationFrame(rotateGlobe);
    }

    rotateGlobe();
}

// Toggle rotation button
document.getElementById('toggle-rotation').addEventListener('click', () => {
    rotationPaused = !rotationPaused;
    const btn = document.getElementById('toggle-rotation');
    btn.textContent = rotationPaused ? 'Resume Rotation' : 'Pause Rotation';
});
