{% extends "base.html" %}

{% set active_page = 'benchmark-results' %}

{% block title %}Benchmark Results History - Deep Research System{% endblock %}

{% block extra_head %}
<meta name="csrf-token" content="{{ csrf_token() }}">
<meta name="app-version" content="{{ version }}">
<link rel="stylesheet" href="/static/css/benchmark.css">
{% endblock %}

{% block content %}
<div class="ldr-page active" id="benchmark-results">
    <div class="ldr-page-header">
        <h1>Benchmark Results History</h1>
        <p class="ldr-page-subtitle">Compare accuracy across different models, search engines, and strategies</p>
    </div>

    <div class="ldr-card ldr-benchmark-results-card">
        <div class="ldr-card-content">
            <!-- Filters -->
            <div class="ldr-filters">
                <div class="ldr-filter-group">
                    <label for="accuracy-filter">Accuracy Range</label>
                    <select id="accuracy-filter">
                        <option value="">All</option>
                        <option value="high">90%+ (High)</option>
                        <option value="medium">70-90% (Medium)</option>
                        <option value="low"><70% (Low)</option>
                    </select>
                </div>
                <div class="ldr-filter-group">
                    <label for="model-filter">Model</label>
                    <select id="model-filter">
                        <option value="">All Models</option>
                    </select>
                </div>
                <div class="ldr-filter-group">
                    <label for="strategy-filter">Strategy</label>
                    <select id="strategy-filter">
                        <option value="">All Strategies</option>
                    </select>
                </div>
                <div class="ldr-filter-group">
                    <label for="status-filter">Status</label>
                    <select id="status-filter">
                        <option value="">All Statuses</option>
                        <option value="completed">Completed</option>
                        <option value="in_progress">In Progress</option>
                        <option value="failed">Failed</option>
                        <option value="cancelled">Cancelled</option>
                    </select>
                </div>
                <div class="ldr-filter-group">
                    <label for="date-filter">Date Range</label>
                    <input type="date" id="date-from">
                    <input type="date" id="date-to">
                </div>
            </div>

            <!-- Results List -->
            <div id="results-container">
                <div class="ldr-loading">
                    <i aria-hidden="true" class="fas fa-spinner fa-spin"></i> Loading benchmark results...
                </div>
            </div>

            <!-- Pagination -->
            <div class="ldr-pagination" id="pagination" style="display: none;">
                <button id="prev-page">← Previous</button>
                <span id="page-info">Page 1 of 1</span>
                <button id="next-page">Next →</button>
            </div>
        </div>
    </div>
</div>

<!-- YAML serialization helpers (yamlEscape / formatSettingValue /
     formatSettingsSnapshot) — extracted so the export escaping is unit-tested.
     Must load before the inline script below, which calls them as globals. -->
<script src="/static/js/utils/yaml_export.js"></script>
<script>
let benchmarkRuns = [];
let filteredRuns = [];
let currentPage = 1;
const itemsPerPage = 20;

document.addEventListener('DOMContentLoaded', function() {
    loadBenchmarkHistory();
    setupFilters();
});

async function loadBenchmarkHistory() {
    try {
        const response = await fetch('/benchmark/api/history');
        const data = await response.json();

        if (data.success) {
            benchmarkRuns = data.runs;
            filteredRuns = [...benchmarkRuns];
            populateFilters();
            displayResults();
        } else {
            document.getElementById('results-container').innerHTML =
                '<div class="ldr-no-results">Error loading benchmark results</div>';
        }
    } catch (error) {
        console.error('Error loading benchmark history:', error);
        document.getElementById('results-container').innerHTML =
            '<div class="ldr-no-results">Error loading benchmark results</div>';
    }
}

function populateFilters() {
    // Populate model filter
    const models = [...new Set(benchmarkRuns.map(run =>
        run.search_config?.model_name).filter(Boolean))];
    const modelFilter = document.getElementById('model-filter');
    models.forEach(model => {
        const option = document.createElement('option');
        option.value = model;
        option.textContent = model;
        modelFilter.appendChild(option);
    });

    // Populate strategy filter
    const strategies = [...new Set(benchmarkRuns.map(run =>
        run.search_config?.search_strategy).filter(Boolean))];
    const strategyFilter = document.getElementById('strategy-filter');
    strategies.forEach(strategy => {
        const option = document.createElement('option');
        option.value = strategy;
        option.textContent = strategy.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
        strategyFilter.appendChild(option);
    });
}

