/* ===================================================
   JAESWIFT.XYZ — 3D Globe (Globe.gl)
   eDEX-UI inspired rotating globe with server location
   =================================================== */

(function () {
    'use strict';

    const container = document.getElementById('globeViz');
    if (!container || typeof Globe === 'undefined') return;

    // Manchester coordinates
    const SERVER_LAT = 53.48;
    const SERVER_LNG = -2.24;

    // Wait for container to be visible and sized
    function initGlobe() {
        const rect = container.parentElement.getBoundingClientRect();
        const size = Math.min(rect.width, 340);

        if (size < 50) {
            setTimeout(initGlobe, 200);
            return;
        }

        const globe = Globe()
            .globeImageUrl('')
            .backgroundColor('rgba(0,0,0,0)')
            .width(size)
            .height(size)
            .showAtmosphere(true)
            .atmosphereColor('#00ff44')
            .atmosphereAltitude(0.2)
            // Hex polygons for land masses
            .hexPolygonsData([])
            // Points - server location
            .pointsData([{
                lat: SERVER_LAT,
                lng: SERVER_LNG,
                size: 0.6,
                color: '#00cc33',
                label: 'MANCHESTER'
            }])
            .pointAltitude('size')
            .pointColor('color')
            .pointRadius(0.4)
            .pointsMerge(false)
            // Rings - pulse effect
            .ringsData([{
                lat: SERVER_LAT,
                lng: SERVER_LNG,
                maxR: 3,
                propagationSpeed: 1.5,
                repeatPeriod: 1200
            }])
            .ringColor(function () { return '#00cc3380'; })
            .ringMaxRadius('maxR')
            .ringPropagationSpeed('propagationSpeed')
            .ringRepeatPeriod('repeatPeriod')
            // Labels
            .labelsData([{
                lat: SERVER_LAT,
                lng: SERVER_LNG,
                text: 'MCR // 53.48°N',
                color: '#00cc33',
                size: 0.7
            }])
            .labelColor('color')
            .labelSize('size')
            .labelDotRadius(0.3)
            .labelAltitude(0.01)
            .labelText('text')
            .labelResolution(2)
            // Custom globe material
            .onGlobeReady(function () {
                // Style the globe mesh
                var globeMesh = globe.scene().children.find(function (c) {
                    return c.type === 'Mesh' && c.geometry && c.geometry.type === 'SphereGeometry';
                });
                if (globeMesh && globeMesh.material) {
                    globeMesh.material.color.setHex(0x0a1a0a);
                    globeMesh.material.emissive.setHex(0x008800);
                    globeMesh.material.emissiveIntensity = 0.8;
                }
            })
            (container);

        // Auto rotate
        globe.controls().autoRotate = true;
        globe.controls().autoRotateSpeed = 0.4;
        globe.controls().enableZoom = false;
        globe.controls().enablePan = false;
        globe.controls().minPolarAngle = Math.PI * 0.35;
        globe.controls().maxPolarAngle = Math.PI * 0.65;

        // Point camera at Manchester
        globe.pointOfView({ lat: SERVER_LAT, lng: SERVER_LNG, altitude: 2.2 }, 1500);

        // Fetch country polygons for land outlines
        fetch('https://unpkg.com/world-atlas@2/countries-110m.json')
            .then(function (r) { return r.json(); })
            .then(function (worldData) {
                var countries = topojsonFeature(worldData, worldData.objects.countries).features;
                globe
                    .hexPolygonsData(countries)
                    .hexPolygonResolution(3)
                    .hexPolygonMargin(0.4)
                    .hexPolygonColor(function () {
                        return 'rgba(0, 220, 50, 0.55)';
                    })
                    .hexPolygonSideColor(function () {
                        return 'rgba(0, 255, 60, 0.6)';
                    })
                    .hexPolygonAltitude(0.005);
            })
            .catch(function () {
                // Fallback: no country data, globe still works
            });

        // Simulated visitor arcs (random locations connecting to Manchester)
        function generateRandomArcs() {
            var cities = [
                { lat: 40.71, lng: -74.01 },  // New York
                { lat: 35.68, lng: 139.69 },  // Tokyo
                { lat: 48.86, lng: 2.35 },    // Paris
                { lat: -33.87, lng: 151.21 }, // Sydney
                { lat: 55.76, lng: 37.62 },   // Moscow
                { lat: 1.35, lng: 103.82 },   // Singapore
                { lat: 37.57, lng: 126.98 },  // Seoul
                { lat: 19.43, lng: -99.13 },  // Mexico City
                { lat: 52.52, lng: 13.41 },   // Berlin
                { lat: -23.55, lng: -46.63 }, // São Paulo
                { lat: 28.61, lng: 77.21 },   // Delhi
                { lat: 34.05, lng: -118.24 }, // LA
            ];

            var arcs = [];
            var count = 2 + Math.floor(Math.random() * 3);
            for (var i = 0; i < count; i++) {
                var city = cities[Math.floor(Math.random() * cities.length)];
                arcs.push({
                    startLat: city.lat,
                    startLng: city.lng,
                    endLat: SERVER_LAT,
                    endLng: SERVER_LNG,
                    color: ['rgba(0, 255, 60, 0.7)', 'rgba(0, 255, 60, 0.08)']
                });
            }
            return arcs;
        }

        globe
            .arcsData(generateRandomArcs())
            .arcColor('color')
            .arcDashLength(0.5)
            .arcDashGap(0.2)
            .arcDashAnimateTime(2000)
            .arcStroke(0.4)
            .arcAltitudeAutoScale(0.3);

        // Refresh arcs periodically
        setInterval(function () {
            globe.arcsData(generateRandomArcs());
        }, 5000);

        // Handle resize
        var resizeTimer;
        window.addEventListener('resize', function () {
            clearTimeout(resizeTimer);
            resizeTimer = setTimeout(function () {
                var newRect = container.parentElement.getBoundingClientRect();
                var newSize = Math.min(newRect.width, 340);
                globe.width(newSize).height(newSize);
            }, 250);
        });
    }

    // Topojson helper
    function topojsonFeature(topology, obj) {
        if (!obj || !obj.geometries) return { type: 'FeatureCollection', features: [] };
        return {
            type: 'FeatureCollection',
            features: obj.geometries.map(function (geom) {
                return {
                    type: 'Feature',
                    geometry: topojsonGeometry(topology, geom),
                    properties: geom.properties || {},
                    id: geom.id
                };
            })
        };
    }

    function topojsonGeometry(topology, obj) {
        var arcs = topology.arcs;
        var transform = topology.transform;

        function decodeArc(arcIdx) {
            var arc = arcs[arcIdx < 0 ? ~arcIdx : arcIdx];
            var coords = [];
            var x = 0, y = 0;
            for (var i = 0; i < arc.length; i++) {
                x += arc[i][0];
                y += arc[i][1];
                var lon = x, lat = y;
                if (transform) {
                    lon = lon * transform.scale[0] + transform.translate[0];
                    lat = lat * transform.scale[1] + transform.translate[1];
                }
                coords.push([lon, lat]);
            }
            if (arcIdx < 0) coords.reverse();
            return coords;
        }

        function decodeRing(arcIndices) {
            var coords = [];
            for (var i = 0; i < arcIndices.length; i++) {
                var arcCoords = decodeArc(arcIndices[i]);
                if (i > 0) arcCoords.shift();
                coords = coords.concat(arcCoords);
            }
            return coords;
        }

        var type = obj.type;
        if (type === 'Polygon') {
            return { type: 'Polygon', coordinates: obj.arcs.map(decodeRing) };
        } else if (type === 'MultiPolygon') {
            return {
                type: 'MultiPolygon',
                coordinates: obj.arcs.map(function (polygon) {
                    return polygon.map(decodeRing);
                })
            };
        } else if (type === 'GeometryCollection') {
            return {
                type: 'GeometryCollection',
                geometries: (obj.geometries || []).map(function (g) {
                    return topojsonGeometry(topology, g);
                })
            };
        }
        return { type: type, coordinates: [] };
    }

    // Init when DOM ready
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', function () {
            setTimeout(initGlobe, 300);
        });
    } else {
        setTimeout(initGlobe, 300);
    }

})();
