// Imaging possibilities month overview chart (Chart.js)
// - Stacked bars per filter (hours)
// - Moon illumination and moon distance lines
// - Click a day to notify Blazor

if (typeof window._imagingMonthCharts === 'undefined') {
    window._imagingMonthCharts = new Map();
}

if (typeof window._imagingYearCharts === 'undefined') {
    window._imagingYearCharts = new Map();
}

async function ensureImagingChartJsLoaded() {
    if (window.astroAppAssets?.ensureChartJsBundle) {
        await window.astroAppAssets.ensureChartJsBundle();
    }

    if (typeof Chart !== 'undefined') {
        return true;
    }

    console.error('[ImagingMonthChart] Chart.js not loaded.');
    return false;
}

function imagingFilterColor(name, alpha) {
    const a = alpha ?? 0.75;
    switch ((name || '').toLowerCase()) {
        case 'l': return `rgba(203, 213, 225, ${a})`;
        case 'r': return `rgba(239, 68, 68, ${a})`;
        case 'g': return `rgba(34, 197, 94, ${a})`;
        case 'b': return `rgba(59, 130, 246, ${a})`;
        case 'ha': return `rgba(244, 63, 94, ${a})`;
        case 'sii': return `rgba(249, 115, 22, ${a})`;
        case 'oiii': return `rgba(56, 189, 248, ${a})`;
        default: return `rgba(139, 92, 246, ${a})`;
    }
}

function getMonthTooltipFilterHours(payload, dataIndex) {
    const filters = payload?.filters || [];
    return filters
        .map((filter, order) => {
            const series = payload?.filterSeries?.[filter] || [];
            const hours = Number(series[dataIndex] ?? 0);
            return { filter, hours, order };
        })
        .filter(entry => entry.hours > 0);
}

function getMonthTooltipGroupedFilters(payload, dataIndex) {
    const filterHours = getMonthTooltipFilterHours(payload, dataIndex);
    const grouped = new Map();

    for (const entry of filterHours) {
        const key = entry.hours.toFixed(2);
        if (!grouped.has(key)) {
            grouped.set(key, {
                hours: entry.hours,
                filters: [],
                order: entry.order
            });
        }

        const group = grouped.get(key);
        group.filters.push(entry.filter);
        group.order = Math.min(group.order, entry.order);
    }

    return Array.from(grouped.values())
        .sort((a, b) => b.hours - a.hours || a.order - b.order);
}

window.destroyImagingPossibilitiesMonthChart = function (canvasId) {
    const existing = window._imagingMonthCharts.get(canvasId);
    if (existing) {
        try { existing.chart.destroy(); } catch (_) {}
        window._imagingMonthCharts.delete(canvasId);
    }

    const canvas = document.getElementById(canvasId);
    if (canvas && typeof Chart !== 'undefined') {
        const chart = Chart.getChart(canvas);
        if (chart) {
            try { chart.destroy(); } catch (_) {}
        }
    }
};

