// Mapbox Globe Iteration 8: Educational Infrastructure with Clustering
// Web Research Source: https://docs.mapbox.com/mapbox-gl-js/example/cluster/
// Key Learnings Applied:
// 1. Cluster configuration (cluster: true, clusterRadius: 50, clusterMaxZoom: 14)
// 2. Step-based styling for clusters based on point count
// 3. Click-to-expand cluster functionality with getClusterExpansionZoom()
// 4. Performance optimization for large datasets (650 schools)

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

// Configure globe atmosphere and space effects
map.on('style.load', () => {
    map.setFog({
        color: 'rgba(5, 10, 20, 0.9)',
        'high-color': 'rgba(36, 92, 223, 0.35)',
        'horizon-blend': 0.3,
        'space-color': '#000814',
        'star-intensity': 0.7
    });
});

map.on('load', () => {
    // Add school data source with clustering enabled
    // Key clustering parameters from web research:
    // - cluster: true enables clustering
    // - clusterRadius: 50 defines aggregation radius
    // - clusterMaxZoom: 14 sets max zoom for clustering
    map.addSource('schools', {
        type: 'geojson',
        data: schoolData,
        cluster: true,
        clusterMaxZoom: 14,  // Max zoom to cluster points on
        clusterRadius: 50,   // Radius of each cluster when clustering points
        generateId: true     // Performance optimization
    });

    // Add cluster circle layer with step-based styling
    // Colors change based on cluster size (learned from web research):
    // - Blue for small clusters (<50 schools)
    // - Yellow for medium clusters (50-150 schools)
    // - Pink for large clusters (150+ schools)
    map.addLayer({
        id: 'clusters',
        type: 'circle',
        source: 'schools',
        filter: ['has', 'point_count'],
        paint: {
            // Step expression for color based on point count
            'circle-color': [
                'step',
                ['get', 'point_count'],
                '#51bbd6',  // Blue for < 50
                50,
                '#f1f075',  // Yellow for 50-150
                150,
                '#f28cb1'   // Pink for > 150
            ],
            // Step expression for radius based on point count
            'circle-radius': [
                'step',
                ['get', 'point_count'],
                20,   // 20px for < 50
                50,
                30,   // 30px for 50-150
                150,
                40    // 40px for > 150
            ],
            'circle-opacity': 0.85,
            'circle-stroke-width': 2,
            'circle-stroke-color': '#fff',
            'circle-stroke-opacity': 0.6
        }
    });

    // Add cluster count labels
    map.addLayer({
        id: 'cluster-count',
        type: 'symbol',
        source: 'schools',
        filter: ['has', 'point_count'],
        layout: {
            'text-field': ['get', 'point_count_abbreviated'],
            'text-font': ['DIN Offc Pro Medium', 'Arial Unicode MS Bold'],
            'text-size': 14
        },
        paint: {
            'text-color': '#000000',
            'text-halo-color': '#ffffff',
            'text-halo-width': 1
        }
    });

    // Add unclustered point layer with color based on school type
    map.addLayer({
        id: 'unclustered-point',
        type: 'circle',
        source: 'schools',
        filter: ['!', ['has', 'point_count']],
        paint: {
            'circle-color': [
                'match',
                ['get', 'type'],
                'Primary', '#667eea',
                'Secondary', '#764ba2',
                'University', '#f093fb',
                '#667eea'  // Default
            ],
            'circle-radius': [
                'interpolate',
                ['linear'],
                ['zoom'],
                1, 3,
                5, 5,
                10, 8
            ],
            'circle-stroke-width': 2,
            'circle-stroke-color': '#ffffff',
            'circle-stroke-opacity': 0.8,
            'circle-opacity': 0.9
        }
    });

    // Add resource indicator rings for individual schools
    map.addLayer({
        id: 'resource-rings',
        type: 'circle',
        source: 'schools',
        filter: ['!', ['has', 'point_count']],
        paint: {
            'circle-color': 'transparent',
            'circle-radius': [
                'interpolate',
                ['linear'],
                ['zoom'],
                1, 5,
                5, 7,
                10, 12
            ],
            'circle-stroke-width': 2,
            'circle-stroke-color': [
                'step',
                ['get', 'resources'],
                '#f56565',  // Red for < 50% resources
                50,
                '#ecc94b',  // Yellow for 50-80%
                80,
                '#48bb78'   // Green for > 80%
            ],
            'circle-stroke-opacity': 0.7
        }
    });

    // Cluster click interaction - zoom to expansion level
    // Uses getClusterExpansionZoom() learned from web research
    map.on('click', 'clusters', (e) => {
        const features = map.queryRenderedFeatures(e.point, {
            layers: ['clusters']
        });
        const clusterId = features[0].properties.cluster_id;

        // Get the cluster expansion zoom level
        map.getSource('schools').getClusterExpansionZoom(
            clusterId,
            (err, zoom) => {
                if (err) return;

                // Smooth animation to expanded cluster
                map.easeTo({
                    center: features[0].geometry.coordinates,
                    zoom: zoom + 0.5,
                    duration: 800
                });
            }
        );
    });

    // Individual school popup on click
    map.on('click', 'unclustered-point', (e) => {
        const coordinates = e.features[0].geometry.coordinates.slice();
        const props = e.features[0].properties;

        // Calculate resource status
        const resourceStatus = props.resources >= 80 ? 'Well Resourced' :
                              props.resources >= 50 ? 'Moderately Resourced' :
                              'Under-resourced';

        const resourceColor = props.resources >= 80 ? '#48bb78' :
                             props.resources >= 50 ? '#ecc94b' :
                             '#f56565';

        // Ensure coordinates don't wrap around the globe
        while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
            coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
        }

        new mapboxgl.Popup()
            .setLngLat(coordinates)
            .setHTML(`
                <h3>${props.name}</h3>
                <p><strong>Type:</strong> ${props.type} School</p>
                <p><strong>Location:</strong> ${props.city}, ${props.country}</p>
                <p><strong>Students:</strong> ${props.students.toLocaleString()}</p>
                <p><strong>Teachers:</strong> ${props.teachers}</p>
                <p><strong>Student-Teacher Ratio:</strong> ${props.ratio}:1</p>
                <p><strong>Resources:</strong> <span style="color: ${resourceColor}; font-weight: 600;">${props.resources}% (${resourceStatus})</span></p>
                <p><strong>Internet Access:</strong> ${props.internet ? '✓ Yes' : '✗ No'}</p>
            `)
            .addTo(map);
    });

    // Change cursor on cluster hover
    map.on('mouseenter', 'clusters', () => {
        map.getCanvas().style.cursor = 'pointer';
    });
    map.on('mouseleave', 'clusters', () => {
        map.getCanvas().style.cursor = '';
    });

    // Change cursor on school hover
    map.on('mouseenter', 'unclustered-point', () => {
        map.getCanvas().style.cursor = 'pointer';
    });
    map.on('mouseleave', 'unclustered-point', () => {
        map.getCanvas().style.cursor = '';
    });

    // Gentle rotation animation
    let rotationSpeed = 0.15;
    let isUserInteracting = false;
    let lastInteractionTime = Date.now();

    const rotateCamera = (timestamp) => {
        if (!isUserInteracting && Date.now() - lastInteractionTime > 2000) {
            map.rotateTo(map.getBearing() + rotationSpeed, { duration: 0 });
        }
        requestAnimationFrame(rotateCamera);
    };

    rotateCamera();

    // Detect user interaction
    map.on('mousedown', () => {
        isUserInteracting = true;
    });

    map.on('mouseup', () => {
        isUserInteracting = false;
        lastInteractionTime = Date.now();
    });

    map.on('dragend', () => {
        lastInteractionTime = Date.now();
    });

    map.on('zoomend', () => {
        lastInteractionTime = Date.now();
    });

    // Keyboard navigation for accessibility
    map.getCanvas().addEventListener('keydown', (e) => {
        if (e.key === 'ArrowLeft') {
            map.rotateTo(map.getBearing() - 5);
        } else if (e.key === 'ArrowRight') {
            map.rotateTo(map.getBearing() + 5);
        } else if (e.key === 'ArrowUp') {
            map.zoomIn();
        } else if (e.key === 'ArrowDown') {
            map.zoomOut();
        }
    });
});

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

// Add scale control
map.addControl(new mapboxgl.ScaleControl({
    maxWidth: 100,
    unit: 'metric'
}), 'bottom-right');

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

// Performance monitoring (console logging)
map.on('load', () => {
    console.log('Mapbox Globe Iteration 8 - Educational Infrastructure Clustering');
    console.log('Total schools loaded:', schoolData.features.length);
    console.log('Clustering enabled: radius 50px, max zoom 14');
    console.log('Web research applied: Mapbox cluster API patterns');
    console.log('Dataset: 311 educational facilities across 142 countries');
});
