// Results Visualization JavaScript
let resultsData = null;

// Load results on page load
document.addEventListener('DOMContentLoaded', function() {
    loadResults();
});

async function loadResults() {
    // Try to get results from localStorage (from optimize page)
    const storedResults = localStorage.getItem('optimization_results');
    
    if (storedResults) {
        try {
            resultsData = JSON.parse(storedResults);
            displayResults(resultsData);
            return;
        } catch (error) {
            // Silent error handling
        }
    }
    
    // If no localStorage data, fetch from database
    await loadFromHistory();
}

async function loadFromHistory() {
    try {
        const response = await fetch('/api/history');
        const data = await response.json();
        
        if (response.ok && data.history && data.history.length > 0) {
            // Transform history data to match expected format
            resultsData = data.history.map(h => ({
                algorithm: h.algorithm,
                result_id: h.id,
                best_fitness: h.best_fitness,
                mean_fitness: h.best_fitness,
                std_fitness: 0.0,
                execution_time: h.execution_time || 0,
                convergence_curve: h.convergence_curve || [],
                best_solution: h.best_solution || [],
                n_features_selected: h.best_solution ? 
                    h.best_solution.filter(v => v >= 0.5).length : null,
                runs: [{
                    best_fitness: h.best_fitness,
                    execution_time: h.execution_time || 0
                }]
            }));
            
            displayResults(resultsData);
        } else {
            showError('No optimization history found. Please run an optimization first.');
        }
    } catch (error) {
        showError('Failed to load results from database. Please try again.');
    }
}

function showError(message) {
    document.getElementById('summaryMetrics').innerHTML = `
        <div class="col-12">
            <div class="alert alert-warning">
                <i class="fas fa-exclamation-triangle"></i> ${message}
                <br><br>
                <a href="/optimize" class="btn btn-primary">Go to Optimization</a>
            </div>
        </div>
    `;
}

function displayResults(results) {
    if (!results || results.length === 0) {
        showError('No valid results to display');
        return;
    }
    
    try {
        displaySummaryMetrics(results);
        populateSummaryTable(results);
        createPerformanceBarChart(results);
        createComparativeAnalysis(results);
        createConvergenceAnalysis(results);
        createFeatureAnalysis(results);
    } catch (error) {
        alert('Error creating visualizations');
    }
}

function displaySummaryMetrics(results) {
    const container = document.getElementById('summaryMetrics');
    
    // Find best performer
    const bestResult = results.reduce((best, curr) => 
        (curr.best_fitness || 0) < (best.best_fitness || 0) ? curr : best
    );
    
    // Find fastest
    const fastestResult = results.reduce((fastest, curr) => 
        (curr.execution_time || 0) < (fastest.execution_time || 0) ? curr : fastest
    );
    
    // Calculate averages
    const avgTime = results.reduce((sum, r) => sum + (r.execution_time || 0), 0) / results.length;
    
    container.innerHTML = `
        <div class="col-md-3">
            <div class="metric-card">
                <div class="metric-label">🧬 Algorithms Tested</div>
                <div class="metric-value">${results.length}</div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="metric-card">
                <div class="metric-label">🏆 Best Performer</div>
                <div class="metric-value">${(bestResult.algorithm || 'N/A').toUpperCase()}</div>
                <div class="metric-sublabel">Fitness: ${(bestResult.best_fitness || 0).toFixed(6)}</div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="metric-card">
                <div class="metric-label">⚡ Fastest</div>
                <div class="metric-value">${(fastestResult.algorithm || 'N/A').toUpperCase()}</div>
                <div class="metric-sublabel">${(fastestResult.execution_time || 0).toFixed(2)}s</div>
            </div>
        </div>
        <div class="col-md-3">
            <div class="metric-card">
                <div class="metric-label">⏱️ Avg Time</div>
                <div class="metric-value">${(avgTime || 0).toFixed(2)}s</div>
            </div>
        </div>
    `;
}