function setupFilters() {
    document.getElementById('accuracy-filter').addEventListener('change', applyFilters);
    document.getElementById('model-filter').addEventListener('change', applyFilters);
    document.getElementById('strategy-filter').addEventListener('change', applyFilters);
    document.getElementById('status-filter').addEventListener('change', applyFilters);
    document.getElementById('date-from').addEventListener('change', applyFilters);
    document.getElementById('date-to').addEventListener('change', applyFilters);
}

function applyFilters() {
    const accuracyFilter = document.getElementById('accuracy-filter').value;
    const modelFilter = document.getElementById('model-filter').value;
    const strategyFilter = document.getElementById('strategy-filter').value;
    const statusFilter = document.getElementById('status-filter').value;
    const dateFrom = document.getElementById('date-from').value;
    const dateTo = document.getElementById('date-to').value;

    filteredRuns = benchmarkRuns.filter(run => {
        // Accuracy filter
        if (accuracyFilter) {
            const accuracy = run.overall_accuracy || 0;
            if (accuracyFilter === 'high' && accuracy < 90) return false;
            if (accuracyFilter === 'medium' && (accuracy < 70 || accuracy >= 90)) return false;
            if (accuracyFilter === 'low' && accuracy >= 70) return false;
        }

        // Model filter
        if (modelFilter && run.search_config?.model_name !== modelFilter) return false;

        // Strategy filter
        if (strategyFilter && run.search_config?.search_strategy !== strategyFilter) return false;

        // Status filter
        if (statusFilter && run.status !== statusFilter) return false;

        // Date filters
        const runDate = new Date(run.created_at).toISOString().split('T')[0];
        if (dateFrom && runDate < dateFrom) return false;
        if (dateTo && runDate > dateTo) return false;

        return true;
    });

    currentPage = 1;
    displayResults();
}

function displayResults() {
    const container = document.getElementById('results-container');

    if (filteredRuns.length === 0) {
        container.innerHTML = '<div class="ldr-no-results">No benchmark results found</div>';
        document.getElementById('pagination').style.display = 'none';
        return;
    }

    const startIndex = (currentPage - 1) * itemsPerPage;
    const endIndex = Math.min(startIndex + itemsPerPage, filteredRuns.length);
    const pageRuns = filteredRuns.slice(startIndex, endIndex);

    const html = pageRuns.map(run => createRunCard(run)).join('');
    container.innerHTML = html;

    // Setup pagination
    setupPagination();
}

