// Results Viewer JavaScript with Advanced Plotting

let currentResults = null;
let currentResultName = null;
let currentCharts = {}; // Store chart instances for updates

// --- Multi-bias results state ---
let biasResults = null;       // {bias_points: [...], results: {...}, has_bias_sweep: bool}
let biasAnimationTimer = null;

// Initialize on page load
$(document).ready(function() {
    loadResultsList();
    bindEvents();
});

function bindEvents() {
    // Refresh results button
    $('#refreshResultsBtn').click(function() {
        loadResultsList();
    });

    // Plot type selector
    $('input[name="plotType"]').change(function() {
        if (currentResults) {
            displayPlots(currentResults, $(this).val());
        }
    });

    // Download results button
    $('#downloadResultsBtn').click(function() {
        downloadResults();
    });

    // Export plots button
    $('#exportPlotsBtn').click(function() {
        const modal = new bootstrap.Modal($('#exportModal')[0]);
        modal.show();
    });

    // Confirm export button
    $('#confirmExportBtn').click(function() {
        exportPlots();
    });

    // Advanced plot settings handlers
    $('input[name="yScale"]').change(function() {
        updateAllPlots();
    });

    $('#showGrid').change(function() {
        updateAllPlots();
    });

    $('#showLegend').change(function() {
        updateAllPlots();
    });

    $('#lineWidth').on('input', function() {
        $('#lineWidthValue').text($(this).val());
        updateAllPlots();
    });

    $('#resetPlotBtn').click(function() {
        resetPlotSettings();
    });

    // Wavefunction toggle for "All" mode
    $('#showWavefunctions').change(function() {
        updateAllPlots();
    });

    // Split band view toggle
    $('#splitBandView').change(function() {
        updateAllPlots();
    });
}

// Load list of available results
function loadResultsList() {
    $('#resultsList').html(showLoading('Loading results...'));

    $.ajax({
        url: '/api/results/list',
        method: 'GET',
        success: function(response) {
            if (response.success) {
                displayResultsList(response.results);
            } else {
                $('#resultsList').html(showError('Failed to load results'));
            }
        },
        error: function(xhr) {
            $('#resultsList').html(showError('Error loading results'));
        }
    });
}

function displayResultsList(results) {
    const $list = $('#resultsList');
    $list.empty();

    // Filter out _St files (intermediate Schrödinger files)
    results = results.filter(r => !r.name.includes('_St'));

    if (results.length === 0) {
        $list.html(`
            <div class="p-3 text-center text-muted">
                <i class="bi bi-inbox"></i><br>
                No simulation results yet
            </div>
        `);
        return;
    }

    results.forEach((result, index) => {
        const timestamp = formatTimestamp(result.timestamp);
        const displayName = result.folder
            ? `${result.folder} / ${result.name}`
            : result.name;

        const item = $(`
            <a href="#" class="list-group-item list-group-item-action result-item"
               data-name="${result.name}" data-folder="${result.folder || ''}">
                <div class="d-flex justify-content-between align-items-start">
                    <div class="flex-grow-1">
                        <div class="result-name">${displayName}</div>
                        <div class="result-timestamp">${timestamp}</div>
                    </div>
                    <button class="btn btn-sm btn-outline-danger delete-result-btn"
                            data-name="${result.name}" data-folder="${result.folder || ''}" title="Delete">
                        <i class="bi bi-trash"></i>
                    </button>
                </div>
            </a>
        `);

        item.click(function(e) {
            if ($(e.target).closest('.delete-result-btn').length > 0) return;
            e.preventDefault();
            $('.result-item').removeClass('active');
            $(this).addClass('active');
            loadResults(result.name, result.folder);
        });

        item.find('.delete-result-btn').click(function(e) {
            e.preventDefault();
            e.stopPropagation();
            deleteSimulation($(this).data('name'), $(this).data('folder'));
        });

        $list.append(item);

        if (index === 0) {
            item.addClass('active');
            loadResults(result.name, result.folder);
        }
    });
}

// Load specific result
function loadResults(name, folder) {
    currentResultName = name;

    $('#plotsContainer').html(showLoading('Loading simulation data...'));

    let url = `/api/results/import/${name}`;
    if (folder) {
        url += `?folder=${encodeURIComponent(folder)}`;
    }

    $.ajax({
        url: url,
        method: 'GET',
        success: function(response) {
            if (response.success) {
                currentResults = response.results;

                // --- Check for multi-bias results ---
                checkForBiasResults(name);

                displayResults(currentResults);
            } else {
                $('#plotsContainer').html(showError('Failed to load results'));
            }
        },
        error: function(xhr) {
            $('#plotsContainer').html(showError('Error loading results'));
        }
    });
}

function displayResults(results) {
    // Show info card
    $('#resultInfoCard').show();
    displayResultInfo(results);

    // Show plot settings card
    $('#plotSettingsCard').show();

    // Show actions card
    $('#resultActionsCard').show();

    // Display plots
    const plotType = $('input[name="plotType"]:checked').val();
    displayPlots(results, plotType);

    // Display eigenvalues if available
    if (results.el_eigenvalues && results.el_eigenvalues.length > 0) {
        displayEigenvalues(results);
        $('#eigenvaluesCard').show();
    }

    // Display C-V data if available
    if (results.cv_voltage && results.cv_voltage.length > 0) {
        displayCVInfo(results);
        $('#cvDataCard').show();
    } else {
        $('#cvDataCard').hide();
    }

    // Display data table
    displayDataTable(results);
    $('#dataExportCard').show();
}

function displayResultInfo(results) {
    let convergence = results.convergence_good ?
        '<span class="badge bg-success">Converged</span>' :
        '<span class="badge bg-warning">Convergence Issues</span>';

    let info = `
        <div class="mb-2">
            <strong>Status:</strong> ${convergence}
        </div>
        <div class="mb-2">
            <strong>Grid Points:</strong> ${results.y.length}
        </div>
        <div class="mb-2">
            <strong>Position Range:</strong> ${results.y[0].toFixed(1)} - ${results.y[results.y.length-1].toFixed(1)} nm
        </div>
    `;

    if (results.el_eigenvalues && results.el_eigenvalues.length > 0) {
        info += `
            <div class="mb-2">
                <strong>Electron States:</strong> ${results.el_eigenvalues.length}
            </div>
        `;
    }

    if (results.hh_eigenvalues && results.hh_eigenvalues.length > 0) {
        info += `
            <div class="mb-2">
                <strong>Hole States:</strong> ${results.hh_eigenvalues.length}
            </div>
        `;
    }

    $('#resultInfo').html(info);
}