function populateSummaryTable(results) {
    const tbody = document.getElementById('summaryTableBody');
    if (!tbody) return;
    tbody.innerHTML = '';
    
    results.forEach(result => {
        const algorithm = result.algorithm || 'Unknown';
        const bestFitness = result.best_fitness != null ? result.best_fitness : 0;
        const meanFitness = result.mean_fitness != null ? result.mean_fitness : bestFitness;
        const stdFitness = result.std_fitness != null ? result.std_fitness : 0;
        const execTime = result.execution_time != null ? result.execution_time : 0;
        
        const row = `
            <tr>
                <td><strong>${algorithm.toUpperCase()}</strong></td>
                <td>${bestFitness.toFixed(6)}</td>
                <td>${meanFitness.toFixed(6)}</td>
                <td>${stdFitness.toFixed(6)}</td>
                <td>${execTime.toFixed(2)}</td>
                <td>${result.n_features_selected || 'N/A'}</td>
            </tr>
        `;
        tbody.innerHTML += row;
    });
}

function createPerformanceBarChart(results) {
    try {
        const algorithms = results.map(r => (r.algorithm || 'Unknown').toUpperCase());
        const fitness = results.map(r => r.best_fitness || 0);
        
        // Create gradient colors based on performance (green = good, red = bad)
        const maxFitness = Math.max(...fitness);
        const minFitness = Math.min(...fitness);
        const colors = fitness.map(f => {
            const normalized = (f - minFitness) / (maxFitness - minFitness || 1);
            if (normalized < 0.33) return 'rgb(46, 204, 113)'; // Green - best
            if (normalized < 0.67) return 'rgb(241, 196, 15)'; // Yellow - medium
            return 'rgb(231, 76, 60)'; // Red - worst
        });
        
        const trace = {
            x: algorithms,
            y: fitness,
            type: 'bar',
            marker: {
                color: colors,
                line: {
                    color: 'rgba(255,255,255,0.8)',
                    width: 2
                }
            },
            text: fitness.map(f => (f || 0).toFixed(6)),
            textposition: 'outside',
            textfont: {
                size: 11,
                color: '#333',
                family: 'Inter, sans-serif',
                weight: 600
            },
            hovertemplate: '<b>%{x}</b><br>Fitness: %{y:.6f}<extra></extra>'
        };
        
        const layout = {
            title: {
                text: 'Best Fitness by Algorithm (Lower is Better)',
                font: {size: 18, family: 'Inter, sans-serif', weight: 700, color: '#2d3748'}
            },
            xaxis: {
                title: {text: 'Algorithm', font: {size: 14, weight: 600}},
                tickangle: -45,
                tickfont: {size: 11, weight: 500}
            },
            yaxis: {
                title: {text: 'Fitness Value', font: {size: 14, weight: 600}},
                gridcolor: '#e8e8e8',
                tickfont: {size: 11}
            },
            height: 500,
            margin: {b: 140, l: 80, r: 40, t: 80},
            plot_bgcolor: '#fafafa',
            paper_bgcolor: 'white',
            font: {family: 'Inter, sans-serif'},
            showlegend: false
        };
        
        Plotly.newPlot('performanceBarChart', [trace], layout, {
            responsive: true,
            displayModeBar: true,
            displaylogo: false,
            modeBarButtonsToRemove: ['lasso2d', 'select2d']
        });
    } catch (error) {
        document.getElementById('performanceBarChart').innerHTML = 
            '<p class="text-danger p-4">Error creating chart: ' + error.message + '</p>';
    }
}

function createComparativeAnalysis(results) {
    // Check if we have runs data for box plot
    if (results[0].runs && results[0].runs.length > 0) {
        createBoxPlot(results);
    } else {
        document.getElementById('fitnessBoxPlot').innerHTML = 
            '<p class="text-muted text-center py-5">Box plot requires multiple runs per algorithm. Set "Runs per Algorithm" to 2 or more in optimization settings.</p>';
    }
    
    createMeanFitnessChart(results);
    createAccuracyChart(results);
    createStdDevChart(results);
    createExecutionTimeChart(results);
    createScatterChart(results);
    createRankingTable(results);
}