function createRunCard(run) {
    const accuracy = run.overall_accuracy || 0;
    const accuracyClass = accuracy >= 90 ? 'ldr-accuracy-high' :
                         accuracy >= 70 ? 'ldr-accuracy-medium' : 'ldr-accuracy-low';

    // Status handling
    const status = run.status || 'unknown';
    const statusClass = `ldr-status-${status.replace('_', '-')}`;
    const statusText = status.replace('_', ' ').replace(/\b\w/g, l => l.toUpperCase());

    const date = new Date(run.created_at).toLocaleDateString();
    const time = new Date(run.created_at).toLocaleTimeString();

    // Progress calculation
    const progress = run.total_examples > 0 ?
        ((run.completed_examples / run.total_examples) * 100).toFixed(1) : 0;

    // Format status text with proper capitalization
    const formattedStatus = status.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());

    return `
        <div class="ldr-run-card" onclick="toggleRunDetails(${run.id})">
            <div class="ldr-run-header">
                <div class="ldr-run-title">${escapeHtml(run.run_name)}</div>
                <div class="ldr-run-date">${date} ${time}</div>
            </div>

            <div class="ldr-run-summary">
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value ${statusClass} ldr-status-indicator">${escapeHtml(formattedStatus)}</div>
                    <div class="ldr-summary-label">Status</div>
                </div>
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value">${run.completed_examples}/${run.total_examples}</div>
                    <div class="ldr-summary-label">Progress (${progress}%)</div>
                </div>
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value ${status === 'completed' && accuracy > 0 ? accuracyClass + ' ldr-accuracy-indicator' : ''}">${status === 'completed' && accuracy > 0 ? accuracy.toFixed(1) + '%' : 'N/A'}</div>
                    <div class="ldr-summary-label">Accuracy</div>
                </div>
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value">${escapeHtml(run.search_config?.model_name || 'Unknown')}</div>
                    <div class="ldr-summary-label">Model</div>
                </div>
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value">${escapeHtml((run.search_config?.search_strategy || 'unknown').replace(/_/g, ' '))}</div>
                    <div class="ldr-summary-label">Strategy</div>
                </div>
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value">${escapeHtml(run.search_config?.search_tool || 'Unknown')}</div>
                    <div class="ldr-summary-label">Search Engine</div>
                </div>
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value">${formatAvgSearchResults(run)}</div>
                    <div class="ldr-summary-label">Avg Search Results</div>
                </div>
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value">${formatAvgSearchRequests(run)}</div>
                    <div class="ldr-summary-label">Avg Search Requests</div>
                </div>
                <div class="ldr-summary-item">
                    <div class="ldr-summary-value">${formatAvgProcessingTime(run)}</div>
                    <div class="ldr-summary-label">Avg Time/Question</div>
                </div>
                <div class="ldr-summary-item">
                    <div style="display: flex; gap: 8px; flex-wrap: wrap; justify-content: center;">
                        ${status === 'completed' ?
                            `<div class="dropdown d-inline-block" onclick="event.stopPropagation()">
                                <button class="btn ldr-btn-outline btn-sm ldr-download-btn dropdown-toggle" type="button" id="export-dropdown-${run.id}" data-bs-toggle="dropdown" aria-expanded="false" title="Export benchmark YAML">
                                    <i aria-hidden="true" class="fas fa-download"></i> Export
                                </button>
                                <ul class="dropdown-menu" aria-labelledby="export-dropdown-${run.id}">
                                    <li><a class="dropdown-item" href="#" onclick="event.preventDefault(); event.stopPropagation(); downloadBenchmarkYAML(${run.id}, false, document.getElementById('include-settings-${run.id}').checked)">
                                        <i aria-hidden="true" class="fas fa-download"></i> Download YAML (summary)
                                    </a></li>
                                    <li><a class="dropdown-item" href="#" onclick="event.preventDefault(); event.stopPropagation(); downloadBenchmarkYAML(${run.id}, true, document.getElementById('include-settings-${run.id}').checked)">
                                        <i aria-hidden="true" class="fas fa-download"></i> Download YAML + examples
                                    </a></li>
                                    <li><hr class="dropdown-divider"></li>
                                    <li class="dropdown-item" onclick="event.stopPropagation()">
                                        <label style="display:flex; align-items:center; gap:6px; margin:0; cursor:pointer;">
                                            <input type="checkbox" id="include-settings-${run.id}" onclick="event.stopPropagation()"> Include settings snapshot
                                        </label>
                                    </li>
                                </ul>
                            </div>` : ''
                        }
                        ${status === 'in_progress' ?
                            `<button class="btn ldr-btn-outline btn-sm ldr-delete-btn" onclick="event.stopPropagation(); cancelAndDeleteBenchmarkRun(${run.id})">
                                <i aria-hidden="true" class="fas fa-stop"></i> Cancel & Delete
                            </button>` :
                            `<button class="btn ldr-btn-outline btn-sm ldr-delete-btn" onclick="event.stopPropagation(); deleteBenchmarkRun(${run.id})">
                                <i aria-hidden="true" class="fas fa-trash"></i> Delete
                            </button>`
                        }
                    </div>
                    <div class="ldr-summary-label">Actions</div>
                </div>
            </div>

            <div class="ldr-expand-indicator">
                <i aria-hidden="true" class="fas fa-chevron-down"></i> Click to view detailed results and examples
            </div>

            <div class="ldr-results-section" id="results-${run.id}">
                <div class="ldr-run-config">
                    <div class="ldr-config-item">
                        <span class="ldr-config-label">Iterations:</span>
                        <span class="ldr-config-value">${escapeHtml(run.search_config?.iterations || 'N/A')}</span>
                    </div>
                    <div class="ldr-config-item">
                        <span class="ldr-config-label">Questions/Iteration:</span>
                        <span class="ldr-config-value">${escapeHtml(run.search_config?.questions_per_iteration || 'N/A')}</span>
                    </div>
                    <div class="ldr-config-item">
                        <span class="ldr-config-label">Temperature:</span>
                        <span class="ldr-config-value">${escapeHtml(run.search_config?.temperature || 'N/A')}</span>
                    </div>
                    <div class="ldr-config-item">
                        <span class="ldr-config-label">Provider:</span>
                        <span class="ldr-config-value">${escapeHtml(run.search_config?.provider || 'N/A')}</span>
                    </div>
                </div>

                <div id="examples-${run.id}">
                    <div class="ldr-loading">Loading detailed results...</div>
                </div>
            </div>
        </div>
    `;
}