function displayPlots(results, plotType) {
    // Destroy existing charts
    Object.values(currentCharts).forEach(chart => {
        if (chart) chart.destroy();
    });
    currentCharts = {};

    $('#plotsContainer').empty();

    // Create canvas elements for plots
    if (plotType === 'all') {
        createAllPlots(results);
    } else if (plotType === 'band') {
        createBandPlot(results);
    } else if (plotType === 'charge') {
        createChargePlot(results);
    } else if (plotType === 'wave') {
        createWavePlot(results);
    } else if (plotType === 'cv') {
        createCVPlot(results);
    }
}

// Get common chart options with current settings
function getChartOptions(title, xLabel, yLabel, useLogScale) {
    const yScale = $('input[name="yScale"]:checked').val();
    const showGrid = $('#showGrid').is(':checked');
    const showLegend = $('#showLegend').is(':checked');
    const lineWidth = parseFloat($('#lineWidth').val()) || 2;

    // Override yScale if plot type requires log (like charge density)
    const finalYScale = useLogScale ? 'logarithmic' : yScale;

    const yAxisConfig = {
        type: finalYScale,
        title: {
            display: true,
            text: yLabel
        },
        grid: {
            display: showGrid
        }
    };

    // Add scientific notation formatting for log scale
    if (finalYScale === 'logarithmic') {
        yAxisConfig.ticks = {
            callback: function(value, index, values) {
                // Format in scientific notation like 1e18
                if (value === 0) return '0';
                const exponent = Math.floor(Math.log10(value));
                const mantissa = value / Math.pow(10, exponent);
                if (Math.abs(mantissa - 1.0) < 0.01) {
                    return '1e' + exponent;
                }
                return mantissa.toFixed(1) + 'e' + exponent;
            }
        };
    }

    return {
        responsive: true,
        maintainAspectRatio: true,
        interaction: {
            mode: 'nearest',
            intersect: false,
        },
        plugins: {
            title: {
                display: true,
                text: title,
                font: { size: 16, weight: 'bold' }
            },
            legend: {
                display: showLegend,
                position: 'top'
            },
            tooltip: {
                enabled: true,
                callbacks: {
                    label: function(context) {
                        let label = context.dataset.label || '';
                        if (label) {
                            label += ': ';
                        }
                        if (finalYScale === 'logarithmic') {
                            label += context.parsed.y.toExponential(2);
                        } else {
                            label += context.parsed.y.toFixed(4);
                        }
                        return label;
                    }
                }
            },
            zoom: {
                pan: {
                    enabled: true,
                    mode: 'xy',
                },
                zoom: {
                    wheel: {
                        enabled: true,
                    },
                    pinch: {
                        enabled: true
                    },
                    mode: 'xy',
                }
            }
        },
        scales: {
            x: {
                title: {
                    display: true,
                    text: xLabel
                },
                ticks: {
                    maxTicksLimit: 10
                },
                grid: {
                    display: showGrid
                }
            },
            y: yAxisConfig
        }
    };
}