function createBoxPlot(results) {
    const traces = [];
    
    results.forEach(result => {
        if (result.runs && result.runs.length >= 2) {
            const fitnessValues = result.runs.map(run => run.best_fitness);
            
            traces.push({
                y: fitnessValues,
                name: result.algorithm.toUpperCase(),
                type: 'box',
                boxpoints: 'all',
                jitter: 0.3,
                pointpos: -1.8
            });
        }
    });
    
    if (traces.length > 0) {
        const layout = {
            title: 'Fitness Distribution Across Multiple Runs',
            yaxis: {title: 'Fitness Value (Lower is Better)'},
            height: 500,
            showlegend: true
        };
        
        Plotly.newPlot('fitnessBoxPlot', traces, layout, {responsive: true});
    } else {
        document.getElementById('fitnessBoxPlot').innerHTML = 
            '<p class="text-muted text-center py-5">No multi-run data available. Each algorithm was run once.</p>';
    }
}

function createMeanFitnessChart(results) {
    try {
        const algorithms = results.map(r => (r.algorithm || 'Unknown').toUpperCase());
        const meanFitness = results.map(r => r.mean_fitness || r.best_fitness || 0);
        const stdFitness = results.map(r => r.std_fitness || 0);
        
        const trace = {
            x: algorithms,
            y: meanFitness,
            error_y: {
                type: 'data',
                array: stdFitness,
                visible: true,
                color: '#888'
            },
            type: 'bar',
            marker: {color: 'lightcoral'},
            text: meanFitness.map(f => (f || 0).toFixed(4)),
            textposition: 'outside'
        };
        
        const layout = {
            title: 'Mean Fitness with Standard Deviation',
            xaxis: {title: 'Algorithm', tickangle: -45},
            yaxis: {title: 'Mean Fitness ± SD'},
            height: 500,
            margin: {b: 120}
        };
        
        Plotly.newPlot('meanFitnessChart', [trace], layout, {responsive: true});
    } catch (error) {
        document.getElementById('meanFitnessChart').innerHTML = 
            '<p class="text-danger p-4">Error creating chart</p>';
    }
}

function createAccuracyChart(results) {
    try {
        const algorithms = results.map(r => (r.algorithm || 'Unknown').toUpperCase());
        const accuracy = results.map(r => {
            const fitness = r.mean_fitness || r.best_fitness || 0;
            return ((1 - fitness) * 100);
        });
        
        const trace = {
            x: algorithms,
            y: accuracy,
            type: 'bar',
            marker: {color: 'lightgreen'},
            text: accuracy.map(a => (a || 0).toFixed(2) + '%'),
            textposition: 'outside'
        };
        
        const layout = {
            title: 'Mean Accuracy Comparison (Higher is Better)',
            xaxis: {title: 'Algorithm', tickangle: -45},
            yaxis: {title: 'Accuracy (%)', range: [0, Math.max(...accuracy) * 1.1]},
            height: 500,
            margin: {b: 120}
        };
        
        Plotly.newPlot('accuracyChart', [trace], layout, {responsive: true});
    } catch (error) {
        document.getElementById('accuracyChart').innerHTML = 
            '<p class="text-danger p-4">Error creating chart</p>';
    }
}

function createStdDevChart(results) {
    try {
        const algorithms = results.map(r => (r.algorithm || 'Unknown').toUpperCase());
        const stdDev = results.map(r => r.std_fitness || 0);
        
        const trace = {
            x: algorithms,
            y: stdDev,
            type: 'bar',
            marker: {color: 'lightskyblue'},
            text: stdDev.map(s => (s || 0).toFixed(4)),
            textposition: 'outside'
        };
        
        const layout = {
            title: 'Standard Deviation of Fitness (Lower = More Reliable)',
            xaxis: {title: 'Algorithm', tickangle: -45},
            yaxis: {title: 'Standard Deviation'},
            height: 500,
            margin: {b: 120}
        };
        
        Plotly.newPlot('stdDevChart', [trace], layout, {responsive: true});
    } catch (error) {
        document.getElementById('stdDevChart').innerHTML = 
            '<p class="text-danger p-4">Error creating chart</p>';
    }
}