async function toggleRunDetails(runId) {
    const resultsSection = document.getElementById(`results-${runId}`);
    const runCard = resultsSection.closest('.ldr-run-card');

    if (resultsSection.classList.contains('ldr-visible')) {
        resultsSection.classList.remove('ldr-visible');
        runCard.classList.remove('ldr-expanded');
        return;
    }

    resultsSection.classList.add('ldr-visible');
    runCard.classList.add('ldr-expanded');

    // Load examples if not already loaded
    const examplesContainer = document.getElementById(`examples-${runId}`);
    if (examplesContainer.innerHTML.includes('Loading detailed results...')) {
        await loadExamples(runId);
    }
}

async function loadExamples(runId) {
    try {
        const response = await fetch(`/benchmark/api/results/${runId}?limit=50`);
        const data = await response.json();

        const examplesContainer = document.getElementById(`examples-${runId}`);

        if (data.success && data.results.length > 0) {
            // Calculate search result statistics
            const searchResultCounts = data.results.map(r => r.search_result_count || 0);
            const avgSearchResults = searchResultCounts.length > 0
                ? (searchResultCounts.reduce((sum, count) => sum + count, 0) / searchResultCounts.length).toFixed(1)
                : 'N/A';
            const minSearchResults = searchResultCounts.length > 0 ? Math.min(...searchResultCounts) : 'N/A';
            const maxSearchResults = searchResultCounts.length > 0 ? Math.max(...searchResultCounts) : 'N/A';

            // Create search results statistics section
            const statsHtml = `
                <div class="ldr-search-stats-section">
                    <h4 class="ldr-section-title">
                        <i aria-hidden="true" class="fas fa-search"></i> Search Results Statistics
                    </h4>
                    <div class="ldr-search-stats-grid">
                        <div class="ldr-stat-item">
                            <div class="ldr-stat-value">${avgSearchResults}</div>
                            <div class="ldr-stat-label">Avg Search Results</div>
                        </div>
                        <div class="ldr-stat-item">
                            <div class="ldr-stat-value">${minSearchResults}</div>
                            <div class="ldr-stat-label">Min Results</div>
                        </div>
                        <div class="ldr-stat-item">
                            <div class="ldr-stat-value">${maxSearchResults}</div>
                            <div class="ldr-stat-label">Max Results</div>
                        </div>
                        <div class="ldr-stat-item">
                            <div class="ldr-stat-value">${data.results.length}</div>
                            <div class="ldr-stat-label">Total Queries</div>
                        </div>
                    </div>
                </div>
            `;

            // Create examples grid
            const examplesHtml = data.results.map(result => createExampleCard(result)).join('');

            examplesContainer.innerHTML = `
                ${statsHtml}
                <div class="ldr-results-divider"></div>
                <div class="ldr-examples-section">
                    <h4 class="ldr-section-title">
                        <i aria-hidden="true" class="fas fa-list"></i> Individual Query Results (${data.results.length} shown)
                    </h4>
                    <div class="ldr-examples-grid">${examplesHtml}</div>
                </div>
            `;
        } else {
            examplesContainer.innerHTML = '<div class="ldr-no-results">No detailed results available</div>';
        }
    } catch (error) {
        console.error('Error loading examples:', error);
        document.getElementById(`examples-${runId}`).innerHTML =
            '<div class="ldr-no-results">Error loading examples</div>';
    }
}