function createBandPlot(results) {
    const lineWidth = parseFloat($('#lineWidth').val()) || 2;
    const showWavefunctions = $('#showWavefunctions') && $('#showWavefunctions').is(':checked');
    const splitBandView = $('#splitBandView') && $('#splitBandView').is(':checked');
    const hasWavefunctions = results.y_wave && results.y_wave.length > 0 &&
        ((results.el_wavefunctions && results.el_wavefunctions.length > 0) ||
         (results.hh_wavefunctions && results.hh_wavefunctions.length > 0));

    if (splitBandView) {
        // Create two separate subplots vertically stacked
        const container = $('<div class="row"></div>');
        const col1 = $('<div class="col-12 mb-3"></div>');
        const canvas1 = $('<canvas id="bandPlotEc"></canvas>');
        col1.append(canvas1);
        container.append(col1);

        const col2 = $('<div class="col-12 mb-3"></div>');
        const canvas2 = $('<canvas id="bandPlotEv"></canvas>');
        col2.append(canvas2);
        container.append(col2);

        $('#plotsContainer').append(container);

        // Datasets for Ec plot (without Ef to maximize space)
        const datasetsEc = [
            {
                label: 'Ec',
                data: results.Ec,
                borderColor: 'rgb(0, 0, 255)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 0
            }
        ];

        // Collect all data for Ec y-axis calculation
        const ecDataForRange = [...results.Ec];

        // Add electron ground state if needed
        if (showWavefunctions && hasWavefunctions && results.el_eigenvalues && results.el_eigenvalues.length > 0 &&
            results.el_wavefunctions && results.el_wavefunctions.length > 0) {
            const E0 = results.el_eigenvalues[0];
            const psi0 = results.el_wavefunctions.map(row => row[0]);
            const wavefunctionData = results.y_wave.map((y, i) => E0 + (psi0[i] || 0) * 0.5);

            datasetsEc.push({
                label: `e⁻ Ground State`,
                data: wavefunctionData,
                borderColor: 'rgb(30, 144, 255)',  // Dodger blue
                borderWidth: lineWidth * 1.2,
                borderDash: [2, 2],
                fill: false,
                pointRadius: 0
            });

            // Add wavefunction data to range calculation
            ecDataForRange.push(...wavefunctionData);
        }

        // Datasets for Ev plot (without Ef to maximize space)
        const datasetsEv = [
            {
                label: 'Ev',
                data: results.Ev,
                borderColor: 'rgb(255, 0, 0)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 0
            }
        ];

        // Collect all data for Ev y-axis calculation
        const evDataForRange = [...results.Ev];

        // Add hole ground state if needed
        if (showWavefunctions && hasWavefunctions && results.hh_eigenvalues && results.hh_eigenvalues.length > 0 &&
            results.hh_wavefunctions && results.hh_wavefunctions.length > 0) {
            const E0 = results.hh_eigenvalues[0];
            const psi0 = results.hh_wavefunctions.map(row => row[0]);
            const wavefunctionData = results.y_wave.map((y, i) => E0 - (psi0[i] || 0) * 0.5);

            datasetsEv.push({
                label: `h⁺ Ground State`,
                data: wavefunctionData,
                borderColor: 'rgb(220, 20, 60)',  // Crimson
                borderWidth: lineWidth * 1.2,
                borderDash: [2, 2],
                fill: false,
                pointRadius: 0
            });

            // Add wavefunction data to range calculation
            evDataForRange.push(...wavefunctionData);
        }

        // Calculate y-axis ranges with ±10% margins (without Ef for maximum space)
        const xLabels = showWavefunctions && hasWavefunctions ? results.y_wave : results.y;

        const minEc = Math.min(...ecDataForRange);
        const maxEc = Math.max(...ecDataForRange);
        const rangeEc = maxEc - minEc;
        const yMinEc = minEc - 0.1 * rangeEc;
        const yMaxEc = maxEc + 0.1 * rangeEc;

        const minEv = Math.min(...evDataForRange);
        const maxEv = Math.max(...evDataForRange);
        const rangeEv = maxEv - minEv;
        const yMinEv = minEv - 0.1 * rangeEv;
        const yMaxEv = maxEv + 0.1 * rangeEv;

        // Create Ec chart
        const ctx1 = canvas1[0].getContext('2d');
        const optionsEc = getChartOptions('Conduction Band', 'Position (nm)', 'Energy (eV)', false);
        optionsEc.scales.y.min = yMinEc;
        optionsEc.scales.y.max = yMaxEc;

        const chart1 = new Chart(ctx1, {
            type: 'line',
            data: { labels: xLabels, datasets: datasetsEc },
            options: optionsEc
        });

        // Create Ev chart
        const ctx2 = canvas2[0].getContext('2d');
        const optionsEv = getChartOptions('Valence Band', 'Position (nm)', 'Energy (eV)', false);
        optionsEv.scales.y.min = yMinEv;
        optionsEv.scales.y.max = yMaxEv;

        const chart2 = new Chart(ctx2, {
            type: 'line',
            data: { labels: xLabels, datasets: datasetsEv },
            options: optionsEv
        });

        currentCharts.bandEc = chart1;
        currentCharts.bandEv = chart2;

    } else {
        // Standard single plot
        const canvas = $('<canvas id="bandPlot" style="max-width: 100%;"></canvas>');
        $('#plotsContainer').append(canvas);

        const datasets = [
            {
                label: 'Conduction Band',
                data: results.Ec,
                borderColor: 'rgb(0, 0, 255)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 0
            },
            {
                label: 'Valence Band',
                data: results.Ev,
                borderColor: 'rgb(255, 0, 0)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 0
            },
            {
                label: 'Fermi Level',
                data: results.Ef,
                borderColor: 'rgb(0, 128, 0)',
                borderWidth: lineWidth * 0.75,
                borderDash: [5, 5],
                fill: false,
                pointRadius: 0
            }
        ];

        // Add wavefunctions if enabled
        if (showWavefunctions && hasWavefunctions) {
            // Add electron ground state with blue tone
            if (results.el_eigenvalues && results.el_eigenvalues.length > 0 &&
                results.el_wavefunctions && results.el_wavefunctions.length > 0) {
                const E0 = results.el_eigenvalues[0];
                const psi0 = results.el_wavefunctions.map(row => row[0]);
                datasets.push({
                    label: `e⁻ Ground State`,
                    data: results.y_wave.map((y, i) => E0 + (psi0[i] || 0) * 0.5),
                    borderColor: 'rgb(30, 144, 255)',  // Dodger blue
                    borderWidth: lineWidth * 1.2,
                    borderDash: [2, 2],
                    fill: false,
                    pointRadius: 0
                });
            }

            // Add hole ground state with red tone
            if (results.hh_eigenvalues && results.hh_eigenvalues.length > 0 &&
                results.hh_wavefunctions && results.hh_wavefunctions.length > 0) {
                const E0 = results.hh_eigenvalues[0];
                const psi0 = results.hh_wavefunctions.map(row => row[0]);
                datasets.push({
                    label: `h⁺ Ground State`,
                    data: results.y_wave.map((y, i) => E0 - (psi0[i] || 0) * 0.5),
                    borderColor: 'rgb(220, 20, 60)',  // Crimson
                    borderWidth: lineWidth * 1.2,
                    borderDash: [2, 2],
                    fill: false,
                    pointRadius: 0
                });
            }
        }

        const ctx = canvas[0].getContext('2d');
        const chart = new Chart(ctx, {
            type: 'line',
            data: {
                labels: showWavefunctions && hasWavefunctions ? results.y_wave : results.y,
                datasets: datasets
            },
            options: getChartOptions('Band Structure', 'Position (nm)', 'Energy (eV)', false)
        });

        currentCharts.band = chart;
    }
}

function createChargePlot(results) {
    const canvas = $('<canvas id="chargePlot" style="max-width: 100%;"></canvas>');
    $('#plotsContainer').append(canvas);

    const lineWidth = parseFloat($('#lineWidth').val()) || 2;

    const ctx = canvas[0].getContext('2d');
    const chart = new Chart(ctx, {
        type: 'line',
        data: {
            labels: results.y,
            datasets: [
                {
                    label: 'Electrons (n)',
                    data: results.n,
                    borderColor: 'rgb(0, 0, 200)',
                    borderWidth: lineWidth,
                    fill: false,
                    pointRadius: 0
                },
                {
                    label: 'Holes (p)',
                    data: results.p,
                    borderColor: 'rgb(200, 0, 0)',
                    borderWidth: lineWidth,
                    fill: false,
                    pointRadius: 0
                }
            ]
        },
        options: getChartOptions('Charge Density', 'Position (nm)', 'Carrier Density (cm⁻³)', true)
    });

    currentCharts.charge = chart;
}