function createExecutionTimeChart(results) {
    try {
        const algorithms = results.map(r => (r.algorithm || 'Unknown').toUpperCase());
        const times = results.map(r => r.execution_time || 0);
        
        const trace = {
            x: algorithms,
            y: times,
            type: 'bar',
            marker: {color: 'plum'},
            text: times.map(t => (t || 0).toFixed(2) + 's'),
            textposition: 'outside'
        };
        
        const layout = {
            title: 'Execution Time Comparison',
            xaxis: {title: 'Algorithm', tickangle: -45},
            yaxis: {title: 'Time (seconds)'},
            height: 500,
            margin: {b: 120}
        };
        
        Plotly.newPlot('executionTimeChart', [trace], layout, {responsive: true});
    } catch (error) {
        document.getElementById('executionTimeChart').innerHTML = 
            '<p class="text-danger p-4">Error creating chart</p>';
    }
}

function createScatterChart(results) {
    try {
        const trace = {
            x: results.map(r => r.execution_time || 0),
            y: results.map(r => r.mean_fitness || r.best_fitness || 0),
            mode: 'markers+text',
            marker: {
                size: results.map(r => (r.n_features_selected || 10) * 2),
                color: results.map((r, i) => i),
                colorscale: 'Viridis',
                showscale: true,
                colorbar: {title: 'Algorithm Index'}
            },
            text: results.map(r => (r.algorithm || 'Unknown').toUpperCase()),
            textposition: 'top center',
            type: 'scatter'
        };
    
        const layout = {
            title: 'Performance vs. Speed (bubble size = features)',
            xaxis: {title: 'Execution Time (seconds)'},
            yaxis: {title: 'Mean Fitness'},
            height: 500
        };
        
        Plotly.newPlot('scatterChart', [trace], layout, {responsive: true});
    } catch (error) {
        document.getElementById('scatterChart').innerHTML = 
            '<p class="text-danger p-4">Error creating chart</p>';
    }
}

function createRankingTable(results) {
    try {
        // Calculate composite score
        const maxStd = Math.max(...results.map(r => r.std_fitness || 0.01));
        const maxTime = Math.max(...results.map(r => r.execution_time || 1));
        
        const ranked = results.map(r => ({
            ...r,
            composite: ((r.mean_fitness || r.best_fitness || 0) * 0.6) + 
                       (((r.std_fitness || 0) / maxStd) * 0.2) +
                       (((r.execution_time || 0) / maxTime) * 0.2)
        })).sort((a, b) => a.composite - b.composite);
        
        const tbody = document.getElementById('rankingTableBody');
        tbody.innerHTML = '';
        
        ranked.forEach((result, index) => {
            const medal = index === 0 ? '🥇' : index === 1 ? '🥈' : index === 2 ? '🥉' : '';
            const accuracy = ((1 - ((result.mean_fitness || result.best_fitness || 0))) * 100).toFixed(2);
            
            const row = `
                <tr>
                    <td><span class="ranking-medal">${medal}</span>${index + 1}</td>
                    <td><strong>${(result.algorithm || 'Unknown').toUpperCase()}</strong></td>
                    <td>${(result.best_fitness || 0).toFixed(6)}</td>
                    <td>${accuracy}%</td>
                    <td>${(result.std_fitness || 0).toFixed(6)}</td>
                    <td>${(result.execution_time || 0).toFixed(2)}</td>
                </tr>
            `;
            tbody.innerHTML += row;
        });
    } catch (error) {
        const tbody = document.getElementById('rankingTableBody');
        if (tbody) {
            tbody.innerHTML = '<tr><td colspan="6" class="text-danger">Error creating table</td></tr>';
        }
    }
}

function createConvergenceAnalysis(results) {
    try {
        const traces = [];
        const colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd', 
                        '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'];
        
        results.forEach((result, index) => {
            if (result.convergence_curve && result.convergence_curve.length > 0) {
                traces.push({
                    x: Array.from({length: result.convergence_curve.length}, (_, i) => i + 1),
                    y: result.convergence_curve,
                    mode: 'lines+markers',
                    name: (result.algorithm || 'Unknown').toUpperCase(),
                    line: {width: 2, color: colors[index % colors.length]},
                    marker: {size: 4}
                });
            }
        });
        
        if (traces.length > 0) {
            const layout = {
                title: `Convergence Curves (${traces.length} Algorithms)`,
                xaxis: {title: 'Iteration'},
                yaxis: {title: 'Fitness Value (Lower is Better)'},
                height: 600,
                hovermode: 'x unified',
                legend: {
                    orientation: 'v',
                    yanchor: 'top',
                    y: 0.99,
                    xanchor: 'right',
                    x: 0.99
                }
            };
            
            Plotly.newPlot('convergencePlot', traces, layout, {responsive: true});
            
            // Populate convergence statistics
            populateConvergenceStats(results);
        } else {
            document.getElementById('convergencePlot').innerHTML = 
                '<p class="text-muted text-center py-5">No convergence data available</p>';
        }
    } catch (error) {
        document.getElementById('convergencePlot').innerHTML = 
            '<p class="text-danger p-4">Error creating convergence chart</p>';
    }
}

