$(document).ready(function () {
    // loadCovidData()

    loadDataChanges()
});


function loadCovidData() {
    $('#loader').show();
    $('#state-legend').empty();
    $('#state-legend').append(` <span><span style="background-color: #c7dfdd"></span>0</span>
                  <span><span style="background-color: #78a5a2"></span>100</span>
                  <span><span style="background-color: #679895"></span>200</span>
                  <span><span style="background-color: #508a87"></span>500</span>
                  <span><span style="background-color: #41837f"></span>1000</span>
                  <span><span style="background-color: #317b76"></span>1.5K</span>
                  <span><span style="background-color: #10524d"></span>5K</span>
                  <span><span style="background-color: #0a3d39"></span>10K</span>`)
    var colors = ['#eec524', '#24cfa2', '#e70c0c']
    $.ajax({
        type: "GET",
        url: 'https://raw.githubusercontent.com/samit22/nepalgeo/master/province.geojson',
        dataType: "json",
        success: function (provData) {
            getProvData(provData);
            $('#loader').slideUp()
        }
    });

    function getProvData(provData) {
        $.ajax({
            type: "GET",
            url: "https://covidapi.mohp.gov.np/api/v1/stats/?province=all",
            dataType: "json",
            success: function (provCases) {
                formatCases(provCases);
                map.addSource('prov-line-covid', {
                    type: 'geojson',
                    data: provData,
                })
                map.addLayer({
                    'id': 'prov-line-covid',
                    'type': 'line',
                    'source': 'prov-line-covid',
                    'layout': {
                        'visibility': 'visible'
                    },
                    'paint': {
                        'line-color': '#ffffff',
                        'line-width': 2
                    }
                })

            }
        })

        function formatCases(provCases) {
            const formattedCases = convertToObject(provCases, "province_id")
            var results = provData.features
            var finalData = []
            for(var i = 0; i < results.length; i++) {
                var prov = results[i]
                var casData = formattedCases[prov.properties.province_id]
                var {
                    total_positive,
                    total_death,
                    province_name,
                    total_recovered
                } = casData

                var feature = {
                    object_id: prov.properties.object_id,
                    province_name: province_name,
                    positive: total_positive,
                    recovered: total_recovered,
                    deaths: total_death,
                    active: total_positive - total_recovered - total_death,
                    mortality_rate: roundOff((total_death / total_positive) * 100) || 0,
                    recovery_rate: roundOff((total_recovered / total_positive) * 100) || 0,
                }
                prov.properties = feature
                finalData.push(prov)

            }

            provCases.features = finalData

            map.addSource('prov-layer-covid', {
                type: 'geojson',
                data: provData
            })

            map.addLayer({
                'id': 'prov-layer-covid',
                'type': 'fill',
                'source': 'prov-layer-covid',
                'layout': {
                    'visibility': 'visible'
                },
                'paint': {
                    'fill-color': [
                        'interpolate',
                        ['linear'],
                        ['get', 'positive'],
                        0,
                        '#c7dfdd',
                        100,
                        '#78a5a2',
                        200,
                        '#679895',
                        500,
                        '#508a87',
                        1000,
                        '#41837f',
                        1500,
                        '#317b76',
                        5000,
                        '#1e746e',
                        10000,
                        '#0a3d39'
                    ],
                    'fill-opacity': 0.75
                },

            })

        }
        function addProvinceDonout(data) {

            let geoData = {
                type: "FeatureCollection",
                features: data
            };

            var active = ['==', ['get', 'active'], ['get', 'active']];
            var recovered = ['==', ['get', 'recovered'], ['get', 'recovered']];
            var deaths = ['==', ['get', 'deaths'], ['get', 'deaths']];

            map.addSource('provinceData', {
                type: 'geojson',
                data: geoData,
                cluster: true,
                clusterRadius: 1,
                clusterProperties: {
                    // keep separate counts for each magnitude category in a cluster
                    'active': ['+', ['case', active, ['get', 'active'], 0]],
                    'recovered': ['+', ['case', recovered, ['get', 'recovered'], 0]],
                    'deaths': ['+', ['case', deaths, ['get', 'deaths'], 0]],
                    'province_name': ["string", ['get', "province_name"]]
                }
            });

            map.addLayer({
                'id': 'province_circle',
                'type': 'circle',
                'source': 'provinceData',
                'layout': {
                    'visibility': 'visible',
                },
                'paint': {
                    'circle-color': [
                        'case',
                        active,
                        colors[0],
                        recovered,
                        colors[1],
                        colors[2]
                    ],
                    'circle-opacity': 0.6,
                    'circle-radius': 12
                }
            })
            map.addLayer({
                'id': 'province_label',
                'type': 'symbol',
                'source': 'provinceData',
                'layout': {
                    'visibility': 'visible'
                }
            });

            map.on('click', 'province_circle', function (e) {
                var coordinates = e.features[0].geometry.coordinates.slice();
                var prpts = e.features[0].properties || {}
                var active = prpts.active || 0
                var deaths = prpts.deaths || 0
                var recovered = prpts.recovered || 0
                var province = prpts.province_name || ""
                var positive = active + deaths + recovered
                var recovery_rate = roundOff(recovered / positive * 100)
                var mortality_rate = roundOff(deaths / positive * 100)
                var coordinates = e.lngLat
                while(Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
                    coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
                }

                const dt = `<div class="full-length" role="tooltip">
           <div class='popup-header'> Province: ${province}</div>
           <hr>
           <div class="popup-body"> Cases: ${positive
                    } <br> Active: ${active
                    } <span class="percentage"> (${roundOff(active / positive * 100)}%) </span> <br> Recovered: ${recovered
                    } <br> Deaths: ${deaths
                    }
             <div class="recovered-color"> Recovery Rate: ${recovery_rate}% </div>
           </div>
           <div class="deaths-color"> Mortality Rate: ${mortality_rate}% </div>
         </div>
         </div>`

                new mapboxgl.Popup()
                    .setLngLat(coordinates)
                    .setHTML(dt)
                    .addTo(map);
            });


        }

    }
    var popup = new mapboxgl.Popup({
        closeButton: true,
        closeOnClick: true
    });

    map.on('click', 'prov-layer-covid', function (e) {


        var data = e.features[0]
        var {
            province_name,
            positive,
            active,
            deaths,
            recovered,
            recovery_rate,
            mortality_rate,
        } = data.properties

        const dt = `<div class="full-length" role="tooltip">
           <div class='popup-header'> ${province_name}</div>
           <hr>
           <div class="popup-body"> Cases: ${positive
            } <br> Active: ${active
            } <span class="percentage"> (${roundOff(active / positive * 100)}%) </span> <br> Recovered: ${recovered
            } <br> Deaths: ${deaths
            }
             <div class="recovered-color"> Recovery Rate: ${recovery_rate}% </div>
           </div>
           <div class="deaths-color"> Mortality Rate: ${mortality_rate}% </div>
         </div>
         </div>`

        var coordinates = e.lngLat
        var description = dt
        while(Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
            coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;
        }
        popup
            .setLngLat(coordinates)
            .setHTML(description)
            .addTo(map);
    });
    map.on('mouseover', 'prov-layer-covid', function (e) {
        map.getCanvas().style.cursor = 'pointer';
    })

    map.on('mouseleave', 'prov-layer-covid', function () {
        map.getCanvas().style.cursor = '';
    });


    // popover

    // map.on('mousemove', function (e) {
    //     var provinces = map.queryRenderedFeatures(e.point, {
    //         layers: ['prov-layer']
    //     });
    //     if(provinces.length > 0) {
    //         var {
    //             province_name,
    //             positive,
    //             active,
    //             deaths,
    //             recovered,
    //             recovery_rate,
    //             mortality_rate
    //         } = provinces[0].properties

    //         document.getElementById('pd').innerHTML = `
    //       <div class="data-header" id="data-header"> ${province_name} </div>
    //       <div id="positive" class="positive data-formatter"> Positive: ${positive} </div>
    //       <div id="active" class="active data-formatter"> Active: ${active} </div>
    //       <div id="recovered" class="recovered data-formatter"> Recovered: ${recovered} </div>
    //       <div id="deaths" class="deaths data-formatter"> Deaths: ${deaths} </div>
    //       </div>`
    //     }
    // });

    function updateProvMarkers() {
        var newMarkers = {};
        var features = map.querySourceFeatures('provinceData');


        for(var i = 0; i < features.length; i++) {
            var coords = features[i].geometry.coordinates;
            var props = features[i].properties;
            var id = props.province_name;
            var marker = markers[id];
            if(!marker) {
                var el = createDonutChart(props);
                marker = markers[id] = new mapboxgl.Marker({
                    element: el
                }).setLngLat(coords);
            }
            newMarkers[id] = marker;
            if(!markersOnScreen[id]) marker.addTo(map);
        } // for every marker we 've added previously, remove those that are no longer visible
        var visibility = map.getLayoutProperty('province_circle', 'visibility');
        if(visibility === "none") {
            for(id in markersOnScreen) {
                if(!newMarkers[id]) {
                    markersOnScreen[id].remove();
                }
            }
            markersOnScreen = newMarkers;
        }
    }

    function updateDistMarkers() {
        var newMarkers = {};
        var features = map.querySourceFeatures('districtData');

        // for every cluster on the screen, create an HTML marker for it (if we didn't yet),
        // and add it to the map if it's not there already
        for(var i = 0; i < features.length; i++) {
            var coords = features[i].geometry.coordinates;
            var props = features[i].properties;
            if(!props.cluster) continue;
            var id = props.district;
            var marker = markers[id];
            if(!marker) {
                var el = createDonutChart(props);
                marker = markers[id] = new mapboxgl.Marker({
                    element: el
                }).setLngLat(coords);
            }
            newMarkers[id] = marker;
            if(!distMarkers[id]) marker.addTo(map);
        }
        var visibility = map.getLayoutProperty('district_circle', 'visibility');

        if(visibility === "none") {
            console.log("DIST MARKER", distMarkers)
            for(id in distMarkers) {
                distMarkers[id].remove();
            }
        }
        // for every marker we 've added previously, remove those that are no longer visible

        distMarkers = newMarkers;
    }

    // var markers = {};
    // var markersOnScreen = {};
    // var distMarkers = {}

    // map.on('data', function (e) {
    //    var source = e.sourceId
    // if(source === 'provinceData') {
    //     var visibility = map.getLayoutProperty('province_circle', 'visibility');
    //     if(visibility === 'visible') {
    //         map.on('move', updateProvMarkers);
    //         map.on('moveend',
    //             updateProvMarkers);
    //         updateProvMarkers();
    //     }
    // } else
    // if(source === 'districtData') {
    //     var visibility = map.getLayoutProperty('district_circle', 'visibility');
    //     if(visibility !== 'visible') {
    //         map.on('move', updateDistMarkers);
    //         map.on('moveend',
    //             updateDistMarkers);
    //         updateDistMarkers();
    //     }
    // }

    // });



    // code for creating an SVG donut chart from feature properties

    function createDonutChart(props) {
        var offsets = [];
        var counts = [props.active, props.recovered, props.deaths];
        var total = 0;
        for(var i = 0; i < counts.length; i++) {
            offsets.push(total);
            total
                += counts[i];
        }
        var fontSize = total >= 1000 ? 22 : total >= 100 ? 20 : total >= 10 ? 18 : 16;
        var r = total >= 1000 ? 50 : total >= 100 ? 32 : total >= 10 ? 24 : 18;
        var r0 = Math.round(r * 0.6);
        var w = r * 2;

        var html =
            '<div><svg width="' +
            w +
            '" height="' +
            w +
            '" viewbox="0 0 ' +
            w +
            ' ' +
            w +
            '" text-anchor="middle" style="font: ' +
            fontSize +
            'px sans-serif">';

        for(i = 0; i < counts.length; i++) {
            html += donutSegment(offsets[i] / total, (offsets[i] + counts[i]) /
                total, r, r0, colors[i]);
        }

        html += '<circle cx="' + r + '" cy="' + r + '" r="' + r0 +
            '" fill="white" /><text dominant-baseline="central" transform="translate(' + r + ', ' + r + ')">' +
            total.toLocaleString() + '</text></svg></div>';
        var el = document.createElement('div');
        el.innerHTML = html;
        return el.firstChild;
    }

    function donutSegment(start, end, r, r0, color) {
        if(end - start === 1) end -= 0.00001;
        var a0 = 2 * Math.PI * (start - 0.25);
        var a1 = 2 * Math.PI * (end - 0.25);
        var
            x0 = Math.cos(a0),
            y0 = Math.sin(a0);
        var x1 = Math.cos(a1),
            y1 = Math.sin(a1);
        var largeArc = end - start > 0.5 ?
            1 : 0;

        return [
            '<path d = "M',
            r + r0 * x0,
            r + r0 * y0,
            'L',
            r + r * x0,
            r + r * y0,
            'A',
            r,
            r,
            0,
            largeArc,
            1,
            r + r * x1,
            r + r * y1,
            'L',
            r + r0 * x1,
            r + r0 * y1,
            'A',
            r0,
            r0,
            0,
            largeArc,
            0,
            r + r0 * x0,
            r + r0 * y0,
            '" fill="' + color + '" />'
        ].join(' ');
    }

}