function createAllPlots(results) {
    const container = $('<div class="row"></div>');

    // Band structure
    const col1 = $('<div class="col-md-6 mb-3"></div>');
    const canvas1 = $('<canvas id="bandPlot"></canvas>');
    col1.append(canvas1);
    container.append(col1);

    // Charge density
    const col2 = $('<div class="col-md-6 mb-3"></div>');
    const canvas2 = $('<canvas id="chargePlot"></canvas>');
    col2.append(canvas2);
    container.append(col2);

    $('#plotsContainer').append(container);

    // Create individual plots
    const lineWidth = parseFloat($('#lineWidth').val()) || 2;

    // Check if wavefunctions should be shown and are available
    const showWavefunctions = $('#showWavefunctions') && $('#showWavefunctions').is(':checked');
    const hasWavefunctions = results.y_wave && results.y_wave.length > 0 &&
        ((results.el_wavefunctions && results.el_wavefunctions.length > 0) ||
         (results.hh_wavefunctions && results.hh_wavefunctions.length > 0));

    // Band plot datasets
    const bandDatasets = [
        {
            label: 'Ec',
            data: results.Ec,
            borderColor: 'rgb(0, 0, 255)',
            borderWidth: lineWidth,
            fill: false,
            pointRadius: 0
        },
        {
            label: 'Ev',
            data: results.Ev,
            borderColor: 'rgb(255, 0, 0)',
            borderWidth: lineWidth,
            fill: false,
            pointRadius: 0
        },
        {
            label: 'Ef',
            data: results.Ef,
            borderColor: 'rgb(0, 128, 0)',
            borderWidth: lineWidth * 0.75,
            borderDash: [5, 5],
            fill: false,
            pointRadius: 0
        }
    ];

    // Add wavefunctions to band plot if enabled
    if (showWavefunctions && hasWavefunctions) {
        // Add electron ground state with dotted line (blue tone)
        if (results.el_eigenvalues && results.el_eigenvalues.length > 0 &&
            results.el_wavefunctions && results.el_wavefunctions.length > 0) {
            const E0 = results.el_eigenvalues[0];
            // Extract first column (ground state) from 2D array
            const psi0 = results.el_wavefunctions.map(row => row[0]);
            bandDatasets.push({
                label: `e⁻ Ground State`,
                data: results.y_wave.map((y, i) => E0 + (psi0[i] || 0) * 0.5),
                borderColor: 'rgb(30, 144, 255)',  // Dodger blue
                borderWidth: lineWidth * 1.2,
                borderDash: [2, 2],  // Dotted line
                fill: false,
                pointRadius: 0
            });
        }

        // Add hole ground state with dotted line (red tone)
        if (results.hh_eigenvalues && results.hh_eigenvalues.length > 0 &&
            results.hh_wavefunctions && results.hh_wavefunctions.length > 0) {
            const E0 = results.hh_eigenvalues[0];
            // Extract first column (ground state) from 2D array
            const psi0 = results.hh_wavefunctions.map(row => row[0]);
            bandDatasets.push({
                label: `h⁺ Ground State`,
                data: results.y_wave.map((y, i) => E0 - (psi0[i] || 0) * 0.5),
                borderColor: 'rgb(220, 20, 60)',  // Crimson
                borderWidth: lineWidth * 1.2,
                borderDash: [2, 2],  // Dotted line
                fill: false,
                pointRadius: 0
            });
        }
    }

    // Band plot
    const ctx1 = canvas1[0].getContext('2d');
    const chart1 = new Chart(ctx1, {
        type: 'line',
        data: {
            labels: showWavefunctions && hasWavefunctions ? results.y_wave : results.y,
            datasets: bandDatasets
        },
        options: getChartOptions('Band Structure', 'Position (nm)', 'Energy (eV)', false)
    });

    // Charge plot
    const ctx2 = canvas2[0].getContext('2d');
    const chart2 = new Chart(ctx2, {
        type: 'line',
        data: {
            labels: results.y,
            datasets: [
                {
                    label: 'n',
                    data: results.n,
                    borderColor: 'rgb(0, 0, 200)',
                    borderWidth: lineWidth,
                    fill: false,
                    pointRadius: 0
                },
                {
                    label: 'p',
                    data: results.p,
                    borderColor: 'rgb(200, 0, 0)',
                    borderWidth: lineWidth,
                    fill: false,
                    pointRadius: 0
                }
            ]
        },
        options: getChartOptions('Charge Density', 'Position (nm)', 'Carrier Density (cm⁻³)', true)
    });

    currentCharts.band = chart1;
    currentCharts.charge = chart2;
}