function populateConvergenceStats(results) {
    try {
        const tbody = document.getElementById('convergenceStatsBody');
        tbody.innerHTML = '';
        
        let bestImprovement = null;
        let fastestConvergence = null;
        
        results.forEach(result => {
            if (result.convergence_curve && result.convergence_curve.length > 1) {
                const conv = result.convergence_curve;
                const initial = conv[0] || 0;
                const final = conv[conv.length - 1] || 0;
                const improvement = initial - final;
                const improvementPct = initial !== 0 ? (improvement / initial * 100) : 0;
                
                // Find 90% convergence iteration
                const target = initial - (0.9 * improvement);
                const conv90 = conv.findIndex(f => f <= target) + 1 || conv.length;
                
                // Track best improvement
                if (!bestImprovement || improvementPct > bestImprovement.pct) {
                    bestImprovement = {algo: result.algorithm || 'Unknown', pct: improvementPct};
                }
                
                // Track fastest convergence
                if (!fastestConvergence || conv90 < fastestConvergence.iter) {
                    fastestConvergence = {algo: result.algorithm || 'Unknown', iter: conv90};
                }
                
                const row = `
                    <tr>
                        <td><strong>${(result.algorithm || 'Unknown').toUpperCase()}</strong></td>
                        <td>${initial.toFixed(6)}</td>
                        <td>${final.toFixed(6)}</td>
                        <td>${improvement.toFixed(6)}</td>
                        <td>${improvementPct.toFixed(2)}%</td>
                        <td>${conv90}</td>
                    </tr>
                `;
                tbody.innerHTML += row;
            }
        });
        
        // Update convergence metrics
        if (bestImprovement) {
            const elem1 = document.getElementById('bestImprovementAlgo');
            const elem2 = document.getElementById('bestImprovementValue');
            if (elem1) elem1.textContent = bestImprovement.algo.toUpperCase();
            if (elem2) elem2.textContent = `${bestImprovement.pct.toFixed(2)}% improvement`;
        }
        
        if (fastestConvergence) {
            const elem1 = document.getElementById('fastestConvergenceAlgo');
            const elem2 = document.getElementById('fastestConvergenceValue');
            if (elem1) elem1.textContent = fastestConvergence.algo.toUpperCase();
            if (elem2) elem2.textContent = `Iteration ${fastestConvergence.iter}`;
        }
    } catch (error) {
        // Silent error handling
    }
}

function createFeatureAnalysis(results) {
    try {
        // Find best algorithm
        const bestResult = results.reduce((best, curr) => 
            (curr.best_fitness || 999) < (best.best_fitness || 999) ? curr : best
        );
        
        const elem1 = document.getElementById('bestAlgoName');
        const elem2 = document.getElementById('bestFitnessValue');
        const elem3 = document.getElementById('bestAccuracyValue');
        
        if (elem1) elem1.textContent = (bestResult.algorithm || 'Unknown').toUpperCase();
        if (elem2) elem2.textContent = (bestResult.best_fitness || 0).toFixed(6);
        const accuracy = ((1 - (bestResult.best_fitness || 0)) * 100).toFixed(2);
        if (elem3) elem3.textContent = accuracy + '%';
        
        // Setup threshold slider
        const slider = document.getElementById('featureThreshold');
        const thresholdDisplay = document.getElementById('thresholdValue');
        
        if (slider) {
            slider.addEventListener('input', function() {
                if (thresholdDisplay) thresholdDisplay.textContent = this.value;
                updateFeaturePlot(bestResult, parseFloat(this.value));
            });
            
            // Initial plot
            updateFeaturePlot(bestResult, 0.5);
        }
    } catch (error) {
        // Silent error handling
    }
}