window.createImagingPossibilitiesMonthChart = async function (canvasId, payloadJson, dotNetRef) {
    if (!await ensureImagingChartJsLoaded()) {
        return false;
    }

    const canvas = document.getElementById(canvasId);
    if (!canvas) {
        return false;
    }

    window.destroyImagingPossibilitiesMonthChart(canvasId);

    let payload;
    try {
        payload = typeof payloadJson === 'string' ? JSON.parse(payloadJson) : payloadJson;
    } catch (err) {
        console.error('[ImagingMonthChart] Invalid payload', err);
        return false;
    }

    const filters = payload.filters || [];
    const datasets = [];

    for (let i = 0; i < filters.length; i++) {
        const filter = filters[i];
        datasets.push({
            type: 'bar',
            label: filter,
            data: (payload.filterSeries && payload.filterSeries[filter]) || [],
            yAxisID: 'y',
            stack: 'hours',
            borderWidth: 0,
            borderRadius: 4,
            backgroundColor: imagingFilterColor(filter, 0.8),
            hoverBackgroundColor: imagingFilterColor(filter, 1.0)
        });
    }

    datasets.push({
        type: 'line',
        label: 'Moon %',
        data: payload.moonIllumination || [],
        yAxisID: 'yMoon',
        borderColor: 'rgba(148, 163, 184, 0.95)',
        backgroundColor: 'rgba(148, 163, 184, 0.15)',
        borderWidth: 2,
        pointRadius: 2,
        pointHoverRadius: 4,
        tension: 0.25
    });

    datasets.push({
        type: 'line',
        label: 'Moon °',
        data: payload.moonDistance || [],
        yAxisID: 'yMoon',
        borderColor: 'rgba(245, 158, 11, 0.95)',
        backgroundColor: 'rgba(245, 158, 11, 0.15)',
        borderWidth: 2,
        pointRadius: 2,
        pointHoverRadius: 4,
        borderDash: [6, 4],
        tension: 0.25
    });

    const chart = new Chart(canvas.getContext('2d'), {
        type: 'bar',
        data: {
            labels: payload.labels || [],
            datasets
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            interaction: {
                mode: 'index',
                intersect: false
            },
            onClick: function (_evt, elements) {
                if (!dotNetRef || !elements || elements.length === 0) {
                    return;
                }
                const idx = elements[0].index;
                dotNetRef.invokeMethodAsync('OnImagingMonthChartPointClicked', idx).catch(() => {});
            },
            plugins: {
                legend: {
                    position: 'bottom',
                    onClick: function (_evt, legendItem, legend) {
                        const chartRef = legend.chart;
                        const datasetIndex = legendItem.datasetIndex;
                        const meta = chartRef.getDatasetMeta(datasetIndex);
                        meta.hidden = meta.hidden === null ? !chartRef.data.datasets[datasetIndex].hidden : null;
                        chartRef.update();
                    },
                    labels: {
                        boxWidth: 12,
                        usePointStyle: true,
                        font: { size: 11 },
                        generateLabels: function (chartRef) {
                            const defaultLabels = Chart.defaults.plugins.legend.labels.generateLabels(chartRef);
                            return defaultLabels.map((item) => {
                                if (item.hidden) {
                                    return {
                                        ...item,
                                        text: `${item.text} (disabled)`,
                                        fillStyle: 'rgba(107, 114, 128, 0.25)',
                                        strokeStyle: 'rgba(107, 114, 128, 0.45)',
                                        fontColor: 'rgba(107, 114, 128, 0.95)'
                                    };
                                }
                                return item;
                            });
                        }
                    }
                },
                tooltip: {
                    displayColors: false,
                    filter: function (tooltipItem) {
                        const datasetLabel = tooltipItem?.dataset?.label || '';
                        const groups = getMonthTooltipGroupedFilters(payload, tooltipItem.dataIndex);
                        if (datasetLabel === 'Moon %' || datasetLabel === 'Moon °') {
                            return !groups.length && datasetLabel === 'Moon %';
                        }

                        if (!groups.length) {
                            return tooltipItem.datasetIndex === 0;
                        }

                        const leaderFilter = groups[0].filters[0];
                        return datasetLabel === leaderFilter;
                    },
                    callbacks: {
                        title: function (items) {
                            if (!items || !items.length) return '';
                            return items[0].label;
                        },
                        label: function (context) {
                            const groups = getMonthTooltipGroupedFilters(payload, context.dataIndex);
                            if (!groups.length) {
                                return 'No filter time';
                            }

                            return groups.map(group => `${group.filters.join(' / ')}: ${group.hours}h`);
                        },
                        afterBody: function (items) {
                            if (!items || !items.length) return [];
                            const i = items[0].dataIndex;
                            const win = (payload.windows && payload.windows[i]) ? payload.windows[i] : 'N/A';
                            const moonPct = (payload.moonIllumination && payload.moonIllumination[i] != null) ? payload.moonIllumination[i] : 0;
                            const moonDist = (payload.moonDistance && payload.moonDistance[i] != null) ? payload.moonDistance[i] : 0;
                            return [
                                `Window: ${win}`,
                                `Moon: ${moonPct}% / ${moonDist}°`
                            ];
                        }
                    }
                }
            },
            scales: {
                x: {
                    grid: { display: false }
                },
                y: {
                    position: 'left',
                    stacked: true,
                    beginAtZero: true,
                    title: {
                        display: true,
                        text: 'Hours'
                    }
                },
                yMoon: {
                    position: 'right',
                    beginAtZero: true,
                    suggestedMax: 100,
                    grid: { drawOnChartArea: false },
                    title: {
                        display: true,
                        text: 'Moon % / °'
                    }
                }
            }
        }
    });

    window._imagingMonthCharts.set(canvasId, {
        chart,
        dotNetRef
    });

    return true;
};

window.destroyImagingPossibilitiesYearChart = function (canvasId) {
    const existing = window._imagingYearCharts.get(canvasId);
    if (existing) {
        try { existing.chart.destroy(); } catch (_) {}
        window._imagingYearCharts.delete(canvasId);
    }

    const canvas = document.getElementById(canvasId);
    if (canvas && typeof Chart !== 'undefined') {
        const chart = Chart.getChart(canvas);
        if (chart) {
            try { chart.destroy(); } catch (_) {}
        }
    }
};

window.createImagingPossibilitiesYearChart = async function (canvasId, payloadJson, dotNetRef) {
    if (!await ensureImagingChartJsLoaded()) {
        return false;
    }

    const canvas = document.getElementById(canvasId);
    if (!canvas) {
        return false;
    }

    window.destroyImagingPossibilitiesYearChart(canvasId);

    let payload;
    try {
        payload = typeof payloadJson === 'string' ? JSON.parse(payloadJson) : payloadJson;
    } catch (err) {
        console.error('[ImagingYearChart] Invalid payload', err);
        return false;
    }

    const datasets = [
        {
            type: 'bar',
            label: 'Total hours',
            data: payload.totalHours || [],
            borderWidth: 0,
            borderRadius: 4,
            backgroundColor: 'rgba(59, 130, 246, 0.75)',
            hoverBackgroundColor: 'rgba(59, 130, 246, 1.0)'
        }
    ];

    const chart = new Chart(canvas.getContext('2d'), {
        type: 'bar',
        data: {
            labels: payload.labels || [],
            datasets
        },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            onClick: function (_evt, elements) {
                if (!dotNetRef || !elements || elements.length === 0) {
                    return;
                }

                const idx = elements[0].index;
                dotNetRef.invokeMethodAsync('OnImagingYearChartPointClicked', idx).catch(() => {});
            },
            plugins: {
                legend: {
                    display: false
                },
                tooltip: {
                    callbacks: {
                        label: function (ctx) {
                            const value = ctx.parsed?.y ?? 0;
                            const totalLabel = payload.totalLabel || 'Total';
                            return `${totalLabel}: ${value}h`;
                        }
                    }
                }
            },
            scales: {
                x: {
                    grid: { display: false }
                },
                y: {
                    beginAtZero: true,
                    title: {
                        display: true,
                        text: 'Hours'
                    }
                }
            }
        }
    });

    window._imagingYearCharts.set(canvasId, {
        chart,
        dotNetRef
    });

    return true;
};
