// Mapbox Globe Iteration 9: Global Educational Funding Choropleth
// Applying choropleth techniques learned from Mapbox documentation

// 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: [20, 20],
    zoom: 1.8,
    pitch: 0
});

// Data processing: calculate funding metrics
const processedData = educationalFundingData.features.map(feature => {
    const props = feature.properties;
    return {
        ...feature,
        properties: {
            ...props,
            fundingGap: props.spendingPerCapita < 500 ? 'Critical' :
                        props.spendingPerCapita < 1000 ? 'High' :
                        props.spendingPerCapita < 2000 ? 'Moderate' : 'Low',
            efficiency: props.spendingPerCapita > 0 ?
                       (props.educationIndex / (props.spendingPerCapita / 1000)).toFixed(2) : 0,
            salaryGap: props.avgTeacherSalary < 10000 ? 'Low' :
                      props.avgTeacherSalary < 30000 ? 'Medium' :
                      props.avgTeacherSalary < 50000 ? 'Good' : 'High'
        }
    };
});

// Country rankings by spending
const countryRankings = [...processedData].sort(
    (a, b) => b.properties.spendingPerCapita - a.properties.spendingPerCapita
);

// Statistics
const stats = {
    avgSpending: processedData.reduce((sum, f) => sum + f.properties.spendingPerCapita, 0) / processedData.length,
    maxSpending: Math.max(...processedData.map(f => f.properties.spendingPerCapita)),
    minSpending: Math.min(...processedData.map(f => f.properties.spendingPerCapita)),
    totalCenters: trainingCentersData.features.length,
    avgTeacherSalary: processedData.reduce((sum, f) => sum + f.properties.avgTeacherSalary, 0) / processedData.length
};

// Update info panel
document.getElementById('avg-spending').textContent = `$${stats.avgSpending.toFixed(0)}`;
document.getElementById('total-countries').textContent = processedData.length;
document.getElementById('total-centers').textContent = stats.totalCenters;
document.getElementById('avg-salary').textContent = `$${stats.avgTeacherSalary.toFixed(0)}`;