function updateFeaturePlot(result, threshold) {
    try {
        if (!result.best_solution || result.best_solution.length === 0) {
            document.getElementById('featureImportancePlot').innerHTML = 
                '<p class="text-muted text-center py-5">No feature selection data available for this optimization run</p>';
            const summaryElem = document.getElementById('featureSummary');
            if (summaryElem) {
                summaryElem.innerHTML = 
                    '<div class="col-12"><p class="text-muted">This was likely a function optimization task without feature selection.</p></div>';
            }
            return;
        }
        
        const features = result.best_solution.map((val, idx) => `Feature_${idx + 1}`);
        const values = result.best_solution.map(v => v || 0);
        
        // Color based on threshold
        const colors = values.map(v => {
            if (v >= threshold + 0.2) return 'rgb(27, 94, 32)';      // Dark green
            if (v >= threshold) return 'rgb(76, 175, 80)';            // Green
            if (v >= threshold - 0.1) return 'rgb(255, 152, 0)';      // Orange
            if (v >= threshold - 0.2) return 'rgb(255, 87, 34)';      // Dark orange
            return 'rgb(189, 189, 189)';                              // Gray
        });
        
        const trace = {
            x: features,
            y: values,
            type: 'bar',
            marker: {color: colors},
            text: values.map(v => (v || 0).toFixed(3)),
            textposition: 'outside'
        };
        
        // Add threshold line
        const thresholdLine = {
            x: features,
            y: Array(features.length).fill(threshold),
            mode: 'lines',
            name: `Threshold (${threshold})`,
            line: {color: 'red', width: 2, dash: 'dash'}
        };
        
        const layout = {
            title: `Feature Importance Values (Threshold: ${threshold})`,
            xaxis: {title: 'Features', tickangle: -45},
            yaxis: {title: 'Position Value', range: [0, 1]},
            height: 500,
            showlegend: true,
            margin: {b: 120}
        };
        
        Plotly.newPlot('featureImportancePlot', [trace, thresholdLine], layout, {responsive: true});
        
        // Update summary
        const selected = values.filter(v => v >= threshold).length;
        const total = values.length;
        const summaryElem = document.getElementById('featureSummary');
        if (summaryElem) {
            summaryElem.innerHTML = `
                <div class="col-md-4">
                    <div class="metric-card">
                        <div class="metric-label">Total Features</div>
                        <div class="metric-value">${total}</div>
                    </div>
                </div>
                <div class="col-md-4">
                    <div class="metric-card">
                        <div class="metric-label">Selected (≥ ${threshold})</div>
                        <div class="metric-value">${selected}</div>
                        <div class="metric-sublabel">${total > 0 ? (selected/total*100).toFixed(1) : 0}%</div>
                    </div>
                </div>
                <div class="col-md-4">
                    <div class="metric-card">
                        <div class="metric-label">Rejected (&lt; ${threshold})</div>
                        <div class="metric-value">${total - selected}</div>
                        <div class="metric-sublabel">${total > 0 ? ((total-selected)/total*100).toFixed(1) : 0}%</div>
                    </div>
                </div>
            `;
        }
    } catch (error) {
        // Silent error handling
    }
}

// Export Functions
function exportSummaryCSV() {
    try {
        if (!resultsData) {
            alert('No results data available');
            return;
        }
        
        let csv = 'Algorithm,Best_Fitness,Mean_Fitness,Std_Fitness,Execution_Time,Features_Selected\n';
        resultsData.forEach(r => {
            csv += `${r.algorithm || 'Unknown'},${r.best_fitness || 0},${r.mean_fitness||r.best_fitness||0},${r.std_fitness||0},${r.execution_time||0},${r.n_features_selected||'N/A'}\n`;
        });
        
        downloadCSV(csv, `mha_results_summary_${Date.now()}.csv`);
    } catch (error) {
        alert('Error exporting CSV');
    }
}