function createWavePlot(results) {
    const $container = $('#plotsContainer');

    // Check if wavefunction data exists
    if (!results.y_wave || results.y_wave.length === 0 ||
        ((!results.el_wavefunctions || results.el_wavefunctions.length === 0) &&
         (!results.hh_wavefunctions || results.hh_wavefunctions.length === 0))) {
        $container.html('<div class="alert alert-info"><i class="bi bi-info-circle"></i> No wavefunction data available. Run simulation in Schrödinger-Poisson mode to see wavefunctions.</div>');
        return;
    }

    const lineWidth = parseFloat($('#lineWidth').val()) || 2;
    const splitBandView = $('#splitBandView') && $('#splitBandView').is(':checked');

    // Get x-axis range from data
    const xMin = Math.min(...results.y_wave);
    const xMax = Math.max(...results.y_wave);

    if (splitBandView) {
        // Create two separate subplots vertically stacked
        const container = $('<div class="row"></div>');
        const col1 = $('<div class="col-12 mb-3"></div>');
        const canvas1 = $('<canvas id="wavePlotEc"></canvas>');
        col1.append(canvas1);
        container.append(col1);

        const col2 = $('<div class="col-12 mb-3"></div>');
        const canvas2 = $('<canvas id="wavePlotEv"></canvas>');
        col2.append(canvas2);
        container.append(col2);

        $container.append(container);

        // Datasets for Ec plot (conduction band + electron wavefunctions)
        const datasetsEc = [
            {
                label: 'Conduction Band',
                data: results.y.map((y, i) => ({x: y, y: results.Ec[i]})),
                borderColor: 'rgb(0, 0, 255)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 0
            }
        ];

        // Collect data for y-axis range
        const ecDataForRange = [...results.Ec];

        // Add electron wavefunctions
        if (results.el_wavefunctions && results.el_wavefunctions.length > 0 && results.el_eigenvalues) {
            const numElStates = Math.min(results.el_eigenvalues.length, 5);
            const numCols = results.el_wavefunctions[0] ? results.el_wavefunctions[0].length : 0;

            for (let i = 0; i < numElStates && i < numCols; i++) {
                const E = results.el_eigenvalues[i];
                const psi = results.el_wavefunctions.map(row => row[i]);

                if (psi.length > 0) {
                    const blueShade = 30 + i * 30;
                    const wavefunctionData = results.y_wave.map((y, j) => ({x: y, y: E + (psi[j] || 0) * 0.5}));

                    datasetsEc.push({
                        label: `e⁻ E${i+1} (${E.toFixed(3)} eV)`,
                        data: wavefunctionData,
                        borderColor: `rgb(${blueShade}, ${blueShade + 100}, 255)`,
                        borderWidth: lineWidth,
                        borderDash: [2, 2],
                        fill: false,
                        pointRadius: 0
                    });

                    // Add to range calculation
                    wavefunctionData.forEach(point => ecDataForRange.push(point.y));
                }
            }
        }

        // Datasets for Ev plot (valence band + hole wavefunctions)
        const datasetsEv = [
            {
                label: 'Valence Band',
                data: results.y.map((y, i) => ({x: y, y: results.Ev[i]})),
                borderColor: 'rgb(255, 0, 0)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 0
            }
        ];

        // Collect data for y-axis range
        const evDataForRange = [...results.Ev];

        // Add hole wavefunctions
        if (results.hh_wavefunctions && results.hh_wavefunctions.length > 0 && results.hh_eigenvalues) {
            const numHhStates = Math.min(results.hh_eigenvalues.length, 5);
            const numCols = results.hh_wavefunctions[0] ? results.hh_wavefunctions[0].length : 0;

            for (let i = 0; i < numHhStates && i < numCols; i++) {
                const E = results.hh_eigenvalues[i];
                const psi = results.hh_wavefunctions.map(row => row[i]);

                if (psi.length > 0) {
                    const redShade = 30 + i * 30;
                    const wavefunctionData = results.y_wave.map((y, j) => ({x: y, y: E - (psi[j] || 0) * 0.5}));

                    datasetsEv.push({
                        label: `h⁺ E${i+1} (${E.toFixed(3)} eV)`,
                        data: wavefunctionData,
                        borderColor: `rgb(255, ${redShade}, ${redShade})`,
                        borderWidth: lineWidth,
                        borderDash: [2, 2],
                        fill: false,
                        pointRadius: 0
                    });

                    // Add to range calculation
                    wavefunctionData.forEach(point => evDataForRange.push(point.y));
                }
            }
        }

        // Calculate y-axis ranges with ±10% margins
        const minEc = Math.min(...ecDataForRange);
        const maxEc = Math.max(...ecDataForRange);
        const rangeEc = maxEc - minEc;
        const yMinEc = minEc - 0.1 * rangeEc;
        const yMaxEc = maxEc + 0.1 * rangeEc;

        const minEv = Math.min(...evDataForRange);
        const maxEv = Math.max(...evDataForRange);
        const rangeEv = maxEv - minEv;
        const yMinEv = minEv - 0.1 * rangeEv;
        const yMaxEv = maxEv + 0.1 * rangeEv;

        // Create Ec chart
        const ctx1 = canvas1[0].getContext('2d');
        const optionsEc = getChartOptions('Conduction Band + Electron Wavefunctions', 'Position (nm)', 'Energy (eV)', false);
        optionsEc.parsing = { xAxisKey: 'x', yAxisKey: 'y' };
        optionsEc.scales.x = {
            type: 'linear',
            title: { display: true, text: 'Position (nm)' },
            min: xMin,
            max: xMax,
            ticks: { maxTicksLimit: 10 },
            grid: { display: $('#showGrid').is(':checked') }
        };
        optionsEc.scales.y.min = yMinEc;
        optionsEc.scales.y.max = yMaxEc;

        const chart1 = new Chart(ctx1, {
            type: 'line',
            data: { datasets: datasetsEc },
            options: optionsEc
        });

        // Create Ev chart
        const ctx2 = canvas2[0].getContext('2d');
        const optionsEv = getChartOptions('Valence Band + Hole Wavefunctions', 'Position (nm)', 'Energy (eV)', false);
        optionsEv.parsing = { xAxisKey: 'x', yAxisKey: 'y' };
        optionsEv.scales.x = {
            type: 'linear',
            title: { display: true, text: 'Position (nm)' },
            min: xMin,
            max: xMax,
            ticks: { maxTicksLimit: 10 },
            grid: { display: $('#showGrid').is(':checked') }
        };
        optionsEv.scales.y.min = yMinEv;
        optionsEv.scales.y.max = yMaxEv;

        const chart2 = new Chart(ctx2, {
            type: 'line',
            data: { datasets: datasetsEv },
            options: optionsEv
        });

        currentCharts.waveEc = chart1;
        currentCharts.waveEv = chart2;

    } else {
        // Standard single plot
        const canvas = $('<canvas id="wavePlot" style="max-width: 100%;"></canvas>');
        $container.append(canvas);

        const datasets = [];

        // Add band edges for reference (consistent colors with other plots)
        if (results.Ec && results.Ec.length > 0) {
            datasets.push({
                label: 'Conduction Band',
                data: results.y.map((y, i) => ({x: y, y: results.Ec[i]})),
                borderColor: 'rgb(0, 0, 255)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 0
            });
            datasets.push({
                label: 'Valence Band',
                data: results.y.map((y, i) => ({x: y, y: results.Ev[i]})),
                borderColor: 'rgb(255, 0, 0)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 0
            });
            datasets.push({
                label: 'Fermi Level',
                data: results.y.map((y, i) => ({x: y, y: results.Ef[i]})),
                borderColor: 'rgb(0, 128, 0)',
                borderWidth: lineWidth * 0.75,
                borderDash: [5, 5],
                fill: false,
                pointRadius: 0
            });
        }

        // Add electron wavefunctions
        if (results.el_wavefunctions && results.el_wavefunctions.length > 0 && results.el_eigenvalues) {
            const numElStates = Math.min(results.el_eigenvalues.length, 5);
            const numCols = results.el_wavefunctions[0] ? results.el_wavefunctions[0].length : 0;

            for (let i = 0; i < numElStates && i < numCols; i++) {
                const E = results.el_eigenvalues[i];
                const psi = results.el_wavefunctions.map(row => row[i]);

                if (psi.length > 0) {
                    const blueShade = 30 + i * 30;
                    datasets.push({
                        label: `e⁻ E${i+1} (${E.toFixed(3)} eV)`,
                        data: results.y_wave.map((y, j) => ({x: y, y: E + (psi[j] || 0) * 0.5})),
                        borderColor: `rgb(${blueShade}, ${blueShade + 100}, 255)`,
                        borderWidth: lineWidth,
                        borderDash: [2, 2],
                        fill: false,
                        pointRadius: 0
                    });
                }
            }
        }

        // Add hole wavefunctions
        if (results.hh_wavefunctions && results.hh_wavefunctions.length > 0 && results.hh_eigenvalues) {
            const numHhStates = Math.min(results.hh_eigenvalues.length, 5);
            const numCols = results.hh_wavefunctions[0] ? results.hh_wavefunctions[0].length : 0;

            for (let i = 0; i < numHhStates && i < numCols; i++) {
                const E = results.hh_eigenvalues[i];
                const psi = results.hh_wavefunctions.map(row => row[i]);

                if (psi.length > 0) {
                    const redShade = 30 + i * 30;
                    datasets.push({
                        label: `h⁺ E${i+1} (${E.toFixed(3)} eV)`,
                        data: results.y_wave.map((y, j) => ({x: y, y: E - (psi[j] || 0) * 0.5})),
                        borderColor: `rgb(255, ${redShade}, ${redShade})`,
                        borderWidth: lineWidth,
                        borderDash: [2, 2],
                        fill: false,
                        pointRadius: 0
                    });
                }
            }
        }

        const ctx = canvas[0].getContext('2d');

        const chart = new Chart(ctx, {
            type: 'line',
            data: { datasets: datasets },
            options: {
                ...getChartOptions('Wavefunctions', 'Position (nm)', 'Energy (eV)', false),
                parsing: {
                    xAxisKey: 'x',
                    yAxisKey: 'y'
                },
                scales: {
                    ...getChartOptions('Wavefunctions', 'Position (nm)', 'Energy (eV)', false).scales,
                    x: {
                        type: 'linear',
                        title: {
                            display: true,
                            text: 'Position (nm)'
                        },
                        min: xMin,
                        max: xMax,
                        ticks: {
                            maxTicksLimit: 10
                        },
                        grid: {
                            display: $('#showGrid').is(':checked')
                        }
                    }
                }
            }
        });

        currentCharts.wave = chart;
    }
}

