// HFR/Stars Chart using Chart.js for better hover support
// Replaces Syncfusion chart for reliable mouse events

// Guard against multiple loads
if (typeof window._hfrChartLoaded === 'undefined') {
    window._hfrChartLoaded = true;
    window._hfrChartInstances = new Map();
}

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

    if (typeof Chart === 'undefined') {
        throw new Error('Chart.js is not available.');
    }
}

// Create quality chart
window.createHfrStarsChart = async function(canvasId, chartDataJson, dotNetRef, imageListContainerId, enableHoverListSync = true) {
    await ensureChartJsLoaded();
    
    // Double-check Chart is actually available after loading
    if (typeof Chart === 'undefined') {
        console.error('Chart.js failed to load');
        return false;
    }
    
    const canvas = document.getElementById(canvasId);
    if (!canvas) return false;
    
    // Destroy existing chart
    if (window._hfrChartInstances.has(canvasId)) {
        window._hfrChartInstances.get(canvasId).destroy();
        window._hfrChartInstances.delete(canvasId);
    }
    
    const ctx = canvas.getContext('2d');
    const data = typeof chartDataJson === 'string' ? JSON.parse(chartDataJson) : chartDataJson;
    
    const containerWidth = canvas.parentElement?.clientWidth || canvas.clientWidth || 0;
    const isCompactWidth = containerWidth > 0 && containerWidth <= 340;
    const isVeryCompactWidth = containerWidth > 0 && containerWidth <= 290;

    // Scroll helper function (throttled)
    let lastScrollTime = 0;
    function scrollToImage(originalIndex) {
        if (!imageListContainerId) return;
        const now = Date.now();
        if (now - lastScrollTime < 200) return; // Throttle scrolls to every 200ms
        lastScrollTime = now;
        
        const elementId = `${imageListContainerId}_img_${originalIndex}`;
        const el = document.getElementById(elementId);
        if (el) {
            el.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
        }
    }
    
    // Build labels array for X-axis
    const labels = data.points.map((p, i) => i);
    
    // Build datasets
    const datasets = [];
    
    const primaryMetricLabel = data.primaryLabel || 'HFR';
    const showSecondary = !!data.showSecondary;
    const secondaryMetricLabel = data.secondaryLabel || 'Stars';

    // Primary metric line (green, left Y-axis)
    datasets.push({
        label: primaryMetricLabel,
        data: data.points.map(p => p.primary),
        borderColor: '#22c55e',
        backgroundColor: '#22c55e',
        borderWidth: 2,
        fill: false,
        tension: 0.1,
        pointRadius: 3,
        pointHoverRadius: 5,
        pointBackgroundColor: '#22c55e',
        pointBorderColor: '#22c55e',
        pointBorderWidth: 0,
        pointHoverBackgroundColor: '#16a34a',
        pointHoverBorderColor: '#ffffff',
        pointHoverBorderWidth: 1,
        yAxisID: 'yPrimary'
    });
    
    // Secondary metric line (blue, right Y-axis)
    if (showSecondary) {
        datasets.push({
            label: secondaryMetricLabel,
            data: data.points.map(p => p.secondary),
            borderColor: '#3b82f6',
            backgroundColor: '#3b82f6',
            borderWidth: 2,
            fill: false,
            tension: 0.1,
            pointRadius: 3,
            pointHoverRadius: 5,
            pointBackgroundColor: '#3b82f6',
            pointBorderColor: '#3b82f6',
            pointBorderWidth: 0,
            pointHoverBackgroundColor: '#2563eb',
            pointHoverBorderColor: '#ffffff',
            pointHoverBorderWidth: 1,
            yAxisID: 'ySecondary'
        });
    }
    
    // Meta1 line (orange, dashed)
    if (data.showMeta1 && data.meta1Label) {
        datasets.push({
            label: data.meta1Label,
            data: data.points.map(p => p.meta1),
            borderColor: '#f97316',
            backgroundColor: '#f97316',
            borderWidth: 1,
            borderDash: [4, 2],
            fill: false,
            tension: 0.1,
            pointRadius: 3,
            pointHoverRadius: 5,
            pointBackgroundColor: '#f97316',
            pointBorderColor: '#f97316',
            pointBorderWidth: 0,
            pointStyle: 'rectRot',
            yAxisID: 'yMeta1'
        });
    }
    
    // Meta2 line (purple, dashed)
    if (data.showMeta2 && data.meta2Label) {
        datasets.push({
            label: data.meta2Label,
            data: data.points.map(p => p.meta2),
            borderColor: '#a855f7',
            backgroundColor: '#a855f7',
            borderWidth: 1,
            borderDash: [4, 2],
            fill: false,
            tension: 0.1,
            pointRadius: 3,
            pointHoverRadius: 5,
            pointBackgroundColor: '#a855f7',
            pointBorderColor: '#a855f7',
            pointBorderWidth: 0,
            pointStyle: 'rectRot',
            yAxisID: 'yMeta2'
        });
    }
    
    // Build X-axis labels with time
    const xLabels = data.points.map((p, i) => {
        if (isCompactWidth) {
            return p.time;
        }

        if (i === 0 || p.showDate) {
            return p.timeWithDate;
        }
        return p.time;
    });

    const primaryTickFontSize = isCompactWidth ? 10 : 11;
    const secondaryTickFontSize = isCompactWidth ? 10 : 11;
    const xTickFontSize = isVeryCompactWidth ? 9 : 10;
    const xTickLimit = isVeryCompactWidth
        ? 3
        : isCompactWidth
            ? 4
            : data.points.length > 50
                ? 12
                : (data.points.length > 20 ? 8 : data.points.length);
    
    // Build scales
    const scales = {
        x: {
            type: 'category',
            display: true,
            labels: xLabels,
            grid: { display: false },
            ticks: {
                color: '#9ca3af',
                maxRotation: isCompactWidth ? 32 : 45,
                minRotation: isCompactWidth ? 32 : 45,
                padding: isCompactWidth ? 2 : 4,
                font: { size: xTickFontSize },
                autoSkip: true,
                maxTicksLimit: xTickLimit
            },
            border: { display: false }
        },
        yPrimary: {
            type: 'linear',
            display: true,
            position: 'left',
            min: data.primaryMin || 0,
            max: data.primaryMax || 4,
            title: {
                display: !isCompactWidth,
                text: primaryMetricLabel,
                color: '#22c55e',
                font: { size: 11 }
            },
            ticks: {
                color: '#22c55e',
                font: { size: primaryTickFontSize },
                padding: isCompactWidth ? 3 : 6,
                maxTicksLimit: isCompactWidth ? 4 : 6
            },
            grid: { 
                display: true,
                color: 'rgba(55, 65, 81, 0.5)',
                drawBorder: false
            },
            border: { display: false }
        },
    };

    if (showSecondary) {
        scales.ySecondary = {
            type: 'linear',
            display: true,
            position: 'right',
            min: 0,
            title: {
                display: !isCompactWidth,
                text: secondaryMetricLabel,
                color: '#3b82f6',
                font: { size: 11 }
            },
            ticks: {
                color: '#3b82f6',
                font: { size: secondaryTickFontSize },
                padding: isCompactWidth ? 2 : 6,
                maxTicksLimit: isCompactWidth ? 4 : 6
            },
            grid: { display: false },
            border: { display: false }
        };
    }
    
    // Add meta axes if needed - show them on left side below HFR
    if (data.showMeta1 && data.meta1Label) {
        scales.yMeta1 = {
            type: 'linear',
            display: !isCompactWidth,
            position: 'left',
            title: {
                display: !isCompactWidth,
                text: data.meta1Label,
                color: '#f97316',
                font: { size: 9 }
            },
            ticks: {
                color: '#f97316',
                font: { size: 9 }
            },
            grid: { display: false },
            border: { display: false }
        };
    }
    if (data.showMeta2 && data.meta2Label) {
        scales.yMeta2 = {
            type: 'linear',
            display: !isCompactWidth,
            position: 'right',
            title: {
                display: !isCompactWidth,
                text: data.meta2Label,
                color: '#a855f7',
                font: { size: 9 }
            },
            ticks: {
                color: '#a855f7',
                font: { size: 9 }
            },
            grid: { display: false },
            border: { display: false }
        };
    }
    
    // Track last hovered point for leave detection
    let lastHoveredIndex = null;
    let hoverDebounceTimer = null;
    
    // Helper function to find nearest point by x position
    function findNearestPointIndex(chart, mouseX) {
        const chartArea = chart.chartArea;
        if (!chartArea || data.points.length === 0) return -1;
        
        // Calculate relative position within chart area
        const relativeX = mouseX - chartArea.left;
        const chartWidth = chartArea.right - chartArea.left;
        
        // Calculate approximate index based on x position
        const pointSpacing = chartWidth / (data.points.length - 1 || 1);
        let nearestIndex = Math.round(relativeX / pointSpacing);
        
        // Clamp to valid range
        nearestIndex = Math.max(0, Math.min(data.points.length - 1, nearestIndex));
        return nearestIndex;
    }
    
    const chart = new Chart(ctx, {
        type: 'line',
        data: { datasets },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            animation: false,
            layout: {
                padding: {
                    top: isCompactWidth ? 4 : 0,
                    right: isCompactWidth ? 0 : 4,
                    bottom: 0,
                    left: 0
                }
            },
            interaction: {
                mode: 'index',
                intersect: false
            },
            hover: {
                mode: 'index',
                intersect: false
            },
            scales: scales,
            plugins: {
                legend: {
                    display: true,
                    position: 'top',
                    align: 'center',
                    labels: {
                        color: '#9ca3af',
                        usePointStyle: true,
                        pointStyle: 'circle',
                        padding: isCompactWidth ? 6 : 8,
                        font: { size: isCompactWidth ? 8 : 9 },
                        boxWidth: isCompactWidth ? 7 : 8,
                        boxHeight: isCompactWidth ? 7 : 8
                    }
                },
                tooltip: {
                    enabled: true,
                    backgroundColor: 'rgba(0, 0, 0, 0.9)',
                    titleColor: '#ffffff',
                    titleFont: { size: 11, weight: '600' },
                    bodyColor: '#e5e7eb',
                    bodyFont: { size: 10 },
                    borderColor: 'rgba(255,255,255,0.2)',
                    borderWidth: 1,
                    padding: 8,
                    cornerRadius: 6,
                    displayColors: true,
                    callbacks: {
                        title: function(context) {
                            const dataIndex = context[0].dataIndex;
                            if (dataIndex >= 0 && dataIndex < data.points.length) {
                                const point = data.points[dataIndex];
                                return point.tooltipTitle || point.timeWithDate;
                            }
                            return '';
                        },
                        label: function(context) {
                            const label = context.dataset.label || '';
                            const value = context.parsed.y;
                            if (value == null) return '';
                            if (label === primaryMetricLabel) return `${primaryMetricLabel}: ${value.toFixed(2)}`;
                            if (label === secondaryMetricLabel) return `${secondaryMetricLabel}: ${Math.round(value)}`;
                            if (label === 'Eccentricity') return `${label}: ${value.toFixed(3)}`;
                            return `${label}: ${value.toFixed(2)}`;
                        },
                        afterBody: function(context) {
                            const dataIndex = context[0].dataIndex;
                            if (dataIndex >= 0 && dataIndex < data.points.length) {
                                const point = data.points[dataIndex];
                                const lines = [];
                                if (point.filter) lines.push(`Filter: ${point.filter}`);
                                if (point.exposure) lines.push(`Exp: ${point.exposure}s`);
                                if (point.gain != null) lines.push(`Gain: ${point.gain}`);
                                if (point.cameraTemp != null) lines.push(`Temp: ${point.cameraTemp.toFixed(0)}°C`);
                                return lines;
                            }
                            return [];
                        }
                    }
                }
            },
            onClick: function(event, elements, chart) {
                if (elements && elements.length > 0) {
                    const element = elements[0];
                    const dataIndex = element.index;
                    if (dataIndex >= 0 && dataIndex < data.points.length) {
                        const originalIndex = data.points[dataIndex].originalIndex;
                        if (dotNetRef) {
                            dotNetRef.invokeMethodAsync('OnChartClick', originalIndex);
                        }
                    }
                }
            }
        }
    });
    
    // Throttled mousemove handler - only process every 100ms max
    let lastMoveTime = 0;
    let pendingMoveEvent = null;
    let moveThrottleTimer = null;
    
    function processMouseMove(mouseX, mouseY) {
        const chartArea = chart.chartArea;
        if (!chartArea || data.points.length === 0) return;
        
        // Check if mouse is inside chart area
        const isInsideChart = mouseX >= chartArea.left && mouseX <= chartArea.right &&
                              mouseY >= chartArea.top && mouseY <= chartArea.bottom;
        
        if (isInsideChart) {
            // Find nearest point by x position
            const dataIndex = findNearestPointIndex(chart, mouseX);
            if (dataIndex >= 0 && dataIndex < data.points.length) {
                const originalIndex = data.points[dataIndex].originalIndex;
                // Only update if index actually changed
                if (lastHoveredIndex !== originalIndex) {
                    lastHoveredIndex = originalIndex;
                    if (enableHoverListSync) {
                        // Handle highlighting purely in JS - no Blazor interop
                        highlightImageInList(originalIndex);
                        scrollToImage(originalIndex);
                    }
                }
            }
            canvas.style.cursor = 'pointer';
        } else {
            if (lastHoveredIndex !== null) {
                lastHoveredIndex = null;
                if (enableHoverListSync) {
                    clearImageHighlight();
                }
            }
            canvas.style.cursor = 'default';
        }
    }
    
    // Pure JS image highlighting - no Blazor calls
    function highlightImageInList(index) {
        if (!imageListContainerId) return;
        // Clear previous highlight
        clearImageHighlight();
        // Add highlight to current
        const el = document.getElementById(`${imageListContainerId}_img_${index}`);
        if (el) {
            el.classList.add('bg-blue-100', 'dark:bg-blue-900/50', 'ring-2', 'ring-blue-500');
            el.dataset.chartHighlight = 'true';
        }
    }
    
    function clearImageHighlight() {
        if (!imageListContainerId) return;
        const highlighted = document.querySelector(`[data-chart-highlight="true"]`);
        if (highlighted) {
            highlighted.classList.remove('bg-blue-100', 'dark:bg-blue-900/50', 'ring-2', 'ring-blue-500');
            delete highlighted.dataset.chartHighlight;
        }
    }
    
    canvas.addEventListener('mousemove', function(e) {
        const now = Date.now();
        const rect = canvas.getBoundingClientRect();
        const mouseX = e.clientX - rect.left;
        const mouseY = e.clientY - rect.top;
        
        // Throttle: only process if 150ms has passed (reduce Blazor interop frequency)
        if (now - lastMoveTime >= 150) {
            lastMoveTime = now;
            processMouseMove(mouseX, mouseY);
        } else {
            // Schedule processing for later if we're throttled
            pendingMoveEvent = { mouseX, mouseY };
            if (!moveThrottleTimer) {
                moveThrottleTimer = setTimeout(() => {
                    moveThrottleTimer = null;
                    if (pendingMoveEvent) {
                        lastMoveTime = Date.now();
                        processMouseMove(pendingMoveEvent.mouseX, pendingMoveEvent.mouseY);
                        pendingMoveEvent = null;
                    }
                }, 150 - (now - lastMoveTime));
            }
        }
    });
    
    // Add mouseleave handler for reliable leave detection
    canvas.addEventListener('mouseleave', function() {
        clearTimeout(moveThrottleTimer);
        moveThrottleTimer = null;
        pendingMoveEvent = null;
        if (lastHoveredIndex !== null) {
            lastHoveredIndex = null;
            if (enableHoverListSync) {
                clearImageHighlight();
            }
        }
        canvas.style.cursor = 'default';
    });
    
    window._hfrChartInstances.set(canvasId, chart);
    return true;
};

// Update chart data
window.updateHfrStarsChart = async function(canvasId, chartDataJson, dotNetRef) {
    // For simplicity, recreate the chart
    return await window.createHfrStarsChart(canvasId, chartDataJson, dotNetRef);
};

// Destroy chart
window.destroyHfrStarsChart = function(canvasId) {
    if (window._hfrChartInstances.has(canvasId)) {
        window._hfrChartInstances.get(canvasId).destroy();
        window._hfrChartInstances.delete(canvasId);
        return true;
    }
    return false;
};