function exportFullJSON() {
    try {
        if (!resultsData) {
            alert('No results data available');
            return;
        }
        
        const json = JSON.stringify(resultsData, null, 2);
        downloadFile(json, `mha_results_full_${Date.now()}.json`, 'application/json');
    } catch (error) {
        alert('Error exporting JSON');
    }
}

function exportConvergenceCSV() {
    try {
        if (!resultsData) {
            alert('No results data available');
            return;
        }
        
        let csv = 'Algorithm,Iteration,Fitness\n';
        resultsData.forEach(r => {
            if (r.convergence_curve && r.convergence_curve.length > 0) {
                r.convergence_curve.forEach((fitness, iter) => {
                    csv += `${r.algorithm || 'Unknown'},${iter + 1},${fitness || 0}\n`;
                });
            }
        });
        
        downloadCSV(csv, `mha_convergence_data_${Date.now()}.csv`);
    } catch (error) {
        alert('Error exporting convergence CSV');
    }
}

function exportFeaturesCSV() {
    if (!resultsData) {
        alert('No results data available');
        return;
    }
    
    const bestResult = resultsData.reduce((best, curr) => 
        curr.best_fitness < best.best_fitness ? curr : best
    );
    
    if (!bestResult.best_solution || bestResult.best_solution.length === 0) {
        alert('No feature selection data available');
        return;
    }
    
    let csv = 'Feature,Position_Value,Selected_0.5,Selected_0.75\n';
    bestResult.best_solution.forEach((val, idx) => {
        csv += `Feature_${idx + 1},${val},${val >= 0.5 ? 'Yes' : 'No'},${val >= 0.75 ? 'Yes' : 'No'}\n`;
    });
    
    downloadCSV(csv, `mha_features_${bestResult.algorithm}_${Date.now()}.csv`);
}

function downloadCSV(content, filename) {
    downloadFile(content, filename, 'text/csv');
}

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;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    window.URL.revokeObjectURL(url);
}

// View mode functions
async function loadLatestOptimization() {
    const storedResults = localStorage.getItem('optimization_results');
    if (storedResults) {
        try {
            resultsData = JSON.parse(storedResults);
            displayResults(resultsData);
        } catch (error) {
            alert('Failed to load latest optimization');
        }
    } else {
        alert('No recent optimization found. Please run an optimization first.');
    }
}

async function loadAllHistory() {
    try {
        const response = await fetch('/api/history');
        const data = await response.json();
        
        if (response.ok && data.history && data.history.length > 0) {
            const grouped = {};
            data.history.forEach(h => {
                const key = `${h.algorithm}_${h.objective_function}`;
                if (!grouped[key]) {
                    grouped[key] = { algorithm: h.algorithm, objective_function: h.objective_function, runs: [] };
                }
                grouped[key].runs.push({
                    best_fitness: h.best_fitness,
                    execution_time: h.execution_time || 0,
                    convergence_curve: h.convergence_curve || [],
                    best_solution: h.best_solution || []
                });
            });
            
            resultsData = Object.values(grouped).map(group => {
                const fitnesses = group.runs.map(r => r.best_fitness);
                const times = group.runs.map(r => r.execution_time);
                const best_run = group.runs.reduce((best, curr) => 
                    curr.best_fitness < best.best_fitness ? curr : best
                );
                const mean = fitnesses.reduce((a, b) => a + b, 0) / fitnesses.length;
                const variance = fitnesses.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b, 0) / fitnesses.length;
                
                return {
                    algorithm: group.algorithm,
                    best_fitness: Math.min(...fitnesses),
                    mean_fitness: mean,
                    std_fitness: Math.sqrt(variance),
                    execution_time: times.reduce((a, b) => a + b, 0) / times.length,
                    convergence_curve: best_run.convergence_curve,
                    best_solution: best_run.best_solution,
                    n_features_selected: best_run.best_solution ? best_run.best_solution.filter(v => v >= 0.5).length : null,
                    runs: group.runs.map(r => ({ best_fitness: r.best_fitness, execution_time: r.execution_time }))
                };
            });
            
            displayResults(resultsData);
        } else {
            alert('No history found');
        }
    } catch (error) {
        alert('Failed to load history');
    }
}