function createCVPlot(results) {
    if (!results.cv_voltage || results.cv_voltage.length === 0) {
        $('#plotsContainer').html(`
            <div class="alert alert-info">
                <i class="bi bi-info-circle"></i> No C-V data available for this simulation.
                Enable C-V calculation in the simulation settings to generate C-V curves.
            </div>
        `);
        return;
    }

    const lineWidth = parseFloat($('#lineWidth').val()) || 2;

    // Create canvas
    const canvas = $('<canvas>').attr('id', 'cvChart');
    const container = $(`
        <div class="card mb-3">
            <div class="card-header"><h6 class="mb-0">C-V Characteristics</h6></div>
            <div class="card-body"></div>
        </div>
    `);
    container.find('.card-body').append(canvas);
    $('#plotsContainer').append(container);

    // Build dataset — convert capacitance to μF/cm²
    const cvData = results.cv_voltage.map((v, i) => ({
        x: v,
        y: results.cv_capacitance[i] * 1e6
    }));

    const ctx = canvas[0].getContext('2d');

    const chart = new Chart(ctx, {
        type: 'line',
        data: {
            datasets: [{
                label: 'Capacitance',
                data: cvData,
                borderColor: 'rgb(54, 162, 235)',
                backgroundColor: 'rgba(54, 162, 235, 0.1)',
                borderWidth: lineWidth,
                fill: false,
                pointRadius: 4,
                pointBackgroundColor: 'rgb(54, 162, 235)'
            }]
        },
        options: {
            responsive: true,
            maintainAspectRatio: true,
            aspectRatio: 1.6,
            plugins: {
                title: {
                    display: true,
                    text: 'C-V Characteristics',
                    font: { size: 16 }
                },
                legend: {
                    display: $('#showLegend').is(':checked')
                }
            },
            scales: {
                x: {
                    type: 'linear',
                    title: {
                        display: true,
                        text: 'Gate Voltage (V)',
                        font: { size: 14 }
                    },
                    grid: {
                        display: $('#showGrid').is(':checked')
                    }
                },
                y: {
                    title: {
                        display: true,
                        text: 'Capacitance (μF/cm²)',
                        font: { size: 14 }
                    },
                    grid: {
                        display: $('#showGrid').is(':checked')
                    }
                }
            },
            parsing: {
                xAxisKey: 'x',
                yAxisKey: 'y'
            }
        }
    });

    currentCharts.cv = chart;
}

// Update all existing plots with new settings
function updateAllPlots() {
    if (!currentResults) return;

    const plotType = $('input[name="plotType"]:checked').val();
    displayPlots(currentResults, plotType);
}

// Reset plot settings to defaults
function resetPlotSettings() {
    $('input[name="yScale"][value="linear"]').prop('checked', true);
    $('#showGrid').prop('checked', true);
    $('#showLegend').prop('checked', true);
    $('#lineWidth').val(2);
    $('#lineWidthValue').text('2');

    updateAllPlots();
}