map.on('load', () => {
    // Configure globe atmosphere
    map.setFog({
        color: 'rgba(10, 15, 35, 0.9)',
        'high-color': 'rgba(25, 50, 100, 0.5)',
        'horizon-blend': 0.3,
        'space-color': '#000814',
        'star-intensity': 0.7
    });

    // Add country polygons source from Mapbox
    // We'll use a custom source with our data for choropleth
    map.addSource('countries', {
        type: 'vector',
        url: 'mapbox://mapbox.country-boundaries-v1'
    });

    // Create a lookup map for quick access to country data
    const countryDataMap = new Map();
    processedData.forEach(feature => {
        countryDataMap.set(feature.properties.iso, feature.properties);
    });

    // Add choropleth fill layer using data-driven styling
    // Technique learned from Mapbox documentation: interpolate expression for continuous color scaling
    map.addLayer({
        'id': 'country-choropleth',
        'type': 'fill',
        'source': 'countries',
        'source-layer': 'country_boundaries',
        'paint': {
            // Choropleth fill-color using interpolate expression
            // This creates a smooth color gradient based on data values
            'fill-color': [
                'case',
                ['has', 'iso_3166_1'],
                [
                    'interpolate',
                    ['linear'],
                    // Access spending data by matching ISO codes
                    ['get', 'spendingPerCapita', ['literal', Object.fromEntries(countryDataMap)]],
                    0, '#440154',      // Very low - deep purple
                    500, '#31688e',    // Low - blue
                    1000, '#35b779',   // Medium - green
                    2000, '#fde724',   // High - yellow
                    5000, '#fde724'    // Very high - bright yellow
                ],
                '#1a1a1a' // Default for countries without data
            ],
            'fill-opacity': 0.8
        }
    }, 'admin-1-boundary-bg');

    // However, the above approach won't work directly because we can't join external data to vector tiles easily
    // Let's use a different approach: convert our point data to a GeoJSON with polygons
    // For this iteration, we'll create country fills from our point data

    // Add educational funding data source (points)
    map.addSource('education-data', {
        type: 'geojson',
        data: {
            type: 'FeatureCollection',
            features: processedData
        }
    });

    // Add circle layer with size based on spending
    map.addLayer({
        'id': 'education-circles',
        'type': 'circle',
        'source': 'education-data',
        'paint': {
            // Circle radius based on spending per capita
            'circle-radius': [
                'interpolate',
                ['linear'],
                ['get', 'spendingPerCapita'],
                0, 3,
                500, 8,
                1000, 12,
                2000, 18,
                5000, 25
            ],
            // Choropleth-style color using interpolate (learned technique)
            'circle-color': [
                'interpolate',
                ['linear'],
                ['get', 'spendingPerCapita'],
                0, '#440154',      // Very low - deep purple (viridis scale)
                500, '#31688e',    // Low - blue
                1000, '#35b779',   // Medium - green
                2000, '#fde724',   // High - yellow
                5000, '#fde724'    // Very high - bright yellow
            ],
            'circle-opacity': 0.85,
            'circle-stroke-width': 2,
            'circle-stroke-color': [
                'interpolate',
                ['linear'],
                ['get', 'educationIndex'],
                0.3, '#ff0000',    // Low quality - red
                0.6, '#ffaa00',    // Medium quality - orange
                0.8, '#00ff00'     // High quality - green
            ],
            'circle-stroke-opacity': 0.9
        }
    });

    // Add teacher training centers
    map.addSource('training-centers', {
        type: 'geojson',
        data: trainingCentersData
    });

    // Training centers as small points
    map.addLayer({
        'id': 'training-centers-layer',
        'type': 'circle',
        'source': 'training-centers',
        'paint': {
            'circle-radius': 4,
            'circle-color': '#ff6b6b',
            'circle-opacity': 0.7,
            'circle-stroke-width': 1,
            'circle-stroke-color': '#ffffff',
            'circle-stroke-opacity': 0.8
        }
    });

    // Add halo effect for training centers
    map.addLayer({
        'id': 'training-centers-halo',
        'type': 'circle',
        'source': 'training-centers',
        'paint': {
            'circle-radius': 8,
            'circle-color': '#ff6b6b',
            'circle-opacity': 0.2,
            'circle-blur': 0.8
        }
    }, 'training-centers-layer');

    // Country labels layer
    map.addLayer({
        'id': 'country-labels',
        'type': 'symbol',
        'source': 'education-data',
        'layout': {
            'text-field': ['get', 'country'],
            'text-size': 11,
            'text-offset': [0, 2],
            'text-anchor': 'top',
            'text-optional': true
        },
        'paint': {
            'text-color': '#ffffff',
            'text-halo-color': '#000000',
            'text-halo-width': 1.5,
            'text-opacity': [
                'interpolate',
                ['linear'],
                ['zoom'],
                1.5, 0,
                2.5, 0.7
            ]
        }
    });

    // Create popup
    const popup = new mapboxgl.Popup({
        closeButton: false,
        closeOnClick: false,
        maxWidth: '350px'
    });

    // Hover interaction for countries
    map.on('mousemove', 'education-circles', (e) => {
        map.getCanvas().style.cursor = 'pointer';

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

        // Calculate additional metrics
        const fundingRank = countryRankings.findIndex(f => f.properties.country === props.country) + 1;
        const percentOfMax = ((props.spendingPerCapita / stats.maxSpending) * 100).toFixed(1);

        const html = `
            <div style="padding: 8px; font-family: 'Inter', sans-serif;">
                <h3 style="margin: 0 0 10px 0; color: #fde724; font-size: 16px; font-weight: 600;">
                    ${props.country}
                </h3>
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 8px; font-size: 12px;">
                    <div>
                        <div style="color: #aaa; margin-bottom: 2px;">Spending/Capita</div>
                        <div style="color: #fff; font-weight: 600; font-size: 14px;">$${props.spendingPerCapita}</div>
                        <div style="color: #888; font-size: 10px;">Rank: #${fundingRank} (${percentOfMax}% of max)</div>
                    </div>
                    <div>
                        <div style="color: #aaa; margin-bottom: 2px;">Budget %</div>
                        <div style="color: #fff; font-weight: 600; font-size: 14px;">${props.budgetPercent}%</div>
                    </div>
                    <div>
                        <div style="color: #aaa; margin-bottom: 2px;">Avg Teacher Salary</div>
                        <div style="color: #fff; font-weight: 600;">$${props.avgTeacherSalary.toLocaleString()}</div>
                    </div>
                    <div>
                        <div style="color: #aaa; margin-bottom: 2px;">Teacher:Student</div>
                        <div style="color: #fff; font-weight: 600;">1:${props.teacherStudentRatio}</div>
                    </div>
                    <div>
                        <div style="color: #aaa; margin-bottom: 2px;">Education Index</div>
                        <div style="color: ${props.educationIndex > 0.8 ? '#00ff00' : props.educationIndex > 0.6 ? '#ffaa00' : '#ff0000'}; font-weight: 600;">${props.educationIndex}</div>
                    </div>
                    <div>
                        <div style="color: #aaa; margin-bottom: 2px;">Training Centers</div>
                        <div style="color: #ff6b6b; font-weight: 600;">${props.trainingCenters}</div>
                    </div>
                </div>
                <div style="margin-top: 10px; padding-top: 8px; border-top: 1px solid #333;">
                    <div style="color: #aaa; font-size: 11px;">Funding Gap:
                        <span style="color: ${props.fundingGap === 'Critical' ? '#ff0000' : props.fundingGap === 'High' ? '#ff8800' : props.fundingGap === 'Moderate' ? '#ffaa00' : '#00ff00'}; font-weight: 600;">
                            ${props.fundingGap}
                        </span>
                    </div>
                    <div style="color: #aaa; font-size: 11px; margin-top: 4px;">Efficiency Score:
                        <span style="color: #35b779; font-weight: 600;">${props.efficiency}</span>
                    </div>
                </div>
            </div>
        `;

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

    map.on('mouseleave', 'education-circles', () => {
        map.getCanvas().style.cursor = '';
        popup.remove();
    });

    // Hover interaction for training centers
    map.on('mousemove', 'training-centers-layer', (e) => {
        map.getCanvas().style.cursor = 'pointer';

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

        const html = `
            <div style="padding: 8px; font-family: 'Inter', sans-serif;">
                <h4 style="margin: 0 0 6px 0; color: #ff6b6b; font-size: 14px;">
                    Teacher Training Center
                </h4>
                <div style="font-size: 12px;">
                    <div style="color: #aaa;">Country: <span style="color: #fff;">${props.country}</span></div>
                    <div style="color: #aaa;">Capacity: <span style="color: #fff;">${props.capacity} students</span></div>
                    <div style="color: #aaa;">Program: <span style="color: #fff;">${props.programTypes}</span></div>
                    <div style="color: #aaa;">Est: <span style="color: #fff;">${props.yearEstablished}</span></div>
                </div>
            </div>
        `;

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

    map.on('mouseleave', 'training-centers-layer', () => {
        map.getCanvas().style.cursor = '';
        popup.remove();
    });

    // Click to fly to country
    map.on('click', 'education-circles', (e) => {
        const coordinates = e.features[0].geometry.coordinates;
        map.flyTo({
            center: coordinates,
            zoom: 4,
            duration: 2000,
            pitch: 45,
            bearing: 0
        });
    });

    // Slow rotation animation
    let userInteracting = false;
    const rotationSpeed = 0.15;

    const rotateCamera = (timestamp) => {
        if (!userInteracting) {
            map.rotateTo((timestamp / 200) % 360, { duration: 0 });
        }
        requestAnimationFrame(rotateCamera);
    };

    map.on('mousedown', () => { userInteracting = true; });
    map.on('mouseup', () => { userInteracting = false; });
    map.on('dragend', () => { userInteracting = false; });
    map.on('pitchend', () => { userInteracting = false; });
    map.on('rotateend', () => { userInteracting = false; });

    // Start rotation
    rotateCamera(0);

    // Layer toggle functionality
    document.getElementById('toggle-centers').addEventListener('click', (e) => {
        const visibility = map.getLayoutProperty('training-centers-layer', 'visibility');
        if (visibility === 'visible') {
            map.setLayoutProperty('training-centers-layer', 'visibility', 'none');
            map.setLayoutProperty('training-centers-halo', 'visibility', 'none');
            e.target.textContent = 'Show Training Centers';
            e.target.classList.remove('active');
        } else {
            map.setLayoutProperty('training-centers-layer', 'visibility', 'visible');
            map.setLayoutProperty('training-centers-halo', 'visibility', 'visible');
            e.target.textContent = 'Hide Training Centers';
            e.target.classList.add('active');
        }
    });

    document.getElementById('toggle-labels').addEventListener('click', (e) => {
        const visibility = map.getLayoutProperty('country-labels', 'visibility');
        if (visibility === 'visible') {
            map.setLayoutProperty('country-labels', 'visibility', 'none');
            e.target.textContent = 'Show Labels';
            e.target.classList.remove('active');
        } else {
            map.setLayoutProperty('country-labels', 'visibility', 'visible');
            e.target.textContent = 'Hide Labels';
            e.target.classList.add('active');
        }
    });

    // Populate top countries list
    const topList = document.getElementById('top-countries-list');
    countryRankings.slice(0, 10).forEach((feature, index) => {
        const props = feature.properties;
        const item = document.createElement('div');
        item.className = 'country-item';
        item.innerHTML = `
            <span class="rank">#${index + 1}</span>
            <span class="name">${props.country}</span>
            <span class="value">$${props.spendingPerCapita}</span>
        `;
        item.addEventListener('click', () => {
            map.flyTo({
                center: feature.geometry.coordinates,
                zoom: 4,
                duration: 2000,
                pitch: 45
            });
        });
        topList.appendChild(item);
    });

    console.log('Globe loaded successfully!');
    console.log(`Total countries: ${processedData.length}`);
    console.log(`Total training centers: ${stats.totalCenters}`);
    console.log(`Average spending: $${stats.avgSpending.toFixed(2)}`);
    console.log(`Top 5 countries by spending:`, countryRankings.slice(0, 5).map(f =>
        `${f.properties.country} ($${f.properties.spendingPerCapita})`
    ));
});

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

// Add fullscreen control
map.addControl(new mapboxgl.FullscreenControl(), 'top-right');