function formatAvgSearchResults(run) {
    if (!run.avg_search_results || run.avg_search_results <= 0) {
        return 'N/A';
    }

    return Math.round(run.avg_search_results).toString();
}

function formatAvgSearchRequests(run) {
    if (!run.total_search_requests || run.total_search_requests <= 0) {
        return 'N/A';
    }

    return Math.round(run.total_search_requests).toString();
}

function formatAvgProcessingTime(run) {
    // Calculate average processing time from completed examples
    if (!run.avg_processing_time && (!run.results || run.results.length === 0)) {
        return 'N/A';
    }

    // Use avg_processing_time if available, otherwise calculate from results
    let avgTime = run.avg_processing_time;
    if (!avgTime && run.results) {
        const timesWithValues = run.results
            .filter(r => r.processing_time && r.processing_time > 0)
            .map(r => r.processing_time);

        if (timesWithValues.length === 0) return 'N/A';
        avgTime = timesWithValues.reduce((sum, time) => sum + time, 0) / timesWithValues.length;
    }

    if (!avgTime || avgTime <= 0) return 'N/A';

    // Format time nicely
    if (avgTime < 60) {
        return `${avgTime.toFixed(1)}s`;
    } else if (avgTime < 3600) {
        const minutes = Math.floor(avgTime / 60);
        const seconds = Math.round(avgTime % 60);
        return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
    } else {
        const hours = Math.floor(avgTime / 3600);
        const minutes = Math.round((avgTime % 3600) / 60);
        return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
    }
}

function createExampleCard(result) {
    const statusClass = result.is_correct ? 'ldr-correct' : 'ldr-incorrect';
    const statusIcon = result.is_correct ? '<i aria-hidden="true" class="fas fa-check-circle"></i>' : '<i aria-hidden="true" class="fas fa-times-circle"></i>';
    const statusText = result.is_correct ? 'Correct' : 'Incorrect';

    // Format processing time for individual result
    const processingTime = result.processing_time && result.processing_time > 0
        ? (result.processing_time < 60
            ? `${result.processing_time.toFixed(1)}s`
            : `${Math.floor(result.processing_time / 60)}m ${Math.round(result.processing_time % 60)}s`)
        : 'N/A';

    // Format search results count
    const searchResultCount = result.search_result_count || 0;

    return `
        <div class="ldr-example-card ${statusClass}">
            <div class="ldr-example-header">
                <span class="ldr-dataset-badge">${escapeHtml(result.dataset_type)}</span>
                <span class="ldr-example-status ${statusClass}">
                    ${statusIcon} ${statusText}
                </span>
                <div class="ldr-example-metrics">
                    <span class="ldr-processing-time">⏱️ ${processingTime}</span>
                    <span class="ldr-search-results-count">🔍 ${searchResultCount} results</span>
                </div>
            </div>

            <div class="ldr-example-question">
                <strong>Question:</strong> ${escapeHtml(result.question)}
            </div>

            <div class="ldr-example-answers">
                <div class="ldr-answer-section ldr-model-answer-section">
                    <div class="ldr-answer-label">Model Answer</div>
                    <div class="ldr-answer-text">${escapeHtml(result.model_answer || 'No answer provided')}</div>
                </div>
                <div class="ldr-answer-section ldr-correct-answer-section">
                    <div class="ldr-answer-label">Expected Answer</div>
                    <div class="ldr-answer-text">${escapeHtml(result.correct_answer || 'No expected answer')}</div>
                </div>
            </div>
        </div>
    `;
}

function setupPagination() {
    const totalPages = Math.ceil(filteredRuns.length / itemsPerPage);
    const paginationDiv = document.getElementById('pagination');

    if (totalPages <= 1) {
        paginationDiv.style.display = 'none';
        return;
    }

    paginationDiv.style.display = 'flex';

    const prevBtn = document.getElementById('prev-page');
    const nextBtn = document.getElementById('next-page');
    const pageInfo = document.getElementById('page-info');

    prevBtn.disabled = currentPage === 1;
    nextBtn.disabled = currentPage === totalPages;
    pageInfo.textContent = `Page ${currentPage} of ${totalPages}`;

    prevBtn.onclick = () => {
        if (currentPage > 1) {
            currentPage--;
            displayResults();
        }
    };

    nextBtn.onclick = () => {
        if (currentPage < totalPages) {
            currentPage++;
            displayResults();
        }
    };
}

