// Bubble chart du dashboard avec option de taille de bulle proportionnelle ou égale

let bubbleChart = null; // Déclaré en dehors pour garder la référence
function waitForChartAndDrawBubble() {
    if (!window.Chart || !window.ChartDataLabels) {
        setTimeout(waitForChartAndDrawBubble, 50);
        return;
    }
    const chartCanvas = document.getElementById('bubbleChart');
    const toggle = document.getElementById('toggleBubbleSize');

    
    

    function drawBubbleChart(proportional) {
        // Détruire toute instance Chart.js existante sur ce canvas (Chart.js v3+)
        const existing = window.Chart.getChart(chartCanvas);
        if (existing) {
            try { existing.destroy(); } catch (e) { console.warn('Erreur destroy Chart:', e); }
        }
        if (bubbleChart) {
            try { bubbleChart.destroy(); } catch (e) { console.warn('Erreur destroy Chart:', e); }
            bubbleChart = null;
        }

        // Forcer le canvas à occuper toute la largeur/hauteur du conteneur en pixels
    if (chartCanvas && chartCanvas.parentElement) {
        const parentRect = chartCanvas.parentElement.getBoundingClientRect();
        console.log('parentRect', parentRect)

        chartCanvas.width = (parentRect.width);
        chartCanvas.height = (parentRect.height);
        chartCanvas.style.width = parentRect.width + 'px';
        chartCanvas.style.height = parentRect.height + 'px';
    }


    if(!getBubbleData){
        console.log('pas de getBubbleData')
        return ; 
    }
        const bubbleChartData = getBubbleData(proportional);

    if(!bubbleChartData){
        console.log('pas de bubbleChartData')
        return ; 
    }

        // Calcul de la régression linéaire (moindres carrés)
        // On ne fait la régression que si on veut, mais l'axe X = fraicheur, Y = complétion
        const validPoints = bubbleChartData.filter(d => d.x !== null && d.y !== null);
        const n = validPoints.length;
        let regressionLine = null, slope = 0, intercept = 0;
        if (n >= 2) {
            let sumX = 0, sumY = 0, sumXY = 0, sumXX = 0;
            validPoints.forEach(d => {
                sumX += d.x;
                sumY += d.y;
                sumXY += d.x * d.y;
                sumXX += d.x * d.x;
            });
            const meanX = sumX / n;
            const meanY = sumY / n;
            slope = (sumXY - n * meanX * meanY) / (sumXX - n * meanX * meanX);
            intercept = meanY - slope * meanX;
            const xMin = Math.min(...validPoints.map(d => d.x));
            const xMax = Math.max(...validPoints.map(d => d.x));
            regressionLine = [
                { x: xMin, y: slope * xMin + intercept },
                { x: xMax, y: slope * xMax + intercept }
            ];
        }
        window.Chart.register(window.ChartDataLabels);
        bubbleChart = new window.Chart(chartCanvas.getContext('2d'), {
            type: 'bubble',
            data: {
                datasets: [
                    {
                        label: 'Villes',
                        data: bubbleChartData,
                        backgroundColor: bubbleChartData.map(d => `rgba(94, 255, 121, ${d.completion / 100})`),
                        borderColor: 'rgb(94, 255, 121)',
                        datalabels: {
                            anchor: 'center',
                            align: 'center',
                            color: '#000',
                            display: true,
                            font: { weight: '400', size : "12px" },
                            formatter: (value, context) => {
                                return context.dataset.data[context.dataIndex].label;
                            }
                        }
                    },
                    regressionLine ? {
                        label: 'Régression linéaire',
                        type: 'line',
                        data: regressionLine,
                        borderColor: 'rgba(95, 168, 0, 0.7)',
                        borderWidth: 2,
                        pointRadius: 0,
                        fill: false,
                        order: 0,
                        tension: 0,
                        datalabels: { display: false }
                    } : null
                ].filter(Boolean)
            },
            options: {
                plugins: {
                    datalabels: {
                        display: false
                    },
                    legend: { display: true },
                    tooltip: {
                        callbacks: {
                            label: (context) => {
                                const d = context.raw;
                                if (context.dataset.type === 'line') {
                                    return `Régression: y = ${slope.toFixed(2)} × x + ${intercept.toFixed(2)}`;
                                }
                                return [
                                    `${d.label}`,
                                    `Fraîcheur moyenne: ${d.freshnessDays ? d.freshnessDays.toLocaleString() + ' jours' : 'N/A'}`,
                                    `Complétion: ${d.y.toFixed(2)}%`,
                                    `Population: ${d.population ? d.population.toLocaleString() : 'N/A'}`,
                                    `Nombre de lieux: ${d.r.toFixed(2)}`,
                                    `Budget: ${d.budget ? d.budget.toLocaleString() + ' €' : 'N/A'}`,
                                    `Budget/habitant: ${d.budgetParHabitant ? d.budgetParHabitant.toFixed(2) + ' €' : 'N/A'}`,
                                    `Budget/lieu: ${d.budgetParLieu ? d.budgetParLieu.toFixed(2) + ' €' : 'N/A'}`
                                ];
                            }
                        }
                    }
                },
                scales: {
                    x: {
                        type: 'linear',
                        title: { display: true, text: 'Fraîcheur moyenne (jours, plus petit = plus récent)' }
                    },
                    y: {
                        title: { display: true, text: 'Taux de complétion (%)' },
                        min: 0,
                        max: 100
                    }
                }
            }
        });
        // Ajout du clic sur une bulle
        chartCanvas.onclick = function(evt) {
            const points = bubbleChart.getElementsAtEventForMode(evt, 'nearest', { intersect: true }, true);
            if (points.length > 0) {
                const firstPoint = points[0];
                const dataIndex = firstPoint.index;
                const stat = window.statsDataForBubble[dataIndex];
                if (stat && stat.zone) {
                    window.location.href = '/admin/stats/' + stat.zone;
                }
            }
        };
    }

    // Initial draw
    console.log('[bubble chart] Initialisation avec taille proportionnelle ?', toggle?.checked);
    if(drawBubbleChart){

        drawBubbleChart(toggle && toggle.checked);
        // Listener
        toggle?.addEventListener('change', function() {
            console.log('[bubble chart] Toggle changé, taille proportionnelle ?', toggle?.checked);
            drawBubbleChart(toggle?.checked);
        });
    }
}

