let trendChart;
let map;

/*
|--------------------------------------------------------------------------
| Load Summary Cards
|--------------------------------------------------------------------------
*/

function loadSummary() {
    fetch('/api/dashboard/summary')
        .then(res => res.json())
        .then(data => {

            let html = '';

            data.forEach(item => {

                let trendColor = 'text-secondary';

                if (item.percent_change > 0) trendColor = 'text-danger';
                if (item.percent_change < 0) trendColor = 'text-success';

                html += `
                    <div class="col-md-2 mb-3">
                        <div class="card shadow-sm h-100">
                            <div class="card-body">

                                <div class="d-flex justify-content-between">

                                    <div>
                                        <h6 class="fw-bold">${item.code}</h6>
                                        <h3 class="mb-1">${item.current_total}</h3>
                                        <small class="text-muted">Last 7 days</small>
                                    </div>

                                    <div class="text-end">

                                        <div class="${trendColor} fw-bold">
                                            ${item.percent_change > 0 ? '▲' : item.percent_change < 0 ? '▼' : '–'}
                                            ${Math.abs(item.percent_change)}%
                                        </div>

                                        <small class="text-muted">
                                            ${item.previous_total ?? 0} last week
                                        </small>

                                    </div>

                                </div>

                            </div>
                        </div>
                    </div>
                `;
            });

            document.getElementById('summary_cards').innerHTML = html;

        });
}


/*
|--------------------------------------------------------------------------
| Load Trend Chart
|--------------------------------------------------------------------------
*/

function loadTrend(periodType, startYear, startWeek, endYear, endWeek) {

    fetch(`/api/dashboard/trend?period_type=${periodType}&start_year=${startYear}&start_week=${startWeek}&end_year=${endYear}&end_week=${endWeek}`)
        .then(res => res.json())
        .then(data => {

            if (trendChart) trendChart.destroy();

            const labelsSet = new Set();

            Object.values(data).forEach(program => {
                program.forEach(row => {
                    labelsSet.add(`${row.year}-${row.period}`);
                });
            });

            const labels = Array.from(labelsSet).sort((a, b) => {

                const [yearA, weekA] = a.split('-').map(Number);
                const [yearB, weekB] = b.split('-').map(Number);

                if (yearA !== yearB) return yearA - yearB;

                return weekA - weekB;

            });

            const colors = {
                SARI: '#2563eb',
                ILI: '#10b981',
                LBM: '#9333ea'
            };

            const datasets = [];

            const allowedPrograms = ['SARI', 'ILI', 'LBM'];

            Object.keys(data).forEach(code => {

                if (!allowedPrograms.includes(code)) return;

                const values = labels.map(label => {

                    const found = data[code].find(row => `${row.year}-${row.period}` === label);

                    return found ? found.total : 0;

                });

                datasets.push({
                    label: code,
                    data: values,
                    borderColor: colors[code],
                    backgroundColor: colors[code],
                    borderWidth: 3,
                    pointRadius: 4,
                    fill: false,
                    tension: 0.3
                });

            });

            const displayLabels = labels.map(l => {
                const [year, week] = l.split('-');
                return `W${String(week).padStart(2, '0')}`;
            });

            trendChart = new Chart(document.getElementById('trendChart'), {

                type: 'line',

                data: {
                    labels: displayLabels,
                    datasets: datasets
                },

                options: {
                    responsive: true,
                    plugins: {
                        legend: { position: 'bottom' }
                    },
                    interaction: {
                        mode: 'index',
                        intersect: false
                    },
                    scales: {
                        y: {
                            beginAtZero: true,
                            ticks: { stepSize: 1 }
                        },
                        x: { grid: { display: false } }
                    }
                }

            });

        });

}


/*
|--------------------------------------------------------------------------
| Province Map
|--------------------------------------------------------------------------
*/

function loadProvinceMap(startYear, startWeek, endYear, endWeek) {

    if (map) map.remove();

    map = L.map('provinceMap').setView([12.7, 104.9], 7);

    L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        attribution: '© OpenStreetMap'
    }).addTo(map);


    Promise.all([
        fetch('/geo/cambodia_provinces.geojson').then(r => r.json()),
        fetch(`/api/dashboard/province-circles?start_year=${startYear}&start_week=${startWeek}&end_year=${endYear}&end_week=${endWeek}`).then(r => r.json())
    ])
        .then(([geojson, data]) => {

            L.geoJSON(geojson, {
                style: {
                    fillOpacity: 0,
                    color: '#ccc',
                    weight: 1,
                    interactive: false
                },

                onEachFeature: function (feature, layer) {

                    const province = feature.properties.ADM1_EN;
                    const center = layer.getBounds().getCenter();

                    const rows = data.filter(d => d.site_province_name === province);

                    const offsets = {
                        1: -0.15,
                        2: 0,
                        3: 0.15
                    };

                    rows.forEach(row => {

                        const lat = center.lat;
                        const lng = center.lng + offsets[row.surveillance_id];

                        const programName =
                            row.surveillance_id === 1 ? 'SARI' :
                                row.surveillance_id === 2 ? 'ILI' : 'LBM';

                        const colors = {
                            1: '#2563eb',
                            2: '#10b981',
                            3: '#9333ea'
                        };

                        L.circleMarker([lat, lng], {

                            radius: 9,
                            fillColor: colors[row.surveillance_id],
                            color: '#fff',
                            weight: 1,
                            fillOpacity: 0.9

                        })
                            .bindTooltip(`
                                        <strong>${province}</strong><br>
                                          ${programName}<br>
                                        Total: ${row.total}
                                        `)
                            .addTo(map);

                    });

                }

            }).addTo(map);

        });

}


/*
|--------------------------------------------------------------------------
| Initialize Dashboard
|--------------------------------------------------------------------------
*/

document.addEventListener("DOMContentLoaded", () => {

    loadSummary();

    new DashboardFilter((startYear, startWeek, endYear, endWeek) => {

        loadTrend('week', startYear, startWeek, endYear, endWeek);

        loadProvinceMap(startYear, startWeek, endYear, endWeek);

    });

});