function displayEigenvalues(results) {
    // Electron eigenvalues
    const $elTable = $('#electronEigenvalues tbody');
    $elTable.empty();

    if (results.el_eigenvalues) {
        results.el_eigenvalues.forEach((E, i) => {
            $elTable.append(`
                <tr>
                    <td>${i + 1}</td>
                    <td>${E.toFixed(4)}</td>
                </tr>
            `);
        });
    }

    // Hole eigenvalues
    const $hhTable = $('#holeEigenvalues tbody');
    $hhTable.empty();

    if (results.hh_eigenvalues) {
        results.hh_eigenvalues.forEach((E, i) => {
            $hhTable.append(`
                <tr>
                    <td>${i + 1}</td>
                    <td>${E.toFixed(4)}</td>
                </tr>
            `);
        });
    }

    // Calculate transition energy
    if (results.el_eigenvalues && results.el_eigenvalues.length > 0 &&
        results.hh_eigenvalues && results.hh_eigenvalues.length > 0) {
        const transitionE = results.el_eigenvalues[0] - results.hh_eigenvalues[0];
        const wavelength = 1239.84 / transitionE; // nm

        $('#transitionEnergyValue').text(transitionE.toFixed(4));
        $('#transitionWavelength').text(wavelength.toFixed(1));
        $('#transitionEnergy').show();
    }
}

function displayCVInfo(results) {
    if (!results.cv_voltage || results.cv_voltage.length === 0) return;

    const minC = Math.min(...results.cv_capacitance) * 1e6;
    const maxC = Math.max(...results.cv_capacitance) * 1e6;
    const vMin = Math.min(...results.cv_voltage);
    const vMax = Math.max(...results.cv_voltage);

    let info = `
        <div class="card mt-3" id="cvDataCard">
            <div class="card-header">
                <h5 class="mb-0"><i class="bi bi-bezier2"></i> C-V Data</h5>
            </div>
            <div class="card-body">
                <div class="row">
                    <div class="col-md-6">
                        <strong>Voltage Range:</strong> ${vMin.toFixed(2)} to ${vMax.toFixed(2)} V<br>
                        <strong>Data Points:</strong> ${results.cv_voltage.length}
                    </div>
                    <div class="col-md-6">
                        <strong>Capacitance Range:</strong><br>
                        ${minC.toFixed(4)} to ${maxC.toFixed(4)} μF/cm²
                    </div>
                </div>
                <button class="btn btn-outline-secondary btn-sm mt-2" onclick="downloadCVData()">
                    <i class="bi bi-download"></i> Download C-V Data (CSV)
                </button>
            </div>
        </div>
    `;

    // Remove existing CV card if present, then append after eigenvalues or after plotsContainer
    $('#cvDataCard').remove();
    if ($('#eigenvaluesCard').is(':visible')) {
        $('#eigenvaluesCard').after(info);
    } else {
        $('#plotsContainer').after(info);
    }
}

function downloadCVData() {
    if (!currentResults || !currentResults.cv_voltage) return;

    let csv = 'Voltage(V),Capacitance(F/cm2),Capacitance(uF/cm2)\n';
    for (let i = 0; i < currentResults.cv_voltage.length; i++) {
        csv += `${currentResults.cv_voltage[i]},${currentResults.cv_capacitance[i]},${currentResults.cv_capacitance[i] * 1e6}\n`;
    }

    downloadFile(csv, `${currentResultName}_CV_data.csv`, 'text/csv');
}

function displayDataTable(results) {
    const $tbody = $('#dataTableBody');
    $tbody.empty();

    // Sample every Nth point for large datasets
    const step = Math.max(1, Math.floor(results.y.length / 100));

    for (let i = 0; i < results.y.length; i += step) {
        $tbody.append(`
            <tr>
                <td>${results.y[i].toFixed(2)}</td>
                <td>${results.Ec[i].toFixed(4)}</td>
                <td>${results.Ev[i].toFixed(4)}</td>
                <td>${results.Ef[i].toFixed(4)}</td>
                <td>${formatScientific(results.n[i])}</td>
                <td>${formatScientific(results.p[i])}</td>
            </tr>
        `);
    }
}

function downloadResults() {
    if (!currentResults || !currentResultName) {
        alert('No results loaded');
        return;
    }

    // Create CSV content
    let csv = 'Position(nm),Ec(eV),Ev(eV),Ef(eV),n(cm-3),p(cm-3)\n';

    for (let i = 0; i < currentResults.y.length; i++) {
        csv += `${currentResults.y[i]},${currentResults.Ec[i]},${currentResults.Ev[i]},`;
        csv += `${currentResults.Ef[i]},${currentResults.n[i]},${currentResults.p[i]}\n`;
    }

    downloadFile(csv, `${currentResultName}_data.csv`, 'text/csv');
}

function exportPlots() {
    const format = $('input[name="exportFormat"]:checked').val();
    const dpi = $('#exportDPI').val();

    if (!currentCharts || Object.keys(currentCharts).length === 0) {
        alert('No plots to export');
        return;
    }

    // Export current visible plots
    Object.entries(currentCharts).forEach(([name, chart]) => {
        if (chart && format === 'png') {
            // Handle split view naming: bandEc -> band_Ec, waveEv -> wave_Ev, etc.
            let filename = name;
            if (name.endsWith('Ec')) {
                filename = name.replace(/Ec$/, '_Ec');
            } else if (name.endsWith('Ev')) {
                filename = name.replace(/Ev$/, '_Ev');
            }

            const link = document.createElement('a');
            link.download = `${currentResultName}_${filename}.png`;
            link.href = chart.toBase64Image();
            link.click();
        }
    });

    if (format !== 'png') {
        alert(`${format.toUpperCase()} export feature coming soon!`);
    }

    bootstrap.Modal.getInstance($('#exportModal')[0]).hide();
}

// Utility functions
function showLoading(message) {
    return `
        <div class="text-center p-4">
            <div class="spinner-border text-primary" role="status">
                <span class="visually-hidden">Loading...</span>
            </div>
            <p class="mt-2 text-muted">${message}</p>
        </div>
    `;
}

function showError(message) {
    return `
        <div class="alert alert-danger" role="alert">
            <i class="bi bi-exclamation-triangle"></i> ${message}
        </div>
    `;
}

function formatTimestamp(timestamp) {
    const date = new Date(timestamp * 1000);
    return date.toLocaleString();
}

