/**
 * Note: URLValidator is available globally via /static/js/security/url-validator.js
 * Research Details Component
 * Manages the display of research details and token metrics for a specific research
 */
(function() {
    /**
     * Get chart colors from CSS variables for theme support
     */
    function getChartColors() {
        const style = getComputedStyle(document.documentElement);
        return {
            // Primary accent (for total/main data)
            accent: style.getPropertyValue('--accent-primary').trim() || '#6e4ff6',
            accentRgb: style.getPropertyValue('--accent-primary-rgb').trim() || '110, 79, 246',
            // Tertiary accent (for input tokens)
            tertiary: style.getPropertyValue('--accent-tertiary').trim() || '#40bfff',
            tertiaryRgb: style.getPropertyValue('--accent-tertiary-rgb').trim() || '64, 191, 255',
            // Error color (for output tokens)
            error: style.getPropertyValue('--error-color').trim() || '#fa5c7c',
            errorRgb: style.getPropertyValue('--error-color-rgb').trim() || '250, 92, 124',
            // Success color
            success: style.getPropertyValue('--success-color').trim() || '#0acf97',
            successRgb: style.getPropertyValue('--success-color-rgb').trim() || '10, 207, 151',
            // Text colors
            textPrimary: style.getPropertyValue('--text-primary').trim() || '#f5f5f5',
            textMuted: style.getPropertyValue('--text-muted').trim() || '#8a8aa0',
            // Background
            bgPrimary: style.getPropertyValue('--bg-primary').trim() || '#121212',
        };
    }

    // DOM Elements
    let queryElement = null;
    let statusElement = null;
    let modeElement = null;
    let progressBar = null;
    let progressPercentage = null;
    let pollInterval = null;

    // Token metrics elements
    let timelineChart = null;

    // Component state
    let currentResearchId = null;
    let isCompleted = false;

    /**
     * Initialize the research details component
     */
    async function initializeResearchDetails() {
        SafeLogger.log('Initializing research details component...');

        // Get research ID from URL
        currentResearchId = getResearchIdFromUrl();

        if (!currentResearchId) {
            SafeLogger.error('No research ID found in URL');
            if (window.ui && window.ui.showError) {
                window.ui.showError('No research ID found. Please return to the history page.');
            }
            return;
        }

        SafeLogger.log('Research ID:', currentResearchId);

        // Get DOM elements
        queryElement = document.getElementById('detail-query');
        statusElement = document.getElementById('detail-status');
        modeElement = document.getElementById('detail-mode');
        progressBar = document.getElementById('detail-progress-fill');
        progressPercentage = document.getElementById('detail-progress-percentage');

        SafeLogger.log('DOM elements found, setting up event listeners...');

        // Set up event listeners
        setupEventListeners();

        // Load initial research details
        await loadResearchDetails();

        // Start polling for updates (only if needed)
        startPolling();

        SafeLogger.log('Research details component initialized');
    }

    /**
     * Extract research ID from URL
     * @returns {string|null} Research ID or null if not found
     */
    function getResearchIdFromUrl() {
        return URLBuilder.extractResearchIdFromPattern('details');
    }

    /**
     * Set up event listeners
     */
    function setupEventListeners() {
        const viewResultsButton = document.getElementById('view-results-btn');
        if (viewResultsButton) {
            viewResultsButton.addEventListener('click', function() {
                // bearer:disable javascript_lang_open_redirect — URLBuilder produces /results/{id}
                window.location.href = URLBuilder.resultsPage(currentResearchId);
            });
        }

        const backButton = document.getElementById('back-to-history-from-details');
        if (backButton) {
            backButton.addEventListener('click', function() {
                window.location.href = URLS.PAGES.HISTORY;
            });
        }
    }

    /**
     * Load basic research details (for polling)
     */
    async function loadBasicResearchDetails() {
        SafeLogger.log('Loading basic research details...');

        try {
            const response = await fetch(URLBuilder.researchDetails(currentResearchId), {
                headers: {
                    'Accept': 'application/json'
                }
            });

            if (!response.ok) {
                throw new Error(`Failed to load research details: ${response.statusText}`);
            }

            const data = await response.json();

            // Update UI with research details
            updateResearchInfo(data);

            // Check if research is in a terminal state
            isCompleted = data.status === 'completed' || data.status === 'failed' || data.status === 'suspended';

        } catch (error) {
            SafeLogger.error('Error loading basic research details:', error);
        }
    }

    /**
     * Load research details from API (full load including token metrics)
     */
    async function loadResearchDetails() {
        SafeLogger.log('Loading research details...');

        try {
            // Fetch research details
            const response = await fetch(URLBuilder.researchDetails(currentResearchId), {
                headers: {
                    'Accept': 'application/json'
                }
            });

            if (!response.ok) {
                throw new Error(`Failed to load research details: ${response.statusText}`);
            }

            const data = await response.json();
            SafeLogger.log('Research details loaded:', data);

            // Update UI with research details
            updateResearchInfo(data);

            // Check if research is in a terminal state
            isCompleted = data.status === 'completed' || data.status === 'failed' || data.status === 'suspended';
            if (isCompleted && pollInterval) {
                clearInterval(pollInterval);
                pollInterval = null;
            }

            // Load token metrics
            await loadTokenMetrics();

            // Load search metrics
            await loadSearchMetrics();

        } catch (error) {
            SafeLogger.error('Error loading research details:', error);
            if (window.ui && window.ui.showError) {
                window.ui.showError('Error loading research details: ' + error.message);
            }
        }
    }

    /**
     * Update research info display
     * @param {Object} data - Research data
     */
    function updateResearchInfo(data) {
        if (queryElement) {
            queryElement.textContent = data.query || 'N/A';
        }

        if (statusElement) {
            statusElement.textContent = data.status || 'N/A';
            statusElement.className = 'ldr-metadata-value ldr-status-' + (data.status || 'unknown').toLowerCase();
        }

        if (modeElement) {
            modeElement.textContent = data.mode || 'standard';
        }

        // Update progress
        const progress = data.progress_percentage || 0;
        if (progressBar) {
            progressBar.style.width = progress + '%';
        }
        if (progressPercentage) {
            progressPercentage.textContent = progress + '%';
        }
    }

    /**
     * Load search metrics for this research
     */
    async function loadSearchMetrics() {
        SafeLogger.log('Loading search metrics...');

        try {
            const response = await fetch(URLBuilder.build(URLS.METRICS_API.RESEARCH_SEARCH, currentResearchId), {
                headers: {
                    'Accept': 'application/json'
                }
            });

            if (!response.ok) {
                SafeLogger.log('No search metrics available for this research');
                return;
            }

            const data = await response.json();

            if (data.status === 'success' && data.metrics) {
                SafeLogger.log('Search metrics loaded:', data.metrics);
                displaySearchMetrics(data.metrics);
                displaySearchEnginePerformance(data.metrics.engine_stats || []);
                displaySearchTimeline(data.metrics.search_calls || []);
            }

        } catch (error) {
            SafeLogger.error('Error loading search metrics:', error);
        }
    }

    /**
     * Display search metrics summary
     * @param {Object} searchData - Search metrics data
     */
    function displaySearchMetrics(searchData) {
        const searchSummary = document.getElementById('search-summary');
        if (!searchSummary || !searchData) return;

        // Show the search analytics section
        const searchSection = document.getElementById('search-metrics-section');
        if (searchSection) {
            searchSection.style.display = 'block';
        }

        const totalSearches = searchData.total_searches || 0;
        const successRate = searchData.success_rate || 0;
        const avgResponseTime = (searchData.avg_response_time || 0) / 1000; // Convert ms to seconds
        const totalResults = searchData.total_results || 0;

        // Update individual metric elements
        const totalSearchesEl = document.getElementById('total-searches');
        const totalResultsEl = document.getElementById('total-search-results');
        const avgResponseTimeEl = document.getElementById('avg-search-response-time');
        const successRateEl = document.getElementById('search-success-rate');

        if (totalSearchesEl) totalSearchesEl.textContent = totalSearches;
        if (totalResultsEl) totalResultsEl.textContent = formatNumber(totalResults);
        if (avgResponseTimeEl) avgResponseTimeEl.textContent = avgResponseTime.toFixed(2) + 's';
        if (successRateEl) successRateEl.textContent = successRate.toFixed(1) + '%';
    }

    /**
     * Display search engine performance breakdown
     * @param {Array} enginePerformance - Search engine performance data
     */
    function displaySearchEnginePerformance(enginePerformance) {
        const engineContainer = document.getElementById('search-engine-performance');
        if (!engineContainer) return;

        if (!enginePerformance || enginePerformance.length === 0) {
            engineContainer.innerHTML = '<p style="text-align: center; color: var(--text-secondary);">No search engine data available</p>';
            return;
        }

        const engineHtml = enginePerformance.map(engine => `
            <div class="search-engine-item">
                <div class="engine-name">${escapeHtml(engine.engine)}</div>
                <div class="engine-stats">
                    <span class="stat">${engine.call_count} searches</span>
                    <span class="stat">${engine.success_rate.toFixed(1)}% success</span>
                    <span class="stat">${(engine.avg_response_time / 1000).toFixed(2)}s avg</span>
                    <span class="stat">${formatNumber(engine.total_results)} results</span>
                </div>
            </div>
        `).join('');

        // bearer:disable javascript_lang_dangerous_insert_html
        engineContainer.innerHTML = engineHtml;
    }

    /**
     * Display search timeline
     * @param {Array} searchTimeline - Search timeline data
     */
    function displaySearchTimeline(searchTimeline) {
        const timelineContainer = document.getElementById('search-timeline');
        if (!timelineContainer) return;

        if (!searchTimeline || searchTimeline.length === 0) {
            timelineContainer.innerHTML = '<p style="text-align: center; color: var(--text-secondary);">No search timeline data available</p>';
            return;
        }

        const timelineHtml = searchTimeline.map(search => {
            const timestamp = new Date(search.timestamp).toLocaleTimeString();
            const statusClass = search.success_status === 'success' ? 'success' : 'error';
            const statusText = search.success_status === 'success' ? 'Success' : 'Failed';

            return `
                <div class="timeline-item">
                    <div class="timeline-time">${timestamp}</div>
                    <div class="timeline-engine">${escapeHtml(search.engine)}</div>
                    <div class="timeline-query">${escapeHtml(search.query)}</div>
                    <div class="timeline-results">${formatNumber(search.results_count)} results</div>
                    <div class="timeline-response">${(search.response_time_ms / 1000).toFixed(2)}s</div>
                    <div class="timeline-status ${statusClass}">${statusText}</div>
                </div>
            `;
        }).join('');

        // bearer:disable javascript_lang_dangerous_insert_html
        timelineContainer.innerHTML = timelineHtml;
    }


    /**
     * Start polling for updates (only if research is not completed)
     */
    function startPolling() {
        // Only poll if research is not completed
        if (!isCompleted) {
            SafeLogger.log('Starting polling for updates...');

            // Poll every 10 seconds (much less frequent)
            pollInterval = setInterval(async () => {
                if (!isCompleted) {
                    // Only reload basic research info, not token metrics
                    await loadBasicResearchDetails();
                } else {
                    // Stop polling once completed
                    if (pollInterval) {
                        clearInterval(pollInterval);
                        pollInterval = null;
                        SafeLogger.log('Research completed, stopped polling');
                    }
                }
            }, 10000);
        } else {
            SafeLogger.log('Research already completed, no polling needed');
        }
    }

    /**
     * Load token metrics for this research
     */
    async function loadTokenMetrics() {
        SafeLogger.log('Loading token metrics...');

        try {
            const response = await fetch(URLBuilder.build(URLS.METRICS_API.RESEARCH_TIMELINE, currentResearchId), {
                headers: {
                    'Accept': 'application/json'
                }
            });

            if (!response.ok) {
                SafeLogger.log('No token metrics available for this research');
                return;
            }

            const data = await response.json();

            if (data.status === 'success') {
                SafeLogger.log('Token metrics loaded:', data.metrics);
                displayTokenMetrics(data.metrics);
            }

        } catch (error) {
            SafeLogger.error('Error loading token metrics:', error);
        }
    }

    /**
     * Display token metrics on the page
     * @param {Object} metrics - Token metrics data
     */
    function displayTokenMetrics(metrics) {
        SafeLogger.log('Displaying token metrics with data:', metrics);

        // Show the metrics section
        const metricsSection = document.getElementById('token-metrics-section');
        if (metricsSection) {
            metricsSection.style.display = 'block';
        }

        // Update summary cards with safe data access
        const summary = metrics.summary || {};
        const totalTokensEl = document.getElementById('total-tokens');
        const totalPromptTokensEl = document.getElementById('total-prompt-tokens');
        const totalCompletionTokensEl = document.getElementById('total-completion-tokens');
        const totalCallsEl = document.getElementById('total-calls');
        const avgResponseTimeEl = document.getElementById('avg-response-time');
        const successRateEl = document.getElementById('success-rate');

        if (totalTokensEl) totalTokensEl.textContent = formatNumber(summary.total_tokens || 0);
        if (totalPromptTokensEl) totalPromptTokensEl.textContent = formatNumber(summary.total_prompt_tokens || 0);
        if (totalCompletionTokensEl) totalCompletionTokensEl.textContent = formatNumber(summary.total_completion_tokens || 0);
        if (totalCallsEl) totalCallsEl.textContent = formatNumber(summary.total_calls || 0);
        if (avgResponseTimeEl) avgResponseTimeEl.textContent = (summary.avg_response_time || 0) + 'ms';
        if (successRateEl) successRateEl.textContent = (summary.success_rate || 0) + '%';

        // Create timeline chart
        createTimelineChart(metrics.timeline);

        // Display phase breakdown
        displayPhaseBreakdown(metrics.phase_stats);

        // Display call stack traces
        displayCallStackTraces(metrics.timeline);
    }

    /**
     * Create timeline chart
     * @param {Array} timeline - Timeline data
     */
    function createTimelineChart(timeline) {
        const ctx = document.getElementById('timeline-chart');
        if (!ctx) return;

        // Handle empty timeline
        if (!timeline || timeline.length === 0) {
            SafeLogger.log('No timeline data available');
            ctx.getContext('2d').clearRect(0, 0, ctx.width, ctx.height);

            // Show a message in the chart area
            const chartContainer = ctx.parentElement;
            if (chartContainer) {
                chartContainer.innerHTML = '<div style="text-align: center; padding: 2rem; color: var(--text-secondary);">No token usage timeline available for this research.<br>This research may have used search-only mode or meta search engine.</div>';
            }
            return;
        }

        // Prepare data
        const labels = timeline.map(item => {
            const date = new Date(item.timestamp);
            return date.toLocaleTimeString('en-US', {
                hour: '2-digit',
                minute: '2-digit',
                second: '2-digit'
            });
        });

        const cumulativeTokens = timeline.map(item => item.cumulative_tokens);
        const cumulativePromptTokens = timeline.map(item => item.cumulative_prompt_tokens);
        const cumulativeCompletionTokens = timeline.map(item => item.cumulative_completion_tokens);
        const promptTokens = timeline.map(item => item.prompt_tokens);
        const completionTokens = timeline.map(item => item.completion_tokens);

        // Debug logging
        SafeLogger.log('Timeline data sample:', timeline.slice(0, 2));
        SafeLogger.log('Prompt tokens sample:', promptTokens.slice(0, 5));
        SafeLogger.log('Completion tokens sample:', completionTokens.slice(0, 5));

        // Destroy existing chart
        if (timelineChart) {
            timelineChart.destroy();
        }

        // Get theme-aware colors
        const colors = getChartColors();

        timelineChart = new Chart(ctx, {
            type: 'line',
            data: {
                labels: labels,
                datasets: [{
                    label: 'Cumulative Total Tokens',
                    data: cumulativeTokens,
                    borderColor: colors.success,
                    backgroundColor: `rgba(${colors.successRgb}, 0.1)`,
                    borderWidth: 3,
                    fill: true,
                    tension: 0.1,
                    pointRadius: 4,
                    pointHoverRadius: 6,
                }, {
                    label: 'Cumulative Input Tokens',
                    data: cumulativePromptTokens,
                    borderColor: colors.tertiary,
                    backgroundColor: `rgba(${colors.tertiaryRgb}, 0.05)`,
                    borderWidth: 2,
                    fill: true,
                    tension: 0.1,
                    pointRadius: 2,
                    pointHoverRadius: 4,
                }, {
                    label: 'Cumulative Output Tokens',
                    data: cumulativeCompletionTokens,
                    borderColor: colors.error,
                    backgroundColor: `rgba(${colors.errorRgb}, 0.05)`,
                    borderWidth: 2,
                    fill: true,
                    tension: 0.1,
                    pointRadius: 2,
                    pointHoverRadius: 4,
                }, {
                    label: 'Input Tokens per Call',
                    data: promptTokens,
                    borderColor: `rgba(${colors.tertiaryRgb}, 0.8)`,
                    backgroundColor: `rgba(${colors.tertiaryRgb}, 0.1)`,
                    borderWidth: 1,
                    fill: false,
                    tension: 0.1,
                    pointRadius: 2,
                    pointHoverRadius: 4,
                    yAxisID: 'y1',
                    borderDash: [5, 5],
                }, {
                    label: 'Output Tokens per Call',
                    data: completionTokens,
                    borderColor: `rgba(${colors.errorRgb}, 0.8)`,
                    backgroundColor: `rgba(${colors.errorRgb}, 0.1)`,
                    borderWidth: 1,
                    fill: false,
                    tension: 0.1,
                    pointRadius: 2,
                    pointHoverRadius: 4,
                    yAxisID: 'y1',
                    borderDash: [5, 5],
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                interaction: {
                    intersect: false,
                    mode: 'index'
                },
                scales: {
                    x: {
                        display: true,
                        title: {
                            display: true,
                            text: 'Time'
                        }
                    },
                    y: {
                        type: 'linear',
                        display: true,
                        position: 'left',
                        title: {
                            display: true,
                            text: 'Cumulative Tokens'
                        },
                        beginAtZero: true
                    },
                    y1: {
                        type: 'linear',
                        display: true,
                        position: 'right',
                        title: {
                            display: true,
                            text: 'Tokens per Call'
                        },
                        beginAtZero: true,
                        grid: {
                            drawOnChartArea: false,
                        },
                    }
                },
                plugins: {
                    legend: {
                        position: 'top'
                    },
                    tooltip: {
                        callbacks: {
                            title: function(context) {
                                const index = context[0].dataIndex;
                                const item = timeline[index];
                                return `${item.research_phase || 'Unknown Phase'} - ${item.model_name || 'Unknown Model'}`;
                            },
                            label: function(context) {
                                let label = context.dataset.label || '';
                                if (label) {
                                    label += ': ';
                                }
                                label += formatNumber(context.parsed.y);
                                return label;
                            },
                            afterBody: function(context) {
                                const index = context[0].dataIndex;
                                const item = timeline[index];
                                return [
                                    `Response Time: ${item.response_time_ms || 0}ms`,
                                    `Status: ${item.success_status || 'unknown'}`,
                                    `Engine: ${item.search_engine_selected || 'N/A'}`
                                ];
                            }
                        }
                    }
                }
            }
        });
    }

    /**
     * Display phase breakdown
     * @param {Object} phaseStats - Phase statistics
     */
    function displayPhaseBreakdown(phaseStats) {
        const container = document.getElementById('phase-breakdown');
        if (!container) return;

        container.innerHTML = '';

        Object.keys(phaseStats).forEach(phase => {
            const stats = phaseStats[phase];
            const item = document.createElement('div');
            item.className = 'ldr-phase-stat-item';
            // bearer:disable javascript_lang_dangerous_insert_html
            item.innerHTML = `
                <div class="phase-name">${escapeHtml(phase)}</div>
                <div class="phase-tokens">${formatNumber(stats.tokens)} tokens</div>
                <div class="phase-calls">${stats.count} calls | ${stats.avg_response_time}ms avg</div>
            `;
            container.appendChild(item);
        });
    }

    /**
     * Display call stack traces for LLM calls
     * @param {Array} timeline - Timeline data with call stack info
     */
    function displayCallStackTraces(timeline) {
        const container = document.getElementById('call-stack-traces');
        if (!container) return;

        container.innerHTML = '';

        // Filter timeline items that have call stack information
        const itemsWithCallStack = timeline.filter(item => item.call_stack || item.calling_function);

        if (itemsWithCallStack.length === 0) {
            container.innerHTML = '<p style="text-align: center; color: var(--text-secondary);">No call stack traces available for this research</p>';
            return;
        }

        itemsWithCallStack.forEach((item, index) => {
            const trace = document.createElement('div');
            trace.style.marginBottom = '1rem';
            trace.style.padding = '0.75rem';
            trace.style.backgroundColor = 'var(--card-bg)';
            trace.style.borderRadius = '6px';
            trace.style.border = '1px solid var(--border-color)';

            // Format timestamp
            const timestamp = item.timestamp ? new Date(item.timestamp).toLocaleTimeString() : 'Unknown time';

            // bearer:disable javascript_lang_dangerous_insert_html
            trace.innerHTML = `
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
                    <div style="font-weight: 500; color: var(--text-primary);">
                        ${escapeHtml(item.calling_function || 'Unknown Function')}
                    </div>
                    <div style="font-size: 0.875rem; color: var(--text-secondary);">
                        ${timestamp} - ${item.prompt_tokens || 0} in + ${item.completion_tokens || 0} out = ${item.tokens || 0} tokens, ${item.response_time_ms || 0}ms
                    </div>
                </div>
                <div style="font-family: 'Courier New', monospace; font-size: 0.75rem; background: var(--bg-color); padding: 0.5rem; border-radius: 4px; color: var(--text-secondary); overflow-x: auto; margin-bottom: 0.5rem;">
                    ${escapeHtml(item.call_stack || 'No stack trace available')}
                </div>
                <div style="display: grid; grid-template-columns: repeat(auto-fit, minmax(120px, 1fr)); gap: 0.5rem; font-size: 0.875rem;">
                    <div><strong>File:</strong> ${escapeHtml((item.calling_file || 'Unknown').split('/').pop())}</div>
                    <div><strong>Phase:</strong> ${escapeHtml(item.research_phase || 'N/A')}</div>
                    <div><strong>Model:</strong> ${escapeHtml(item.model_name || 'N/A')}</div>
                    <div><strong>Status:</strong>
                        <span style="color: ${item.success_status === 'success' ? 'green' : 'red'}">
                            ${escapeHtml(item.success_status || 'Unknown')}
                        </span>
                    </div>
                </div>
            `;
            container.appendChild(trace);
        });
    }

    /**
     * Format large numbers with commas
     * @param {number} num - Number to format
     * @returns {string} Formatted number
     */
    function formatNumber(num) {
        return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
    }

    /**
     * Fallback HTML escape function (used if xss-protection.js fails to load).
     * NOTE: This declaration is safe because it is INSIDE an IIFE (function scope).
     * Do NOT move it to top-level scope — it would conflict with the global
     * escapeHtmlFallback in services/ui.js and crash the page.
     */
    // bearer:disable javascript_lang_manual_html_sanitization — intentional defense-in-depth XSS fallback
    const escapeHtmlFallback = (str) => String(str || '').replace(/[&<>"']/g, (m) => ({'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'})[m]);

    // Use global escapeHtml from xss-protection.js with fallback
    const escapeHtml = window.escapeHtml || escapeHtmlFallback;

    // Clean up on page unload
    window.addEventListener('beforeunload', function() {
        if (pollInterval) {
            clearInterval(pollInterval);
        }
    });

    // Initialize on DOM content loaded
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', () => {
            initializeResearchDetails().catch(console.error);
        });
    } else {
        initializeResearchDetails().catch(console.error);
    }
})();