function getBubbleData(proportional) {
    // Générer les données puis trier par rayon décroissant
    const data = window.statsDataForBubble?.map(stat => {
        const population = parseInt(stat.population, 10);
        const placesCount = parseInt(stat.placesCount, 10);
        const completion =  parseInt(stat.completionPercent, 10);
        // Fraîcheur moyenne : âge moyen en jours (plus récent à droite)
        let freshnessDays = null;
        if (stat.osmDataDateAvg) {
            const now = new Date();
            const avgDate = new Date(stat.osmDataDateAvg);
            freshnessDays = Math.round((now - avgDate) / (1000 * 60 * 60 * 24));
        }
        // Pour l'axe X, on veut que les plus récents soient à droite (donc X = -freshnessDays)
        const x = freshnessDays !== null ? -freshnessDays : 0;
        // Budget
        const budget = stat.budgetAnnuel ? parseFloat(stat.budgetAnnuel) : null;
        const budgetParHabitant = (budget && population) ? budget / population : null;
        const budgetParLieu = (budget && placesCount) ? budget / placesCount : null;
        return {
            x: x,
            y: completion,
            r: proportional ? Math.sqrt(placesCount) * 2 : 12,
            label: stat.name,
            completion: stat.completionPercent || 0,
            zone: stat.zone,
            budget,
            budgetParHabitant,
            budgetParLieu,
            population,
            placesCount,
            freshnessDays
        };
    });
    // Trier du plus gros au plus petit rayon
    if(data){
        data.sort((a, b) => b.r - a.r);
    }
    return data;
}
document.addEventListener('DOMContentLoaded', function() {
    waitForChartAndDrawBubble();

    // Forcer deleteMissing=1 sur le formulaire de labourage
    const labourerForm = document.getElementById('labourerForm');
    if (labourerForm) {
        labourerForm.addEventListener('submit', function(e) {
            e.preventDefault();
            const zipCode = document.getElementById('selectedZipCode').value;
            if (zipCode) {
                window.location.href = '/admin/labourer/' + zipCode + '?deleteMissing=1';
            }
        });
    }
}); 