async function cancelAndDeleteBenchmarkRun(runId) {
    if (!confirm('Are you sure you want to cancel and delete this running benchmark? This action cannot be undone.')) {
        return;
    }

    try {
        // Get CSRF token
        const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

        // First cancel the benchmark
        const cancelResponse = await fetch(`/benchmark/api/cancel/${runId}`, {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': csrfToken
            }
        });

        const cancelData = await cancelResponse.json();

        if (cancelData.success) {
            showAlert('Benchmark cancelled successfully. Deleting...', 'info');

            // Wait a moment for cancellation to process
            await new Promise(resolve => setTimeout(resolve, 1000));

            // Then delete it
            await deleteBenchmarkRun(runId);
        } else {
            showAlert('Error cancelling benchmark: ' + cancelData.error, 'error');
        }
    } catch (error) {
        console.error('Error cancelling benchmark:', error);
        showAlert('Error cancelling benchmark: ' + error.message, 'error');
    }
}

// yamlEscape / formatSettingValue / formatSettingsSnapshot are defined in
// /static/js/utils/yaml_export.js (loaded via <script src> above) as globals,
// so the YAML escaping is unit-tested (tests/js/utils/yaml_export.test.js).

async function downloadBenchmarkYAML(runId, includeExamples = false, includeSettings = false) {
    try {
        // Find the run in our local data
        const run = benchmarkRuns.find(r => r.id === runId);
        if (!run) {
            showAlert('Benchmark run not found', 'error');
            return;
        }

        // Always fetch /export to stamp the YAML with the LDR version + the
        // date the benchmark RAN — not the current app version / current date
        // the user happens to download on. The full settings snapshot is only
        // requested when the user opts in (it's ~184KB and exposes the full
        // config), so the default summary download stays lean and shareable.
        // Pre-0014 rows return null fields and the YAML falls back to
        // "unknown (pre-0014 run)" gracefully.
        let exportData = { metadata: {}, results: [] };
        try {
            const exportUrl = `/benchmark/api/results/${runId}/export${includeSettings ? '?include_settings=1' : ''}`;
            const exportResponse = await fetch(exportUrl);
            exportData = await exportResponse.json();
        } catch (e) {
            console.error('Error fetching benchmark export:', e);
            // Continue with cached run data only — YAML will lack settings_snapshot
        }
        const meta = exportData.metadata || {};

        // Filename uses today's date for sortability — we want the file to
        // sort by when YOU downloaded it, not when the benchmark ran.
        const fileDate = new Date().toISOString().split('T')[0];

        // YAML's `date_tested` field MUST come from the benchmark's actual
        // start_time (or created_at as fallback). External parsers — most
        // importantly /home/coder1/code/ldr-benchmarks/scripts/build_leaderboards.py
        // — read this field for the public HuggingFace leaderboard. Pulling
        // from new Date() (the old behaviour) silently corrupted that history.
        const startedAt = meta.started_at || run.start_time || run.created_at;
        const dateTested = startedAt
            ? String(startedAt).split('T')[0]
            : fileDate;

        // Same story for ldr_version: prefer the value that was active at
        // benchmark START, then the cached run field, then a clear sentinel
        // for pre-0014 rows so users can tell the YAML predates this feature.
        // Do NOT fall back to the current app version — stamping today's
        // version onto a historical run is the exact bug this feature fixes
        // (a v1.6.5 run downloaded on v1.6.7 must not read 1.6.7).
        const ldrVersion = meta.ldr_version || run.ldr_version || 'unknown (pre-0014 run)';

        // Extract model name and clean it for filename
        const modelName = run.search_config?.model_name || 'unknown-model';
        const cleanModelName = modelName.replace(/[^a-zA-Z0-9.-]/g, '-').toLowerCase();

        // Read context window / max tokens from search_config (captured at benchmark start)
        const localContextWindow = run.search_config?.local_context_window_size ?? null;
        const cloudContextWindow = run.search_config?.context_window_size ?? null;
        const contextWindowUnrestricted = run.search_config?.context_window_unrestricted ?? null;
        const maxTokens = run.search_config?.max_tokens ?? null;

        // Determine if local provider (ollama, llamacpp, lmstudio)
        const provider = (run.search_config?.provider || '').toLowerCase();
        const isLocalProvider = ['ollama', 'llamacpp', 'lmstudio'].includes(provider);

        // Build evaluator section from evaluation_config (only safe keys, never API keys).
        // Free-form string values are double-quoted + yamlEscape()d so a model
        // name / provider / URL containing YAML-special chars (':', '#', quotes…)
        // can't produce malformed YAML.
        const evalConfig = run.evaluation_config || {};
        let evaluatorYaml = 'evaluator:\n';
        if (evalConfig.model_name) evaluatorYaml += `  model: "${yamlEscape(evalConfig.model_name)}"\n`;
        if (evalConfig.provider) evaluatorYaml += `  provider: "${yamlEscape(evalConfig.provider)}"\n`;
        // The eval endpoint URL can be a private/internal host, so gate it
        // behind the settings opt-in (same as the settings snapshot below).
        // The default summary download stays shareable without leaking an
        // internal URL; opting in includes it for full reproducibility.
        if (includeSettings && evalConfig.openai_endpoint_url) evaluatorYaml += `  endpoint_url: "${yamlEscape(evalConfig.openai_endpoint_url)}"\n`;
        if (evalConfig.temperature !== undefined && evalConfig.temperature !== null) {
            evaluatorYaml += `  temperature: ${evalConfig.temperature}\n`;
        }

        const avgSearchResults = formatAvgSearchResults(run).replace(' results', '');
        // Use actual strategy and dataset from the run, not hardcoded values.
        // datasets_config is a dict like {"simpleqa": {"count": 100}, ...}
        const strategy = run.search_config?.search_strategy;
        const datasetKeys = run.datasets_config ? Object.keys(run.datasets_config) : [];
        const dataset = datasetKeys.length > 0 ? datasetKeys[0] : 'unknown';
        // Map canonical IDs to display names
        const datasetDisplayNames = {simpleqa: 'SimpleQA', browsecomp: 'BrowseComp', xbench_deepsearch: 'xbench-DeepSearch'};
        const datasetName = datasetDisplayNames[dataset] || dataset;
        // Use completed_examples (actual evaluated) rather than total_examples (planned)
        // so the accuracy fraction and question count reflect reality.
        const evaluated = run.completed_examples || run.total_examples;
        const correctCount = run.overall_accuracy ? Math.round(run.overall_accuracy * evaluated / 100) : 0;

        // Generate compact YAML — data only, no empty placeholders
        let yamlContent = `model: "${yamlEscape(modelName)}"
model_provider: "${yamlEscape(run.search_config?.provider || 'unknown')}"
search_engine: "${yamlEscape(run.search_config?.search_tool || 'unknown')}"
${avgSearchResults !== 'N/A' ? `average_results_per_query: ${avgSearchResults}\n` : ''}results:
  dataset: "${yamlEscape(datasetName)}"
  total_questions: ${evaluated}
  ${strategy}:
    accuracy: "${run.overall_accuracy ? run.overall_accuracy.toFixed(1) : 0}% (${correctCount}/${evaluated})"
    iterations: ${run.search_config?.iterations || 'N/A'}
    questions_per_iteration: ${run.search_config?.questions_per_iteration || 'N/A'}
    avg_time_per_question: "${formatAvgProcessingTime(run)}"
configuration:
  temperature: ${run.search_config?.temperature ?? 'N/A'}
${isLocalProvider && localContextWindow != null ? `  context_window: ${localContextWindow}  # captured at benchmark start\n` : ''}${!isLocalProvider && contextWindowUnrestricted != null ? `  context_window_unrestricted: ${contextWindowUnrestricted ? 'yes' : 'no'}  # captured at benchmark start\n` : ''}${!isLocalProvider && !contextWindowUnrestricted && cloudContextWindow != null ? `  context_window: ${cloudContextWindow}  # captured at benchmark start\n` : ''}${maxTokens != null ? `  max_tokens: ${maxTokens}  # captured at benchmark start\n` : ''}${evaluatorYaml}versions:
  ldr_version: ${ldrVersion}
date_tested: ${dateTested}
`;

        // Optionally append the full (redacted) settings snapshot. Opt-in
        // only: the default download stays a shareable summary and never
        // ships internal URLs / local paths. formatSettingsSnapshot handles
        // a null snapshot (pre-0014 rows) as "settings: null # ...".
        if (includeSettings) {
            yamlContent += formatSettingsSnapshot(meta.settings_snapshot);
        }

        // Optionally append individual examples (already fetched in exportData)
        if (includeExamples) {
            if (exportData.success && exportData.results && exportData.results.length > 0) {
                yamlContent += `examples:\n`;

                for (const ex of exportData.results) {
                    const result = ex.is_correct === true ? 'correct'
                        : ex.is_correct === false ? 'incorrect'
                        : 'not_graded';
                    const time = ex.processing_time != null
                        ? Number(ex.processing_time).toFixed(1)
                        : null;

                    yamlContent += `  - question: "${yamlEscape(ex.question)}"\n`;
                    yamlContent += `    correct_answer: "${yamlEscape(ex.correct_answer)}"\n`;
                    yamlContent += `    model_answer: "${yamlEscape(ex.model_answer)}"\n`;
                    yamlContent += `    result: ${result}\n`;
                    yamlContent += `    dataset: ${ex.dataset_type || 'unknown'}\n`;
                    if (time !== null) {
                        yamlContent += `    processing_time_seconds: ${time}\n`;
                    }
                }
            } else if (!exportData.success) {
                showAlert('Could not fetch individual examples, downloading without them.', 'warning');
            }
        }

        // Create blob and download
        const blob = new Blob([yamlContent], { type: 'text/yaml' });
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.style.display = 'none';
        a.href = url;
        a.download = `${cleanModelName}_${fileDate}.yaml`;
        document.body.appendChild(a);
        a.click();
        window.URL.revokeObjectURL(url);
        document.body.removeChild(a);

        showAlert('Benchmark YAML downloaded successfully.', 'success');
    } catch (error) {
        console.error('Error downloading YAML:', error);
        showAlert('Error downloading YAML: ' + error.message, 'error');
    }
}

async function deleteBenchmarkRun(runId) {
    try {
        // Get CSRF token
        const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');

        const response = await fetch(`/benchmark/api/delete/${runId}`, {
            method: 'DELETE',
            headers: {
                'Content-Type': 'application/json',
                'X-CSRFToken': csrfToken
            }
        });

        const data = await response.json();

        if (data.success) {
            // Show success message
            showAlert('Benchmark run deleted successfully!', 'success');

            // Remove the run from our local data
            benchmarkRuns = benchmarkRuns.filter(run => run.id !== runId);

            // Reapply filters and redisplay
            applyFilters();
        } else {
            showAlert('Error deleting benchmark run: ' + data.error, 'error');
        }
    } catch (error) {
        console.error('Error deleting benchmark run:', error);
        showAlert('Error deleting benchmark run: ' + error.message, 'error');
    }
}

function showAlert(message, type) {
    // Create alert element
    const alertDiv = document.createElement('div');
    const alertType = type === 'error' ? 'danger' : type;
    alertDiv.className = `alert alert-${alertType}`;
    alertDiv.style.cssText = `
        position: fixed;
        top: 20px;
        right: 20px;
        z-index: 1000;
        max-width: 400px;
        padding: 15px;
        border-radius: 6px;
        color: white;
        font-weight: 500;
        box-shadow: 0 4px 12px rgba(0,0,0,0.3);
    `;

    // Set background color based on type
    const colors = {
        success: '#4caf50',
        error: '#f44336',
        warning: '#ff9800',
        info: '#2196f3'
    };
    alertDiv.style.backgroundColor = colors[type] || colors.info;

    alertDiv.innerHTML = `
        <div style="display: flex; align-items: center; justify-content: space-between;">
            <span>${escapeHtml(message)}</span>
            <button onclick="this.parentElement.parentElement.remove()" style="background: none; border: none; color: white; font-size: 1.2rem; cursor: pointer; margin-left: 10px;">&times;</button>
        </div>
    `;

    document.body.appendChild(alertDiv);

    // Auto-remove after 5 seconds
    setTimeout(() => {
        if (alertDiv.parentElement) {
            alertDiv.remove();
        }
    }, 5000);
}
</script>
{% endblock %}