function formatScientific(value) {
    if (value === 0) return '0';
    return value.toExponential(2);
}

function downloadFile(content, filename, mimeType) {
    const blob = new Blob([content], { type: mimeType });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = filename;
    a.click();
    window.URL.revokeObjectURL(url);
}

function deleteSimulation(name, folder) {
    if (!confirm(`Are you sure you want to delete the simulation "${name}"?\n\nThis will delete all associated output files and cannot be undone.`)) {
        return;
    }

    let url = `/api/results/delete/${name}`;
    if (folder) {
        url += `?folder=${encodeURIComponent(folder)}`;
    }

    $.ajax({
        url: url,
        method: 'DELETE',
        success: function(response) {
            if (response.success) {
                loadResultsList();

                if (currentResultName === name) {
                    currentResults = null;
                    currentResultName = null;
                    $('#plotsContainer').html(`
                        <div class="alert alert-secondary">
                            <i class="bi bi-info-circle"></i> Select a simulation from the list to view results
                        </div>
                    `);
                    $('#resultInfoCard').hide();
                    $('#plotSettingsCard').hide();
                    $('#resultActionsCard').hide();
                    $('#eigenvaluesCard').hide();
                    $('#dataExportCard').hide();
                    $('#cvDataCard').remove();
                }
            } else {
                alert('Failed to delete simulation: ' + (response.error || 'Unknown error'));
            }
        },
        error: function(xhr) {
            alert('Error deleting simulation: ' + (xhr.responseJSON?.error || 'Unknown error'));
        }
    });
}

// =============================================================================
// Multi-Bias Results
// =============================================================================

function checkForBiasResults(name) {
    $.ajax({
        url: `/api/results/bias/${name}`,
        method: 'GET',
        success: function(response) {
            if (response.success && response.has_bias_sweep) {
                biasResults = response;
                showBiasSelector(response);
            } else {
                biasResults = null;
                $('#biasResultsCard').hide();
            }
        },
        error: function() {
            biasResults = null;
            $('#biasResultsCard').hide();
        }
    });
}

function showBiasSelector(data) {
    const $select = $('#biasVoltageSelect');
    $select.empty();

    // Add "Base (no voltage suffix)" option
    $select.append(`<option value="base">Base result</option>`);

    data.bias_points.forEach(function(voltage) {
        const label = `V = ${voltage} V`;
        $select.append(`<option value="${voltage}">${label}</option>`);
    });

    $('#biasPointCount').text(`${data.bias_points.length} bias points`);
    $('#biasResultsCard').show();

    // Bind change handler
    $select.off('change').on('change', function() {
        const val = $(this).val();
        if (val === 'base') {
            // Reload base results
            loadResults(currentResultName);
        } else {
            // Load specific bias point results
            const voltageKey = val;
            if (biasResults && biasResults.results[voltageKey]) {
                currentResults = biasResults.results[voltageKey];
                displayResults(currentResults);
            }
        }
    });

    // Compare button
    $('#compareBiasBtn').off('click').on('click', function() {
        if (biasResults) {
            showBiasComparison(biasResults);
        }
    });

    // Animate button
    $('#animateBiasBtn').off('click').on('click', function() {
        if (biasResults) {
            animateBiasResults(biasResults);
        }
    });
}

function showBiasComparison(data) {
    // Create overlay comparison plot showing band diagrams at all bias points
    const $container = $('#plotsContainer');
    $container.html('');

    const canvas = document.createElement('canvas');
    canvas.id = 'biasComparisonChart';
    canvas.style.width = '100%';
    canvas.style.height = '500px';
    $container.append(canvas);

    const datasets = [];
    const colorScale = generateColorScale(data.bias_points.length);

    data.bias_points.forEach(function(voltage, idx) {
        const voltageKey = String(voltage);
        const result = data.results[voltageKey];
        if (!result || !result.y || !result.Ec) return;

        datasets.push({
            label: `Ec (V=${voltage}V)`,
            data: result.y.map((y, i) => ({ x: y, y: result.Ec[i] })),
            borderColor: colorScale[idx],
            backgroundColor: 'transparent',
            borderWidth: 1.5,
            pointRadius: 0,
            tension: 0.1
        });
    });

    const ctx = canvas.getContext('2d');
    new Chart(ctx, {
        type: 'scatter',
        data: { datasets: datasets },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                title: {
                    display: true,
                    text: 'Band Diagram Comparison — All Bias Points',
                    font: { size: 14 }
                },
                legend: {
                    position: 'right',
                    labels: { font: { size: 10 } }
                }
            },
            scales: {
                x: {
                    type: 'linear',
                    title: { display: true, text: 'Position (nm)' }
                },
                y: {
                    title: { display: true, text: 'Ec - Ef (eV)' }
                }
            },
            showLine: true
        }
    });

    // Add a "Back to single view" button
    $container.prepend(`
        <button class="btn btn-sm btn-outline-secondary mb-2" id="backToSingleBtn">
            <i class="bi bi-arrow-left"></i> Back to single view
        </button>
    `);
    $('#backToSingleBtn').click(function() {
        displayResults(currentResults);
    });
}

function animateBiasResults(data) {
    if (biasAnimationTimer) {
        clearInterval(biasAnimationTimer);
        biasAnimationTimer = null;
        $('#animateBiasBtn').html('<i class="bi bi-play-circle"></i> Animate');
        return;
    }

    const points = data.bias_points;
    if (points.length < 2) return;

    let currentIdx = 0;
    $('#animateBiasBtn').html('<i class="bi bi-stop-circle"></i> Stop');

    biasAnimationTimer = setInterval(function() {
        const voltageKey = String(points[currentIdx]);
        const result = data.results[voltageKey];

        if (result) {
            currentResults = result;
            displayResults(result);
            $('#biasVoltageSelect').val(voltageKey);
        }

        currentIdx = (currentIdx + 1) % points.length;
    }, 1000);
}

function generateColorScale(count) {
    const colors = [];
    for (let i = 0; i < count; i++) {
        const hue = (i / count) * 270; // Blue to red spectrum
        colors.push(`hsl(${hue}, 70%, 50%)`);
    }
    return colors;
}