// Main application functionality
document.addEventListener('DOMContentLoaded', () => {
    // Global socket variable - initialize as null
    let socket = null;
    let socketConnected = false;
    
    // Global state variables
    let isResearchInProgress = false;
    let currentResearchId = null;
    window.currentResearchId = null;
    
    // Polling interval for research status
    let pollingInterval = null;
    
    // Sound notification variables
    let successSound = null;
    let errorSound = null;
    let notificationsEnabled = true;
    
    // Add function to cleanup research resources globally
    window.cleanupResearchResources = function() {
        console.log('Cleaning up research resources');
        
        // Disconnect any active sockets
        disconnectAllSockets();
        
        // Remove any active research data
        if (window.currentResearchId) {
            console.log(`Cleaning up research ID: ${window.currentResearchId}`);
            window.currentResearchId = null;
        }
        
        // Reset any active timers
        if (pollingInterval) {
            clearInterval(pollingInterval);
            pollingInterval = null;
            console.log('Cleared polling interval during cleanup');
        }
        
        // Reset research state flags
        isResearchInProgress = false;
    };
    
    // Initialize notification sounds
    function initializeSounds() {
        successSound = new Audio('/research/static/sounds/success.mp3');
        errorSound = new Audio('/research/static/sounds/error.mp3');
        successSound.volume = 0.7;
        errorSound.volume = 0.7;
    }
    
    // Function to play a notification sound
    function playNotificationSound(type) {
        console.log(`Attempting to play ${type} notification sound`);
        if (!notificationsEnabled) {
            console.log('Notifications are disabled');
            return;
        }
        
        // Play sounds regardless of tab focus
        if (type === 'success' && successSound) {
            console.log('Playing success sound');
            successSound.play().catch(err => console.error('Error playing success sound:', err));
        } else if (type === 'error' && errorSound) {
            console.log('Playing error sound');
            errorSound.play().catch(err => console.error('Error playing error sound:', err));
        } else {
            console.warn(`Unknown sound type or sound not initialized: ${type}`);
        }
    }
    
    // Initialize socket only when needed with a timeout for safety
    function initializeSocket() {
        if (socket) {
            // If we already have a socket but it's disconnected, reconnect
            if (!socketConnected) {
                try {
                    console.log('Socket disconnected, reconnecting...');
                    socket.connect();
                } catch (e) {
                    console.error('Error reconnecting socket:', e);
                    // Create a new socket
                    socket = null;
                    return initializeSocket();
                }
            }
            return socket; 
        }
        
        console.log('Initializing socket connection...');
        // Create new socket connection with optimized settings for threading mode
        socket = io({
            path: '/research/socket.io',
            transports: ['polling', 'websocket'], // Try polling first, then websocket
            reconnection: true,
            reconnectionAttempts: 10,
            reconnectionDelay: 1000,
            timeout: 25000, // Increase timeout further
            autoConnect: true,
            forceNew: true,
            upgrade: false // Disable automatic transport upgrade for more stability
        });
        
        // Add event handlers
        socket.on('connect', () => {
            console.log('Socket connected');
            socketConnected = true;
            
            // If we're reconnecting and have a current research, resubscribe
            if (currentResearchId) {
                console.log(`Reconnected, resubscribing to research ${currentResearchId}`);
                socket.emit('subscribe_to_research', { research_id: currentResearchId });
            }
        });
        
        socket.on('disconnect', () => {
            console.log('Socket disconnected');
            socketConnected = false;
        });
        
        socket.on('connect_error', (error) => {
            console.error('Socket connection error:', error);
            socketConnected = false;
        });
        
        socket.on('error', (error) => {
            console.error('Socket error:', error);
        });
        
        // Set a timeout to detect hanging connections
        let connectionTimeoutId = setTimeout(() => {
            if (!socketConnected) {
                console.log('Socket connection timeout - forcing reconnect');
                try {
                    if (socket) {
                        // First try to disconnect cleanly
                        try {
                            socket.disconnect();
                        } catch (disconnectErr) {
                            console.warn('Error disconnecting socket during timeout:', disconnectErr);
                        }
                        
                        // Then try to reconnect
                        try {
                            socket.connect();
                        } catch (connectErr) {
                            console.warn('Error reconnecting socket during timeout:', connectErr);
                            // Create a new socket only if connect fails
                            socket = null;
                            socket = initializeSocket();
                        }
                    } else {
                        // Socket is already null, just create a new one
                        socket = initializeSocket();
                    }
                } catch (e) {
                    console.error('Error during forced reconnect:', e);
                    // Force create a new socket
                    socket = null;
                    socket = initializeSocket();
                }
            }
        }, 15000); // Longer timeout before forcing reconnection
        
        // Clean up timeout if socket connects
        socket.on('connect', () => {
            if (connectionTimeoutId) {
                clearTimeout(connectionTimeoutId);
                connectionTimeoutId = null;
            }
        });
        
        return socket;
    }
    
    // Function to safely disconnect socket
    window.disconnectSocket = function() {
        try {
            if (socket) {
                console.log('Manually disconnecting socket');
                try {
                    // First remove all listeners
                    socket.removeAllListeners();
                } catch (listenerErr) {
                    console.warn('Error removing socket listeners:', listenerErr);
                }
                
                try {
                    // Then disconnect
                    socket.disconnect();
                } catch (disconnectErr) {
                    console.warn('Error during socket disconnect:', disconnectErr);
                }
                
                // Always set to null to allow garbage collection
                socket = null;
                socketConnected = false;
            }
        } catch (e) {
            console.error('Error disconnecting socket:', e);
            // Ensure socket is nullified even if errors occur
            socket = null;
            socketConnected = false;
        }
    };
    
    // Function to connect to socket for a research
    window.connectToResearchSocket = async function(researchId) {
        if (!researchId) {
            console.error('No research ID provided for socket connection');
            return;
        }
        
        try {
            // Check if research is terminated/suspended before connecting
            const response = await fetch(getApiUrl(`/api/research/${researchId}`));
            const data = await response.json();
            
            // Don't connect to socket for terminated or suspended research
            if (data.status === 'suspended' || data.status === 'failed') {
                console.log(`Not connecting socket for ${data.status} research ${researchId}`);
                
                // Make sure UI reflects the suspended state
                updateTerminationUIState('suspended', `Research was ${data.status}`);
                return;
            }
            // Don't connect to completed research
            else if (data.status === 'completed') {
                console.log(`Not connecting socket for completed research ${researchId}`);
                return;
            }
            
            console.log(`Connecting to socket for research ${researchId} (status: ${data.status})`);
            
            // Initialize socket if it doesn't exist
            if (!socket) {
                initializeSocket();
            }
            
            // Subscribe to the research channel
            if (socket && socket.connected) {
                socket.emit('subscribe_to_research', { research_id: researchId });
                console.log(`Subscribed to research ${researchId}`);
            } else {
                console.warn('Socket not connected, waiting for connection...');
                // Wait for socket to connect
                const maxAttempts = 5;
                let attempts = 0;
                
                const socketConnectInterval = setInterval(() => {
                    attempts++;
                    if (socket && socket.connected) {
                        socket.emit('subscribe_to_research', { research_id: researchId });
                        console.log(`Subscribed to research ${researchId} after ${attempts} attempts`);
                        clearInterval(socketConnectInterval);
                    } else if (attempts >= maxAttempts) {
                        console.error(`Failed to connect to socket after ${maxAttempts} attempts`);
                        clearInterval(socketConnectInterval);
                        addConsoleLog('Failed to connect to real-time updates', 'error');
                    }
                }, 1000);
            }
        } catch (error) {
            console.error(`Error connecting to socket for research ${researchId}:`, error);
        }
    };

    // Format the research status for display
    function formatStatus(status) {
        if (!status) return 'Unknown';
        
        // Handle in_progress specially
        if (status === 'in_progress') return 'In Progress';
        
        // Capitalize first letter for other statuses
        return status.charAt(0).toUpperCase() + status.slice(1).toLowerCase();
    }

    // Format the research mode for display
    function formatMode(mode) {
        if (!mode) return 'Unknown';
        
        return mode === 'detailed' ? 'Detailed Report' : 'Quick Summary';
    }

    // Format a date for display
    function formatDate(date, duration = null) {
        // Handle null/undefined gracefully
        if (!date) return 'Unknown';
            
        // Check if we have a date string instead of a Date object
        if (typeof date === 'string') {
            try {
                // Handle ISO string with microseconds (which causes problems)
                if (date.includes('.') && date.includes('T')) {
                    // Extract only up to milliseconds (3 digits after dot) or remove microseconds entirely
                    const parts = date.split('.');
                    if (parts.length > 1) {
                        // If there's a Z or + or - after microseconds, preserve it
                        let timezone = '';
                        const microsecondPart = parts[1];
                        const tzIndex = microsecondPart.search(/[Z+-]/);
                        
                        if (tzIndex !== -1) {
                            timezone = microsecondPart.substring(tzIndex);
                        }
                        
                        // Use only milliseconds (first 3 digits after dot) or none if format issues
                        const milliseconds = microsecondPart.substring(0, Math.min(3, tzIndex !== -1 ? tzIndex : microsecondPart.length));
                        
                        // Reconstruct with controlled precision
                        const cleanedDateStr = parts[0] + (milliseconds.length > 0 ? '.' + milliseconds : '') + timezone;
                        date = new Date(cleanedDateStr);
                    } else {
                        date = new Date(date);
                    }
                } else {
                    date = new Date(date);
                }
            } catch (e) {
                console.warn('Error parsing date string:', e);
                return 'Invalid date'; // Return error message if we can't parse
            }
        }
        
        // Ensure we're handling the date properly
        if (!(date instanceof Date) || isNaN(date.getTime())) {
            console.warn('Invalid date provided to formatDate:', date);
            return 'Invalid date';
        }
        
        // Get current year to compare with date year
        const currentYear = new Date().getFullYear();
        const dateYear = date.getFullYear();
        
        // Get month name, day, and time
        const month = date.toLocaleString('en-US', { month: 'short' });
        const day = date.getDate();
        const hours = date.getHours().toString().padStart(2, '0');
        const minutes = date.getMinutes().toString().padStart(2, '0');
        
        // Format like "Feb 25, 08:09" or "Feb 25, 2022, 08:09" if not current year
        let formattedDate;
        if (dateYear === currentYear) {
            formattedDate = `${month} ${day}, ${hours}:${minutes}`;
        } else {
            formattedDate = `${month} ${day}, ${dateYear}, ${hours}:${minutes}`;
        }
        
        // Add duration if provided
        if (duration) {
            let durationText = '';
            const durationSec = typeof duration === 'number' ? duration : parseInt(duration);
            
            if (durationSec < 60) {
                durationText = `${durationSec}s`;
            } else if (durationSec < 3600) {
                durationText = `${Math.floor(durationSec / 60)}m ${durationSec % 60}s`;
            } else {
                durationText = `${Math.floor(durationSec / 3600)}h ${Math.floor((durationSec % 3600) / 60)}m`;
            }
            
            formattedDate += ` (Duration: ${durationText})`;
        }
        
        return formattedDate;
    }

    // Update the socket event handler to fix termination handling
    window.handleResearchProgressEvent = function(data) {
        console.log('Research progress update:', data);
        
        // Extract research ID from the event
        const eventResearchId = getActiveResearchId();
        
        // Track processed messages to prevent duplicates
        window.processedMessages = window.processedMessages || new Set();
        
        // Add to console log if there's a message
        if (data.message) {
            let logType = 'info';
            
            // Create a unique identifier for this message (message + timestamp if available)
            const messageId = data.message + (data.log_entry?.time || '');
            
            // Check if we've already processed this message
            if (!window.processedMessages.has(messageId)) {
                window.processedMessages.add(messageId);
                
                // Determine log type based on status or message content
                if (data.status === 'failed' || data.status === 'suspended' || data.status === 'terminating') {
                    logType = 'error';
                } else if (isMilestoneLog(data.message, data.log_entry?.metadata)) {
                    logType = 'milestone';
                }
                
                // Store meaningful messages to avoid overwriting with generic messages
                if (data.message && data.message !== 'Processing research...') {
                    window.lastMeaningfulStatusMessage = data.message;
                }
                
                // Extract metadata for search engine information
                const metadata = data.log_entry?.metadata || null;
                
                // Pass metadata to addConsoleLog for potential search engine info
                // Pass the research ID to respect the current viewing context
                addConsoleLog(data.message, logType, metadata, eventResearchId);
            }
        }
        
        // Add error messages to log
        if (data.error && !window.processedMessages.has('error:' + data.error)) {
            window.processedMessages.add('error:' + data.error);
            addConsoleLog(data.error, 'error', null, eventResearchId);
            
            // Store error as last meaningful message
            window.lastMeaningfulStatusMessage = data.error;
        }
        
        // Update progress UI if progress is provided
        if (data.progress !== undefined) {
            const displayMessage = data.message || window.lastMeaningfulStatusMessage || 'Processing research...';
            updateProgressUI(data.progress, data.status, displayMessage);
        }
        
        // Update detail log if log_entry is provided
        if (data.log_entry) {
            updateDetailLogEntry(data.log_entry);
        }
        
        // Handle status changes
        if (data.status) {
            // Special handling for terminating status and handling already terminated research
            if (data.status === 'terminating') {
                // Immediately mark as suspended and update UI
                isResearchInProgress = false;
                
                // Update UI state
                updateTerminationUIState('suspending', data.message || 'Terminating research...');
            }
            // Handle suspended research specifically
            else if (data.status === 'suspended') {
                console.log('Research was suspended, updating UI directly');
                
                const researchId = getActiveResearchId();
                if (!researchId) return;
                
                // Mark research as not in progress
                isResearchInProgress = false;
                
                // Clear polling interval
                if (pollingInterval) {
                    console.log('Clearing polling interval due to suspension');
                    clearInterval(pollingInterval);
                    pollingInterval = null;
                }
                
                // Play error notification sound
                playNotificationSound('error');
                
                // Update UI for suspended research
                updateTerminationUIState('suspended', data.message || 'Research was suspended');
                
                // Add console log
                addConsoleLog('Research suspended', 'error');
                
                // Reset lastMeaningfulStatusMessage for next research
                window.lastMeaningfulStatusMessage = '';
                
                // Reset current research ID
                currentResearchId = null;
                window.currentResearchId = null;
                
                // Update navigation
                updateNavigationBasedOnResearchStatus();
                
                // Refresh history if on history page
                if (document.getElementById('history').classList.contains('active')) {
                    loadResearchHistory();
                }
            }
            // Handle completion states
            else if (data.status === 'completed' || data.status === 'failed') {
                const researchId = getActiveResearchId();
                if (!researchId) return;
                
                // Mark research as not in progress
                isResearchInProgress = false;
                
                // Clear polling interval
                if (pollingInterval) {
                    console.log('Clearing polling interval from socket event');
                    clearInterval(pollingInterval);
                    pollingInterval = null;
                }
                
                if (data.status === 'completed') {
                    // Success sound and notification
                    playNotificationSound('success');
                    
                    // Store the completed research ID for navigation
                    const completedResearchId = researchId;
                    
                    // Reset current research ID
                    currentResearchId = null;
                    window.currentResearchId = null;
                    
                    // Reset lastMeaningfulStatusMessage for next research
                    window.lastMeaningfulStatusMessage = '';
                    
                    // Update navigation state
                    updateNavigationBasedOnResearchStatus();
                    
                    // Navigate to results page with a slight delay to ensure all updates are processed
                    setTimeout(() => {
                        // Load the research results
                        loadResearch(completedResearchId);
                    }, 800);
                } else {
                    // Error sound and notification
                    playNotificationSound('error');
                    
                    // Use the updateTerminationUIState function for consistency
                    updateTerminationUIState('suspended', data.error || `Research was ${data.status}`);
                    
                    // Reset lastMeaningfulStatusMessage for next research
                    window.lastMeaningfulStatusMessage = '';
                    
                    // Reset current research ID
                    currentResearchId = null;
                    window.currentResearchId = null;
                    
                    // Update navigation - important for correctly showing/hiding various elements
                    // based on the current research state
                    updateNavigationBasedOnResearchStatus();
                }
                
                // Refresh the history list to show the completed research
                if (document.getElementById('history').classList.contains('active')) {
                    loadResearchHistory();
                }
            }
        }
    };
    
    // Check for active research on page load
    async function checkActiveResearch() {
        try {
            const response = await fetch(getApiUrl('/api/history'));
            const history = await response.json();
            
            // Find in-progress research
            const activeResearch = history.find(item => item.status === 'in_progress');
            
            if (activeResearch) {
                // Verify the research is truly active by checking its details
                try {
                    const detailsResponse = await fetch(getApiUrl(`/api/research/${activeResearch.id}`));
                    const details = await detailsResponse.json();
                    
                    // If status is not in_progress in the details, it's stale
                    if (details.status !== 'in_progress') {
                        console.log(`Research ${activeResearch.id} is stale (status: ${details.status}), ignoring`);
                        return;
                    }
                    
                    // Check when the research was started - if it's been more than 1 hour, it might be stale
                    if (details.created_at) {
                        const startTime = new Date(details.created_at);
                        const currentTime = new Date();
                        const hoursSinceStart = (currentTime - startTime) / (1000 * 60 * 60);
                        
                        if (hoursSinceStart > 1) {
                            console.log(`Research ${activeResearch.id} has been running for ${hoursSinceStart.toFixed(2)} hours, which is unusually long. Checking for activity...`);
                            
                            // Check if there has been log activity in the last 10 minutes
                            let recentActivity = false;
                            if (details.log && Array.isArray(details.log) && details.log.length > 0) {
                                const lastLogTime = new Date(details.log[details.log.length - 1].time);
                                const minutesSinceLastLog = (currentTime - lastLogTime) / (1000 * 60);
                                
                                if (minutesSinceLastLog < 10) {
                                    recentActivity = true;
                                } else {
                                    console.log(`No recent activity for ${minutesSinceLastLog.toFixed(2)} minutes, treating as stale`);
                                    return;
                                }
                            }
                        }
                    }
                    
                    // If we get here, the research seems to be genuinely active
                    isResearchInProgress = true;
                    currentResearchId = activeResearch.id;
                    window.currentResearchId = currentResearchId;
                    
                    // Check if we're on the new research page and redirect to progress
                    const currentPage = document.querySelector('.page.active');
                    
                    if (currentPage && currentPage.id === 'new-research') {
                        // Navigate to progress page
                        switchPage('research-progress');
                        
                        // Connect to socket for this research
                        window.connectToResearchSocket(currentResearchId);
                        
                        // Start polling for updates
                        pollResearchStatus(currentResearchId);
                    }
                } catch (detailsError) {
                    console.error('Error checking research details:', detailsError);
                }
            }
        } catch (error) {
            console.error('Error checking for active research:', error);
        }
    }
    
    // Add unload event listener
    window.addEventListener('beforeunload', function() {
        window.disconnectSocket();
    });
    
    // Function to start research
    async function startResearch(query, mode) {
        // First validate that we have a query
        if (!query || query.trim() === '') {
            alert('Please enter a query');
            return;
        }
        
        try {
            // Update button state
            const startBtn = document.getElementById('start-research-btn');
            if (startBtn) {
                startBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Starting...';
                startBtn.disabled = true;
            }
            
            // Clear any previous research
            resetResearchState();
            
            // Set favicon to loading
            setFavicon('loading');
            
            // Get the current query element
            const currentQueryEl = document.getElementById('current-query');
            if (currentQueryEl) {
                currentQueryEl.textContent = query;
            }
            
            // Create payload
            const payload = {
                query: query,
                mode: mode || 'quick'
            };
            
            // Call the API
            const response = await fetch(getApiUrl('/api/start_research'), {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify(payload)
            });
            
            // Parse the response
            const result = await response.json();
            
            if (result.status === 'success') {
                // Update the current research ID
                currentResearchId = result.research_id;
                window.currentResearchId = result.research_id;
                
                console.log(`Started research with ID: ${currentResearchId}`);
                
                // Mark as in progress
                isResearchInProgress = true;
                
                // Hide the try again button if visible
                const tryAgainBtn = document.getElementById('try-again-btn');
                if (tryAgainBtn) {
                    tryAgainBtn.style.display = 'none';
                }
                
                // Reset progress UI
                updateProgressUI(0, 'in_progress', `Researching: ${query}`);

                // Store query in case we need to display it again
                window.currentResearchQuery = query;

                // Update navigation
                updateNavigationBasedOnResearchStatus();
                
                // Navigate to the progress page
                switchPage('research-progress');
                
                // Connect to the socket for this research
                window.connectToResearchSocket(currentResearchId);
                
                // Start polling for status
                pollResearchStatus(currentResearchId);
            } else {
                // Handle error
                const errorMessage = result.message || 'Failed to start research';
                console.error('Research start error:', errorMessage);
                
                // Add error to log
                addConsoleLog(`Error: ${errorMessage}`, 'error');
                
                alert(errorMessage);
                
                // Reset the favicon
                setFavicon('default');
                
                // Reset button state
                if (startBtn) {
                    startBtn.innerHTML = '<i class="fas fa-rocket"></i> Start Research';
                    startBtn.disabled = false;
                }
            }
        } catch (error) {
            console.error('Error starting research:', error);
            
            // Add error to log
            addConsoleLog(`Error: ${error.message}`, 'error');
            
            // Reset the favicon
            setFavicon('default');
            
            // Reset button state
            const startBtn = document.getElementById('start-research-btn');
            if (startBtn) {
                startBtn.innerHTML = '<i class="fas fa-rocket"></i> Start Research';
                startBtn.disabled = false;
            }
            
            alert('An error occurred while starting the research. Please try again.');
        }
    }
    
    // Function to clear any existing polling interval
    function clearPollingInterval() {
        if (pollingInterval) {
            console.log('Clearing existing polling interval');
            clearInterval(pollingInterval);
            pollingInterval = null;
        }
    }
    
    // Update the polling function to prevent "Processing research..." from overwriting actual status messages
    function pollResearchStatus(researchId) {
        if (!researchId) {
            console.error('No research ID provided for polling');
            return;
        }
        
        // Reset message deduplication when starting a new poll
        window.processedMessages = window.processedMessages || new Set();
        
        // Don't set "Loading research..." here, as we'll set the actual query from the response
        // Only set loading if currentQuery is empty
        const currentQueryEl = document.getElementById('current-query');
        if (currentQueryEl && (!currentQueryEl.textContent || currentQueryEl.textContent === 'Loading research...')) {
            currentQueryEl.textContent = window.currentResearchQuery || 'Loading research...';
        }
        
        console.log(`Starting polling for research ${researchId}`);
        
        // Store the last real message to avoid overwriting with generic messages
        window.lastMeaningfulStatusMessage = window.lastMeaningfulStatusMessage || '';
        
        // Ensure we have a socket connection
        if (typeof window.connectToResearchSocket === 'function') {
            window.connectToResearchSocket(researchId);
        }
        
        // Set polling interval for updates
        if (pollingInterval) {
            clearInterval(pollingInterval);
        }
        
        // Make an immediate request
        checkResearchStatus(researchId);
        
        // Then set up polling
        pollingInterval = setInterval(() => {
            checkResearchStatus(researchId);
        }, 2000); // Poll every 2 seconds
        
        // Function to check research status
        function checkResearchStatus(researchId) {
            fetch(getApiUrl(`/api/research/${researchId}/details`))
            .then(response => response.json())
            .then(data => {
                // Update the current query with the actual query from the research
                const currentQueryEl = document.getElementById('current-query');
                if (currentQueryEl && data.query) {
                    currentQueryEl.textContent = data.query;
                    // Store the query in case we need it later
                    window.currentResearchQuery = data.query;
                }
                
                // Process status update
                if (data && data.status !== 'error') {
                    // Update UI with progress
                    const progress = data.progress || 0;
                    const status = data.status || 'in_progress';
                    
                    // Get most recent message
                    let message = '';
                    let foundNewMessage = false;
                    let latestMetadata = null;
                    
                    if (data.log && data.log.length > 0) {
                        // Get the latest unique log entry
                        for (let i = data.log.length - 1; i >= 0; i--) {
                            const latestLog = data.log[i];
                            const messageId = latestLog.message + (latestLog.time || '');
                            
                            if (!window.processedMessages.has(messageId)) {
                                window.processedMessages.add(messageId);
                                message = latestLog.message || '';
                                latestMetadata = latestLog.metadata || null;
                                
                                // Only update the lastMeaningfulStatusMessage if we have a real message
                                if (message && message !== 'Processing research...') {
                                    window.lastMeaningfulStatusMessage = message;
                                    foundNewMessage = true;
                                }
                                
                                // Add to console logs
                                if (message) {
                                    let logType = 'info';
                                    if (isMilestoneLog(message, latestLog.metadata)) {
                                        logType = 'milestone';
                                    } else if (latestLog.type === 'error' || (latestLog.metadata && latestLog.metadata.phase === 'error')) {
                                        logType = 'error';
                                    } else if (latestLog.type) {
                                        logType = latestLog.type; // Use the type from the database if available
                                    }
                                    addConsoleLog(message, logType, latestMetadata);
                                }
                                
                                break; // Only process one message per poll
                            }
                        }
                    }
                    
                    // Use a meaningful message if available; otherwise, keep the last good one
                    const displayMessage = foundNewMessage ? message :
                                          (window.lastMeaningfulStatusMessage || 'Processing research...');
                    
                    // Update progress UI
                    updateProgressUI(progress, status, displayMessage);
                    
                    // Update the UI based on research status
                    if (status === 'completed' || status === 'failed' || status === 'suspended') {
                        // Clear polling interval
                        if (pollingInterval) {
                            console.log('Clearing polling interval due to status change');
                            clearInterval(pollingInterval);
                            pollingInterval = null;
                        }
                        
                        // Handle completion or failure
                        if (status === 'completed') {
                            addConsoleLog('Research completed successfully', 'milestone');
                            playNotificationSound('success');
                            
                            // Store the completed research ID for navigation
                            const completedResearchId = researchId;
                            
                            // Reset current research ID
                            currentResearchId = null;
                            window.currentResearchId = null;
                            
                            // Update navigation state
                            isResearchInProgress = false;
                            updateNavigationBasedOnResearchStatus();
                            
                            // Reset lastMeaningfulStatusMessage for next research
                            window.lastMeaningfulStatusMessage = '';
                            
                            // Navigate to results page with a slight delay to ensure all updates are processed
                            setTimeout(() => {
                                // Load the research results
                                loadResearch(completedResearchId);
                            }, 800);
                        } else {
                            addConsoleLog(`Research ${status}`, 'error');
                            playNotificationSound('error');
                            
                            // Show error message and Try Again button
                            const errorMessage = document.getElementById('error-message');
                            const tryAgainBtn = document.getElementById('try-again-btn');
                            
                            if (errorMessage) {
                                errorMessage.textContent = data.error || `Research was ${status}`;
                                errorMessage.style.display = 'block';
                            }
                            
                            if (tryAgainBtn) {
                                tryAgainBtn.style.display = 'block';
                            }
                            
                            // Reset lastMeaningfulStatusMessage for next research
                            window.lastMeaningfulStatusMessage = '';
                            
                            // Update navigation
                            isResearchInProgress = false;
                            currentResearchId = null;
                            window.currentResearchId = null;
                            updateNavigationBasedOnResearchStatus();
                        }
                    } else {
                        // Research is still in progress
                        isResearchInProgress = true;
                        currentResearchId = researchId;
                        window.currentResearchId = researchId;
                    }
                }
            })
            .catch(error => {
                console.error('Error polling research status:', error);
                // Don't clear the interval on error - just keep trying
            });
        }
    }
    
    // Function to reset the start research button to its default state
    function resetStartResearchButton() {
        const startBtn = document.getElementById('start-research-btn');
        if (startBtn) {
            startBtn.innerHTML = '<i class="fas fa-rocket"></i> Start Research';
            startBtn.disabled = false;
        }
    }

    // Main initialization function
    function initializeApp() {
        console.log('Initializing application...');
        
        // Initialize the sounds
        initializeSounds();
        
        // Initialize socket connection
        initializeSocket();
        
        // Create a dynamic favicon with the lightning emoji by default
        createDynamicFavicon('⚡');
        
        // Add try again button handler
        const tryAgainBtn = document.getElementById('try-again-btn');
        if (tryAgainBtn) {
            tryAgainBtn.addEventListener('click', function() {
                // Switch back to the new research page
                switchPage('new-research');
                
                // Reset the research state
                resetResearchState();
                
                // Reset the Start Research button
                resetStartResearchButton();
            });
        }
        
        // Get navigation elements
        const navItems = document.querySelectorAll('.sidebar-nav li');
        const mobileNavItems = document.querySelectorAll('.mobile-tab-bar li');
        const pages = document.querySelectorAll('.page');
        const mobileTabBar = document.querySelector('.mobile-tab-bar');
        const logo = document.getElementById('logo-link');
        
        // Handle responsive navigation based on screen size
        function handleResponsiveNavigation() {
            // Mobile tab bar should only be visible on small screens
            if (window.innerWidth <= 767) {
                if (mobileTabBar) {
                    mobileTabBar.style.display = 'flex';
                }
            } else {
                if (mobileTabBar) {
                    mobileTabBar.style.display = 'none';
                }
            }
        }
        
        // Call on initial load
        handleResponsiveNavigation();
        
        // Add resize listener for responsive design
        window.addEventListener('resize', handleResponsiveNavigation);
        
        // Handle logo click
        if (logo) {
            logo.addEventListener('click', () => {
                switchPage('new-research');
                resetStartResearchButton();
            });
        }
        
        // Setup navigation click handlers
        navItems.forEach(item => {
            if (!item.classList.contains('external-link')) {
                item.addEventListener('click', function() {
                    const pageId = this.dataset.page;
                    if (pageId) {
                        switchPage(pageId);
                        // Reset Start Research button when returning to the form
                        if (pageId === 'new-research') {
                            resetStartResearchButton();
                        }
                    }
                });
            }
        });
        
        mobileNavItems.forEach(item => {
            if (!item.classList.contains('external-link')) {
                item.addEventListener('click', function() {
                    const pageId = this.dataset.page;
                    if (pageId) {
                        switchPage(pageId);
                        // Reset Start Research button when returning to the form
                        if (pageId === 'new-research') {
                            resetStartResearchButton();
                        }
                    }
                });
            }
        });
        
        // Setup form submission
        const researchForm = document.getElementById('research-form');
        if (researchForm) {
            researchForm.addEventListener('submit', function(e) {
                e.preventDefault();
                const query = document.getElementById('query').value.trim();
                if (!query) {
                    alert('Please enter a research query');
                    return;
                }
                
                const mode = document.querySelector('.mode-option.active')?.dataset.mode || 'quick';
                startResearch(query, mode);
            });
        }
        
        // Initialize research mode selection
        const modeOptions = document.querySelectorAll('.mode-option');
        modeOptions.forEach(option => {
            option.addEventListener('click', function() {
                modeOptions.forEach(opt => opt.classList.remove('active'));
                this.classList.add('active');
                
                // Update favicon based on selected mode
                const mode = this.dataset.mode;
                setFavicon(mode);
            });
        });
        
        // Load research history initially
        if (document.getElementById('history-list')) {
            loadResearchHistory();
        }
        
        // Check for active research
        checkActiveResearch();
        
        // Setup notification toggle and other form elements
        setupResearchForm();
        
        console.log('Application initialized');
    }
    
    // Initialize the app
    initializeApp();
    
    // Function to switch between pages
    function switchPage(pageId) {
        // First hide all pages
        const pages = document.querySelectorAll('.page');
        pages.forEach(page => page.classList.remove('active'));
        
        // Then activate the selected page
        const selectedPage = document.getElementById(pageId);
        if (selectedPage) {
            selectedPage.classList.add('active');
        }
        
        // Update the URL hash
        window.location.hash = '#' + pageId;
        
        // Update the navigation UI to highlight the active page
        updateNavigationUI(pageId);
        
        // Clear console logs when switching to pages that don't show research details
        if (pageId === 'new-research' || pageId === 'history') {
            clearConsoleLogs();
            // Reset the viewing research ID when navigating to non-research pages
            viewingResearchId = null;
        }
        
        // Special handling for history page
        if (pageId === 'history') {
            loadResearchHistory();
        }
        
        // Reset scroll position for the newly activated page
        window.scrollTo(0, 0);
        
        console.log(`Switched to page: ${pageId}`);
        
        // Update the log panel visibility
        updateLogPanelVisibility(pageId);
    }
    
    // Track termination status
    let isTerminating = false;
    
    // Check if we're on the history page and load history if needed
    const historyPage = document.getElementById('history');
    if (historyPage && historyPage.classList.contains('active')) {
        // Use setTimeout to ensure the DOM is fully loaded
        setTimeout(() => loadResearchHistory(), 100);
    }
    
    // Add a prefix helper function at the top of the file
    function getApiUrl(path) {
        // This function adds the /research prefix to all API URLs
        return `/research${path}`;
    }
    
    // Function to properly disconnect all socket connections 
    function disconnectAllSockets() {
        if (socket) {
            try {
                console.log('Disconnecting all socket connections');
                
                // Get the active research ID
                const researchId = getActiveResearchId();
                
                // If there's an active research, unsubscribe first
                if (researchId) {
                    console.log(`Unsubscribing from research ${researchId}`);
                    socket.emit('unsubscribe_from_research', { research_id: researchId });
                }
                
                // Also attempt to disconnect the socket
                socket.disconnect();
                socket = null;
                
                console.log('Socket disconnected successfully');
            } catch (error) {
                console.error('Error disconnecting socket:', error);
            }
        }
    }
    
    // Update the terminateResearch function to handle termination more gracefully
    async function terminateResearch(researchId) {
        if (!researchId) {
            console.error('No research ID provided for termination');
            return;
        }
        
        // Prevent multiple termination requests
        if (document.getElementById('terminate-research-btn')?.disabled) {
            console.log('Termination already in progress');
            return;
        }
        
        // Confirm with the user
        if (!confirm('Are you sure you want to terminate this research? This action cannot be undone.')) {
            return;
        }
        
        console.log(`Attempting to terminate research: ${researchId}`);
        
        try {
            // Get the terminate button
            const terminateBtn = document.getElementById('terminate-research-btn');
            if (terminateBtn) {
                // Disable the button to prevent multiple clicks
                terminateBtn.disabled = true;
                terminateBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Terminating...';
            }
            
            // Update UI to show terminating state immediately
            updateTerminationUIState('suspending', 'Terminating research...');
            
            // Add a log entry
            addConsoleLog('Terminating research...', 'error');
            
            // Immediately mark the research as terminated in our app state 
            // so we don't reconnect to it
            isResearchInProgress = false;
            
            // Disconnect all sockets to ensure we stop receiving updates
            disconnectAllSockets();
            
            // Clear the polling interval immediately
            if (pollingInterval) {
                clearInterval(pollingInterval);
                pollingInterval = null;
                console.log('Cleared polling interval during termination');
            }
            
            // Call the API to terminate
            const response = await fetch(getApiUrl(`/api/research/${researchId}/terminate`), {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            
            const data = await response.json();
            
            if (data.status === 'success') {
                console.log(`Research ${researchId} termination requested successfully`);
                
                // Add termination log
                addConsoleLog('Research termination requested. Please wait...', 'error');
                
                // Immediately update UI for better responsiveness
                updateTerminationUIState('suspended', 'Research was terminated');
                
                // Start polling for the suspended status with a more reliable approach
                let checkAttempts = 0;
                const maxAttempts = 3; // Reduced from 5
                const checkInterval = setInterval(async () => {
                    checkAttempts++;
                    console.log(`Checking termination status (attempt ${checkAttempts}/${maxAttempts})...`);
                    
                    try {
                        const statusResponse = await fetch(getApiUrl(`/api/research/${researchId}`));
                        const statusData = await statusResponse.json();
                        
                        // Check for actual termination status in the response
                        if (statusData.status === 'suspended' || statusData.status === 'failed') {
                            console.log(`Research is now ${statusData.status}, updating UI`);
                            clearInterval(checkInterval);
                            
                            // Reset research state
                            currentResearchId = null;
                            window.currentResearchId = null;
                            
                            // Disconnect any remaining sockets again, just to be sure
                            disconnectAllSockets();
                            
                            // Update navigation
                            updateNavigationBasedOnResearchStatus();
                            
                            return;
                        }
                        
                        // If we reach the maximum attempts but status isn't updated yet
                        if (checkAttempts >= maxAttempts) {
                            console.log('Max termination check attempts reached, forcing UI update');
                            clearInterval(checkInterval);
                            
                            // Force update to suspended state even if backend hasn't caught up yet
                            currentResearchId = null;
                            window.currentResearchId = null;
                            
                            // Disconnect any remaining sockets
                            disconnectAllSockets();
                            
                            // Update database status directly with a second termination request
                            try {
                                console.log('Sending second termination request to ensure completion');
                                await fetch(getApiUrl(`/api/research/${researchId}/terminate`), {
                                    method: 'POST',
                                    headers: { 'Content-Type': 'application/json' }
                                });
                            } catch (secondError) {
                                console.error('Error sending second termination request:', secondError);
                            }
                            
                            updateNavigationBasedOnResearchStatus();
                        }
                    } catch (checkError) {
                        console.error(`Error checking termination status: ${checkError}`);
                        if (checkAttempts >= maxAttempts) {
                            clearInterval(checkInterval);
                            updateTerminationUIState('error', 'Error checking termination status');
                        }
                    }
                }, 300); // Check faster for more responsive feedback
                
            } else {
                console.error(`Error terminating research: ${data.message}`);
                addConsoleLog(`Error terminating research: ${data.message}`, 'error');
                
                // Re-enable the button
                if (terminateBtn) {
                    terminateBtn.disabled = false;
                    terminateBtn.innerHTML = '<i class="fas fa-stop-circle"></i> Terminate Research';
                }
            }
        } catch (error) {
            console.error(`Error in terminate request: ${error}`);
            addConsoleLog(`Error in terminate request: ${error}`, 'error');
            
            // Re-enable the button
            const terminateBtn = document.getElementById('terminate-research-btn');
            if (terminateBtn) {
                terminateBtn.disabled = false;
                terminateBtn.innerHTML = '<i class="fas fa-stop-circle"></i> Terminate Research';
            }
        }
    }

    // Helper function to update UI elements during termination
    function updateTerminationUIState(state, message) {
        const terminateBtn = document.getElementById('terminate-research-btn');
        const errorMessage = document.getElementById('error-message');
        const tryAgainBtn = document.getElementById('try-again-btn');
        const progressStatus = document.getElementById('progress-status');
        const progressBar = document.getElementById('progress-bar');
        
        switch (state) {
            case 'suspending':
                if (progressStatus) {
                    progressStatus.textContent = 'Terminating research...';
                    progressStatus.className = 'progress-status status-terminating fade-in';
                }
                if (progressBar) {
                    progressBar.classList.remove('suspended-status');
                }
                if (terminateBtn) {
                    terminateBtn.disabled = true;
                    terminateBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Terminating...';
                }
                if (errorMessage) {
                    errorMessage.style.display = 'none';
                }
                if (tryAgainBtn) {
                    tryAgainBtn.style.display = 'none';
                }
                break;
                
            case 'suspended':
                if (progressStatus) {
                    progressStatus.innerHTML = '<i class="fas fa-exclamation-triangle termination-icon"></i> ' + (message || 'Research was suspended');
                    progressStatus.className = 'progress-status status-failed fade-in';
                }
                if (progressBar) {
                    progressBar.classList.add('suspended-status');
                }
                if (terminateBtn) {
                    terminateBtn.style.display = 'none';
                }
                if (errorMessage) {
                    // Hide the error message box completely
                    errorMessage.style.display = 'none';
                }
                if (tryAgainBtn) {
                    tryAgainBtn.style.display = 'block';
                    // Update try again button to be more attractive
                    tryAgainBtn.innerHTML = '<i class="fas fa-sync-alt"></i> Try Again';
                    tryAgainBtn.className = 'btn btn-primary fade-in';
                }
                
                // Update page title to show suspension
                document.title = '⚠️ Research Suspended - Local Deep Research';
                
                break;
                
            case 'error':
                if (progressStatus) {
                    progressStatus.innerHTML = '<i class="fas fa-exclamation-circle termination-icon"></i>' + (message || 'Error terminating research');
                    progressStatus.className = 'progress-status status-failed fade-in';
                }
                if (progressBar) {
                    progressBar.classList.remove('suspended-status');
                }
                if (terminateBtn) {
                    terminateBtn.disabled = false;
                    terminateBtn.innerHTML = '<i class="fas fa-stop-circle"></i> Terminate Research';
                }
                if (errorMessage) {
                    errorMessage.innerHTML = '<i class="fas fa-exclamation-circle termination-icon"></i>' + (message || 'Error terminating research');
                    errorMessage.style.display = 'block';
                    errorMessage.className = 'error-message fade-in';
                }
                if (tryAgainBtn) {
                    tryAgainBtn.style.display = 'none';
                }
                break;
        }
    }
    
    // Expose the terminate function to the window object
    window.terminateResearch = terminateResearch;
    
    // Function to update the progress UI
    function updateProgressUI(progress, status, message) {
        const progressFill = document.getElementById('progress-fill');
        const progressPercentage = document.getElementById('progress-percentage');
        const progressStatus = document.getElementById('progress-status');
        const errorMessage = document.getElementById('error-message');
        const tryAgainBtn = document.getElementById('try-again-btn');
        
        if (progressFill && progressPercentage) {
            progressFill.style.width = `${progress}%`;
            progressPercentage.textContent = `${progress}%`;
        }
        
        if (progressStatus && message) {
            progressStatus.textContent = message;
            
            // Update status class
            progressStatus.className = 'progress-status';
            if (status) {
                progressStatus.classList.add(`status-${status}`);
            }
        }
        
        // Show/hide terminate button based on status
        const terminateBtn = document.getElementById('terminate-research-btn');
        if (terminateBtn) {
            if (status === 'in_progress') {
                terminateBtn.style.display = 'inline-flex';
                terminateBtn.disabled = false;
                terminateBtn.innerHTML = '<i class="fas fa-stop-circle"></i> Terminate Research';
                
                // Hide try again button when in progress
                if (tryAgainBtn) {
                    tryAgainBtn.style.display = 'none';
                }
            } else if (status === 'terminating') {
                terminateBtn.style.display = 'inline-flex';
                terminateBtn.disabled = true;
                terminateBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> Terminating...';
            } else {
                terminateBtn.style.display = 'none';
                
                // Show try again button for failed or suspended research
                if (tryAgainBtn && (status === 'failed' || status === 'suspended')) {
                    tryAgainBtn.style.display = 'inline-flex';
                    
                    // Get the current query for retry
                    const currentQuery = document.getElementById('current-query');
                    const queryText = currentQuery ? currentQuery.textContent : '';
                    
                    // Add click event to try again button to go back to research form with the query preserved
                    tryAgainBtn.onclick = function() {
                        // Switch to the research form
                        switchPage('new-research');
                        
                        // Set the query text in the form
                        const queryTextarea = document.getElementById('query');
                        if (queryTextarea && queryText) {
                            queryTextarea.value = queryText;
                        }
                        
                        // Clean up any remaining research state
                        window.cleanupResearchResources();
                    };
                }
            }
        }
        
        // Show error message when there's an error
        if (errorMessage) {
            if (status === 'failed' || status === 'suspended') {
                errorMessage.style.display = 'block';
                errorMessage.textContent = message || (status === 'failed' ? 'Research failed' : 'Research was suspended');
            } else {
                errorMessage.style.display = 'none';
            }
        }
    }
    
    // Completely rewritten function to ensure reliable history loading
    async function loadResearchHistory() {
        const historyList = document.getElementById('history-list');
        
        // Make sure we have the history list element
        if (!historyList) {
            console.error('History list element not found');
            return;
        }
        
        historyList.innerHTML = '<div class="loading-spinner centered"><div class="spinner"></div></div>';
        
        try {
            const response = await fetch(getApiUrl('/api/history'));
            
            if (!response.ok) {
                throw new Error(`Server returned ${response.status}`);
            }
            
            const data = await response.json();
            
            // Clear the loading spinner
            historyList.innerHTML = '';
            
            // Handle empty data
            if (!data || !Array.isArray(data) || data.length === 0) {
                historyList.innerHTML = '<div class="empty-state">No research history found. Start a new research project!</div>';
                return;
            }
            
            // Check if any research is in progress
            const inProgressResearch = data.find(item => item.status === 'in_progress');
            
            // Get the start research button
            const startResearchBtn = document.getElementById('start-research-btn');
            
            if (inProgressResearch) {
                isResearchInProgress = true;
                currentResearchId = inProgressResearch.id;
                if (startResearchBtn) {
                    startResearchBtn.disabled = true;
                }
            } else {
                isResearchInProgress = false;
                if (startResearchBtn) {
                    startResearchBtn.disabled = false;
                }
            }
            
            // Display each history item
            data.forEach(item => {
                try {
                    // Skip if item is invalid
                    if (!item || !item.id) {
                        return;
                    }
                    
                    // Create container
                    const historyItem = document.createElement('div');
                    historyItem.className = 'history-item';
                    historyItem.dataset.researchId = item.id;
                    
                    // Create header with title and status
                    const header = document.createElement('div');
                    header.className = 'history-item-header';
                    
                    const title = document.createElement('div');
                    title.className = 'history-item-title';
                    title.textContent = item.query || 'Untitled Research';
                    
                    const status = document.createElement('div');
                    status.className = `history-item-status status-${item.status ? item.status.replace('_', '-') : 'unknown'}`;
                    status.textContent = item.status ? 
                        (item.status === 'in_progress' ? 'In Progress' : 
                         item.status.charAt(0).toUpperCase() + item.status.slice(1)) : 
                        'Unknown';
                    
                    header.appendChild(title);
                    header.appendChild(status);
                    historyItem.appendChild(header);
                    
                    // Create meta section
                    const meta = document.createElement('div');
                    meta.className = 'history-item-meta';
                    
                    const date = document.createElement('div');
                    date.className = 'history-item-date';
                    try {
                        // Use completed_at if available, fall back to created_at if not
                        const dateToUse = item.completed_at || item.created_at;
                        date.textContent = dateToUse ? formatDate(new Date(dateToUse)) : 'Unknown date';
                    } catch (e) {
                        date.textContent = item.completed_at || item.created_at || 'Unknown date';
                    }
                    
                    const mode = document.createElement('div');
                    mode.className = 'history-item-mode';
                    const modeIcon = item.mode === 'quick' ? 'bolt' : 'microscope';
                    const modeText = item.mode === 'quick' ? 'Quick Summary' : 'Detailed Report';
                    mode.innerHTML = `<i class="fas fa-${modeIcon}"></i> ${modeText}`;
                    
                    meta.appendChild(date);
                    meta.appendChild(mode);
                    historyItem.appendChild(meta);
                    
                    // Create actions section
                    const actions = document.createElement('div');
                    actions.className = 'history-item-actions';
                    
                    // View button
                    const viewBtn = document.createElement('button');
                    viewBtn.className = 'btn btn-sm btn-outline view-btn';
                    
                    if (item.status === 'completed') {
                        viewBtn.innerHTML = '<i class="fas fa-eye"></i> View';
                        viewBtn.addEventListener('click', (e) => {
                            e.stopPropagation();
                            loadResearch(item.id);
                        });
                        
                        // PDF button for completed research
                        const pdfBtn = document.createElement('button');
                        pdfBtn.className = 'btn btn-sm btn-outline pdf-btn';
                        pdfBtn.innerHTML = '<i class="fas fa-file-pdf"></i> PDF';
                        pdfBtn.addEventListener('click', (e) => {
                            e.stopPropagation();
                            generatePdfFromResearch(item.id);
                        });
                        actions.appendChild(pdfBtn);
                    } else if (item.status === 'in_progress') {
                        viewBtn.innerHTML = '<i class="fas fa-spinner fa-spin"></i> In Progress';
                        viewBtn.addEventListener('click', (e) => {
                            e.stopPropagation();
                            navigateToResearchProgress({id: item.id, query: item.query, progress: 0});
                        });
                    } else {
                        viewBtn.innerHTML = '<i class="fas fa-eye"></i> View';
                        viewBtn.disabled = true;
                    }
                    
                    actions.appendChild(viewBtn);
                    
                    // Delete button
                    const deleteBtn = document.createElement('button');
                    deleteBtn.className = 'btn btn-sm btn-outline delete-btn';
                    deleteBtn.innerHTML = '<i class="fas fa-trash"></i> Delete';
                    deleteBtn.addEventListener('click', (e) => {
                        e.stopPropagation();
                        if (confirm(`Are you sure you want to delete this research: "${item.query}"?`)) {
                            deleteResearch(item.id);
                        }
                    });
                    actions.appendChild(deleteBtn);
                    
                    historyItem.appendChild(actions);
                    
                    // Add click handler for the entire item
                    historyItem.addEventListener('click', (e) => {
                        // Skip if clicking on a button
                        if (e.target.closest('button')) {
                            return;
                        }
                        
                        if (item.status === 'completed') {
                            loadResearch(item.id);
                        } else if (item.status === 'in_progress') {
                            navigateToResearchProgress({id: item.id, query: item.query, progress: 0});
                        }
                    });
                    
                    // Add to the history list
                    historyList.appendChild(historyItem);
                } catch (itemError) {
                    console.error('Error processing history item:', itemError, item);
                }
            });
            
        } catch (error) {
            console.error('Error loading history:', error);
            historyList.innerHTML = `
                <div class="error-message">
                    Error loading history: ${error.message}
                </div>
                <div style="text-align: center; margin-top: 1rem;">
                    <button id="retry-history-btn" class="btn btn-primary">
                        <i class="fas fa-sync"></i> Retry
                    </button>
                </div>`;
                
            const retryBtn = document.getElementById('retry-history-btn');
            if (retryBtn) {
                retryBtn.addEventListener('click', () => {
                    loadResearchHistory();
                });
            }
        }
        
        // Add a fallback in case something goes wrong and the history list is still empty
        setTimeout(() => {
            if (historyList.innerHTML === '' || historyList.innerHTML.includes('loading-spinner')) {
                console.warn('History list is still empty or showing spinner after load attempt - applying fallback');
                historyList.innerHTML = `
                    <div class="error-message">
                        Something went wrong while loading the history. 
                    </div>
                    <div style="text-align: center; margin-top: 1rem;">
                        <button id="fallback-retry-btn" class="btn btn-primary">
                            <i class="fas fa-sync"></i> Retry
                        </button>
                    </div>`;
                    
                const fallbackRetryBtn = document.getElementById('fallback-retry-btn');
                if (fallbackRetryBtn) {
                    fallbackRetryBtn.addEventListener('click', () => {
                        loadResearchHistory();
                    });
                }
            }
        }, 5000); // Check after 5 seconds
    }
    
    // Function to navigate to research progress
    function navigateToResearchProgress(research) {
        // Set the current viewing research ID
        viewingResearchId = research.id;
        
        // First check if the research is already terminated/suspended
        if (research.status === 'suspended' || research.status === 'failed') {
            // Switch to the progress page with terminated state
            switchPage('research-progress');
            
            // Show the query
            document.getElementById('current-query').textContent = research.query || '';
            
            // Update UI for terminated state
            updateTerminationUIState('suspended', `Research was ${research.status}`);
            
            // Update progress percentage
            const progress = research.progress || 0;
            document.getElementById('progress-fill').style.width = `${progress}%`;
            document.getElementById('progress-percentage').textContent = `${progress}%`;
            
            // Load logs for this research
            loadLogsForResearch(research.id);
            
            // Don't connect to socket or start polling for terminated research
            return;
        }
        
        document.getElementById('current-query').textContent = research.query;
        document.getElementById('progress-fill').style.width = `${research.progress || 0}%`;
        document.getElementById('progress-percentage').textContent = `${research.progress || 0}%`;
        
        // Navigate to progress page
        switchPage('research-progress');
        
        // Load logs for this research
        loadLogsForResearch(research.id);
        
        // Connect to socket for this research
        window.connectToResearchSocket(research.id);
        
        // Start polling for status
        pollResearchStatus(research.id);
    }
    
    // Function to delete a research record
    async function deleteResearch(researchId) {
        try {
            const response = await fetch(getApiUrl(`/api/research/${researchId}/delete`), {
                method: 'DELETE'
            });
            
            if (response.ok) {
                // Reload the history
                loadResearchHistory();
            } else {
                alert('Failed to delete research. Please try again.');
            }
        } catch (error) {
            console.error('Error deleting research:', error);
            alert('An error occurred while deleting the research.');
        }
    }
    
    // Update the loadResearch function to handle terminated/suspended research better
    async function loadResearch(researchId) {
        try {
            console.log(`Loading research results for research ID: ${researchId}`);
            
            // Set the current viewing research ID
            viewingResearchId = researchId;
            
            // Get research data first to check status
            fetch(getApiUrl(`/api/research/${researchId}`))
                .then(response => response.json())
                .then(researchData => {
                    // Check if research was terminated or failed
                    if (researchData.status === 'suspended' || researchData.status === 'failed') {
                        console.log(`Research ${researchId} was ${researchData.status}, not loading results`);
                        
                        // Switch to research progress page if not already there
                        const progressPage = document.getElementById('research-progress');
                        if (!progressPage.classList.contains('active')) {
                            switchPage('research-progress');
                        }
                        
                        // Show error message and Try Again button
                        const errorMessage = document.getElementById('error-message');
                        const tryAgainBtn = document.getElementById('try-again-btn');
                        
                        if (errorMessage) {
                            errorMessage.textContent = researchData.error || `Research was ${researchData.status}`;
                            errorMessage.style.display = 'block';
                        }
                        
                        if (tryAgainBtn) {
                            tryAgainBtn.style.display = 'block';
                        }
                        
                        // Update UI elements for this research
                        document.getElementById('current-query').textContent = researchData.query || 'Unknown query';
                        
                        // Update progress bar
                        const progressFill = document.getElementById('progress-fill');
                        const progressPercentage = document.getElementById('progress-percentage');
                        if (progressFill) progressFill.style.width = '0%';
                        if (progressPercentage) progressPercentage.textContent = '0%';
                        
                        // Load logs for this research
                        loadLogsForResearch(researchId);
                        
                        return; // Exit early, no need to load report for terminated research
                    }
                    
                    // Normal flow for completed research
                    fetch(getApiUrl(`/api/report/${researchId}`))
                        .then(response => response.json())
                        .then(data => {
                            if (data.status === 'error') {
                                throw new Error('Research report not found');
                            }
                            
                            if (!data.content) {
                                console.error('No report content found in research data');
                                throw new Error('Report content is empty');
                            }
                            
                            // Set the report content and metadata
                            document.getElementById('result-query').textContent = researchData.query || 'Unknown Query';
                            document.getElementById('result-date').textContent = formatDate(
                                researchData.completed_at, 
                                researchData.duration_seconds
                            );
                            document.getElementById('result-mode').textContent = formatMode(researchData.mode);
                            
                            // Update duration if available (for backward compatibility with existing UI elements)
                            if (researchData.created_at && researchData.completed_at && !researchData.duration_seconds) {
                                // Calculate duration if it's not provided by the API
                                const startDate = new Date(researchData.created_at);
                                const endDate = new Date(researchData.completed_at);
                                const durationSec = Math.floor((endDate - startDate) / 1000);
                                
                                // Update the date display with calculated duration
                                document.getElementById('result-date').textContent = formatDate(
                                    researchData.completed_at, 
                                    durationSec
                                );
                                
                                // Also update any UI elements that might rely on updateResearchDuration
                                const metadata = {
                                    started_at: researchData.created_at,
                                    completed_at: researchData.completed_at
                                };
                                updateResearchDuration(metadata);
                            }
                            
                            // Render the content
                            const resultsContent = document.getElementById('results-content');
                            resultsContent.innerHTML = ''; // Clear any previous content
                            
                            // Convert markdown to HTML
                            const htmlContent = marked.parse(data.content);
                            resultsContent.innerHTML = htmlContent;
                            
                            // Apply code highlighting
                            document.querySelectorAll('pre code').forEach((block) => {
                                hljs.highlightBlock(block);
                            });
                            
                            // Load logs for this research
                            loadLogsForResearch(researchId);
                            
                            // Switch to the results page
                            switchPage('research-results');
                        })
                        .catch(error => {
                            console.error(`Error loading research: ${error}`);
                        });
                })
                .catch(error => {
                    console.error(`Error checking research status: ${error}`);
                });
        } catch (error) {
            console.error(`Error loading research: ${error}`);
        }
    }
    
    // Function to load research details
    async function loadResearchDetails(researchId) {
        try {
            // Show loading indicators
            document.getElementById('research-log').innerHTML = '<div class="loading-spinner centered"><div class="spinner"></div></div>';
            
            // Set the current viewing research ID
            viewingResearchId = researchId;
            
            // Fetch the research data
            const response = await fetch(getApiUrl(`/api/research/${researchId}/details`));
            const data = await response.json();
            
            if (data.status === 'success') {
                // Update the metadata display
                document.getElementById('detail-query').textContent = data.query || 'Unknown query';
                document.getElementById('detail-status').textContent = formatStatus(data.status);
                document.getElementById('detail-mode').textContent = formatMode(data.mode);
            
            // Update progress percentage
                const progressFill = document.getElementById('detail-progress-fill');
                const progressPercentage = document.getElementById('detail-progress-percentage');
                
                if (progressFill && progressPercentage) {
                    const progress = data.progress || 0;
                    progressFill.style.width = `${progress}%`;
                    progressPercentage.textContent = `${progress}%`;
                }
                
                // Update duration if available
                const metadata = {
                    created_at: data.created_at,
                    completed_at: data.completed_at
                };
                updateResearchDuration(metadata);
                
                // Render the log entries from the response directly
                if (data.log && Array.isArray(data.log)) {
                    renderResearchLog(data.log, researchId);
                } else {
                    // Fallback to the dedicated logs endpoint if log data is missing
                    try {
                        const logResponse = await fetch(getApiUrl(`/api/research/${researchId}/logs`));
                        const logData = await logResponse.json();
                        
                        if (logData.status === 'success' && logData.logs && Array.isArray(logData.logs)) {
                            renderResearchLog(logData.logs, researchId);
                        } else {
                            document.getElementById('research-log').innerHTML = '<div class="empty-state">No log entries available</div>';
                        }
                    } catch (logError) {
                        console.error('Error fetching logs:', logError);
                        document.getElementById('research-log').innerHTML = '<div class="empty-state">Failed to load log entries</div>';
                    }
                }
                
                // Update detail actions based on research status
                updateDetailActions(data);
                
                // Load logs for the console panel as well
                loadLogsForResearch(researchId);
                
                // Switch to the details page
                switchPage('research-details');
            } else {
                alert('Failed to load research details: ' + (data.message || 'Unknown error'));
            }
        } catch (error) {
            console.error('Error loading research details:', error);
            alert('An error occurred while loading the research details');
        }
    }
    
    // Function to render log entries
    function renderResearchLog(logEntries, researchId) {
        const researchLog = document.getElementById('research-log');
        researchLog.innerHTML = '';
        
        if (!logEntries || logEntries.length === 0) {
            researchLog.innerHTML = '<div class="empty-state">No log entries available.</div>';
            return;
        }
        
        try {
            // Use a document fragment for better performance
            const fragment = document.createDocumentFragment();
            const template = document.getElementById('log-entry-template');
            
            if (!template) {
                console.error('Log entry template not found');
                researchLog.innerHTML = '<div class="error-message">Error rendering log entries: Template not found</div>';
                return;
            }
            
            logEntries.forEach(entry => {
                if (!entry) return; // Skip invalid entries
                
                try {
                    const clone = document.importNode(template.content, true);
                    
                    // Format the timestamp
                    let timeStr = 'N/A';
                    try {
                        if (entry.time) {
                            const time = new Date(entry.time);
                            timeStr = time.toLocaleTimeString();
                        }
                    } catch (timeErr) {
                        console.warn('Error formatting time:', timeErr);
                    }
                    
                    const timeEl = clone.querySelector('.log-entry-time');
                    if (timeEl) timeEl.textContent = timeStr;
                    
                    // Add message with phase highlighting if available
                    const messageEl = clone.querySelector('.log-entry-message');
                    if (messageEl) {
                        let phaseClass = '';
                        if (entry.metadata && entry.metadata.phase) {
                            phaseClass = `phase-${entry.metadata.phase}`;
                        }
                        messageEl.textContent = entry.message || 'No message';
                        messageEl.classList.add(phaseClass);
                    }
                    
                    // Add progress information if available
                    const progressEl = clone.querySelector('.log-entry-progress');
                    if (progressEl) {
                        if (entry.progress !== null && entry.progress !== undefined) {
                            progressEl.textContent = `Progress: ${entry.progress}%`;
                        } else {
                            progressEl.textContent = '';
                        }
                    }
                    
                    fragment.appendChild(clone);
                } catch (entryError) {
                    console.error('Error processing log entry:', entryError, entry);
                    // Continue with other entries
                }
            });
            
            researchLog.appendChild(fragment);
            
            // Scroll to the bottom
            researchLog.scrollTop = researchLog.scrollHeight;
        } catch (error) {
            console.error('Error rendering log entries:', error);
            researchLog.innerHTML = '<div class="error-message">Error rendering log entries. Please try again later.</div>';
        }
        
        // Connect to socket for updates if this is an in-progress research
        // Check for research ID and whether it's in progress by checking the database status
        if (researchId) {
            // Check research status in the database to determine if we should connect to socket
            fetch(getApiUrl(`/api/research/${researchId}`))
                .then(response => response.json())
                .then(data => {
                    if (data && data.status === 'in_progress') {
                        console.log(`Connecting to socket for research ${researchId} from log view`);
                        window.connectToResearchSocket(researchId);
                    }
                })
                .catch(err => console.error(`Error checking research status for socket connection: ${err}`));
        }
    }
    
    // Function to update detail log with a new entry
    function updateDetailLogEntry(logEntry) {
        if (!logEntry || !document.getElementById('research-details').classList.contains('active')) {
            return;
        }
        
        const researchLog = document.getElementById('research-log');
        const template = document.getElementById('log-entry-template');
        const clone = document.importNode(template.content, true);
        
        // Format the timestamp
        const time = new Date(logEntry.time);
        clone.querySelector('.log-entry-time').textContent = time.toLocaleTimeString();
        
        // Add message with phase highlighting if available
        const messageEl = clone.querySelector('.log-entry-message');
        let phaseClass = '';
        if (logEntry.metadata && logEntry.metadata.phase) {
            phaseClass = `phase-${logEntry.metadata.phase}`;
        }
        messageEl.textContent = logEntry.message;
        messageEl.classList.add(phaseClass);
        
        // Add progress information if available
        const progressEl = clone.querySelector('.log-entry-progress');
        if (logEntry.progress !== null && logEntry.progress !== undefined) {
            progressEl.textContent = `Progress: ${logEntry.progress}%`;
            
            // Also update the progress bar in the details view
            document.getElementById('detail-progress-fill').style.width = `${logEntry.progress}%`;
            document.getElementById('detail-progress-percentage').textContent = `${logEntry.progress}%`;
        } else {
            progressEl.textContent = '';
        }
        
        researchLog.appendChild(clone);
        
        // Scroll to the bottom
        researchLog.scrollTop = researchLog.scrollHeight;
    }
    
    // Back to history button handlers - using direct page switching
    document.getElementById('back-to-history')?.addEventListener('click', () => {
        switchPage('history');
    });
    
    document.getElementById('back-to-history-from-details')?.addEventListener('click', () => {
        switchPage('history');
    });
    
    // Helper functions
    function capitalizeFirstLetter(string) {
        return string.charAt(0).toUpperCase() + string.slice(1);
    }
    
    // Function to update progress UI from current research
    function updateProgressFromCurrentResearch() {
        if (!isResearchInProgress || !currentResearchId) return;
        
        // Fetch current status
        fetch(getApiUrl(`/api/research/${currentResearchId}`))
        .then(response => response.json())
        .then(data => {
            document.getElementById('current-query').textContent = data.query || '';
            document.getElementById('progress-fill').style.width = `${data.progress || 0}%`;
            document.getElementById('progress-percentage').textContent = `${data.progress || 0}%`;
            
            // Connect to socket for this research
            window.connectToResearchSocket(currentResearchId);
        })
        .catch(error => {
            console.error('Error fetching research status:', error);
        });
    }

    // Function to update the sidebar navigation based on research status
    function updateNavigationBasedOnResearchStatus() {
        const isResearchPage = document.getElementById('research-progress').classList.contains('active');
        const isAnyResearchInProgress = window.currentResearchId !== null && isResearchInProgress;
        
        // Get the sidebar nav items and mobile tab items
        const sidebarNewResearchItem = document.querySelector('.sidebar-nav li[data-page="new-research"]');
        const sidebarHistoryItem = document.querySelector('.sidebar-nav li[data-page="history"]');
        const mobileNewResearchItem = document.querySelector('.mobile-tab-bar li[data-page="new-research"]');
        const mobileHistoryItem = document.querySelector('.mobile-tab-bar li[data-page="history"]');
        
        // Control elements
        const terminateBtn = document.getElementById('terminate-research-btn');
        const errorMessage = document.getElementById('error-message');
        const tryAgainBtn = document.getElementById('try-again-btn');
        
        // Log panel should only be visible on research-progress and research-results pages
        const logPanel = document.querySelector('.collapsible-log-panel');
        
        // If research is in progress
        if (isAnyResearchInProgress) {
            // Disable new research and history navigation while research is in progress
            if (sidebarNewResearchItem) sidebarNewResearchItem.classList.add('disabled');
            if (sidebarHistoryItem) sidebarHistoryItem.classList.add('disabled');
            if (mobileNewResearchItem) mobileNewResearchItem.classList.add('disabled');
            if (mobileHistoryItem) mobileHistoryItem.classList.add('disabled');
            
            // If user is not already on the research progress page, switch to it
            if (!isResearchPage) {
                switchPage('research-progress');
            }
            
            // Show terminate button and hide error message and try again button
            if (terminateBtn) terminateBtn.style.display = 'block';
            if (errorMessage) errorMessage.style.display = 'none';
            if (tryAgainBtn) tryAgainBtn.style.display = 'none';
        } else {
            // Enable navigation when no research is in progress
            if (sidebarNewResearchItem) sidebarNewResearchItem.classList.remove('disabled');
            if (sidebarHistoryItem) sidebarHistoryItem.classList.remove('disabled');
            if (mobileNewResearchItem) mobileNewResearchItem.classList.remove('disabled');
            if (mobileHistoryItem) mobileHistoryItem.classList.remove('disabled');
            
            // Hide terminate button when no research is in progress
            if (terminateBtn) terminateBtn.style.display = 'none';
        }
        
        console.log('Updated navigation based on research status. In progress:', isAnyResearchInProgress);
    }

    // Function to update the research progress page from nav click
    function updateProgressPage() {
        if (!currentResearchId && !window.currentResearchId) {
            return;
        }
        
        const researchId = currentResearchId || window.currentResearchId;
        
        // Update the progress page
        fetch(getApiUrl(`/api/research/${researchId}`))
            .then(response => response.json())
            .then(data => {
                // Update the query display
                document.getElementById('current-query').textContent = data.query;
                
                // Check status before updating UI
                if (data.status === 'in_progress') {
                    // Update the progress bar
                    updateProgressUI(data.progress || 0, data.status);
                    
                    // Check if we need to show the terminate button
                    const terminateBtn = document.getElementById('terminate-research-btn');
                    if (terminateBtn) {
                        terminateBtn.style.display = 'inline-flex';
                        terminateBtn.disabled = false;
                    }
                    
                    // Only connect to socket for in-progress research
                    window.connectToResearchSocket(researchId);
                    // Only start polling for in-progress research
                    if (!pollingInterval) {
                        pollResearchStatus(researchId);
                    }
                } 
                else if (data.status === 'suspended' || data.status === 'failed') {
                    // Update UI for terminated research
                    updateTerminationUIState('suspended', data.error || `Research was ${data.status}`);
                    // Update progress bar
                    document.getElementById('progress-fill').style.width = `${data.progress || 0}%`;
                    document.getElementById('progress-percentage').textContent = `${data.progress || 0}%`;
                }
                else {
                    // Just update progress for completed research
                    document.getElementById('progress-fill').style.width = `${data.progress || 0}%`;
                    document.getElementById('progress-percentage').textContent = `${data.progress || 0}%`;
                }
            })
            .catch(error => {
                console.error('Error fetching research status:', error);
            });
    }

    // Function to update a specific history item without reloading the whole list
    function updateHistoryItemStatus(researchId, status, statusText) {
        const historyList = document.getElementById('history-list');
        
        // Format the status for display
        const displayStatus = statusText || 
            (status === 'in_progress' ? 'In Progress' : 
             status.charAt(0).toUpperCase() + status.slice(1));
        
        // Format the CSS class
        const statusClass = `status-${status.replace('_', '-')}`;
        
        // Look for the item in the active research banner
        const activeBanner = historyList.querySelector(`.active-research-banner[data-research-id="${researchId}"]`);
        if (activeBanner) {
            const statusEl = activeBanner.querySelector('.history-item-status');
            if (statusEl) {
                statusEl.textContent = displayStatus;
                statusEl.className = 'history-item-status';
                statusEl.classList.add(statusClass);
            }
            
            // Update buttons
            const terminateBtn = activeBanner.querySelector('.terminate-btn');
            if (terminateBtn) {
                terminateBtn.style.display = 'none';
            }
            
            const viewProgressBtn = activeBanner.querySelector('.view-progress-btn');
            if (viewProgressBtn) {
                if (status === 'suspended') {
                    viewProgressBtn.innerHTML = '<i class="fas fa-pause-circle"></i> Suspended';
                } else if (status === 'failed') {
                    viewProgressBtn.innerHTML = '<i class="fas fa-exclamation-triangle"></i> Failed';
                }
                viewProgressBtn.disabled = true;
            }
            
            return;
        }
        
        // Look for the item in the regular list
        const historyItem = historyList.querySelector(`.history-item[data-research-id="${researchId}"]`);
        if (historyItem) {
            const statusEl = historyItem.querySelector('.history-item-status');
            if (statusEl) {
                statusEl.textContent = displayStatus;
                statusEl.className = 'history-item-status';
                statusEl.classList.add(statusClass);
            }
            
            // Update view button
            const viewBtn = historyItem.querySelector('.view-btn');
            if (viewBtn) {
                if (status === 'suspended') {
                    viewBtn.innerHTML = '<i class="fas fa-pause-circle"></i> Suspended';
                    viewBtn.disabled = true;
                } else if (status === 'failed') {
                    viewBtn.innerHTML = '<i class="fas fa-exclamation-triangle"></i> Failed';
                    viewBtn.disabled = true;
                } else if (status === 'completed') {
                    viewBtn.innerHTML = '<i class="fas fa-eye"></i> View';
                    viewBtn.disabled = false;
                    
                    // Also make the PDF button visible if not already
                    const pdfBtn = historyItem.querySelector('.pdf-btn');
                    if (pdfBtn) {
                        pdfBtn.style.display = 'inline-flex';
                    }
                }
            }
        }
    }

    // PDF Generation Functions
    function generatePdf() {
        const resultsContent = document.getElementById('results-content');
        const query = document.getElementById('result-query').textContent;
        const date = document.getElementById('result-date').textContent;
        const mode = document.getElementById('result-mode').textContent;
        
        // Show loading indicator
        const loadingIndicator = document.createElement('div');
        loadingIndicator.className = 'loading-spinner centered';
        loadingIndicator.innerHTML = '<div class="spinner"></div><p style="margin-top: 10px;">Generating PDF...</p>';
        resultsContent.parentNode.insertBefore(loadingIndicator, resultsContent);
        resultsContent.style.display = 'none';
        
        // Create a clone of the content for PDF generation
        const contentClone = resultsContent.cloneNode(true);
        contentClone.style.display = 'block';
        contentClone.style.position = 'absolute';
        contentClone.style.left = '-9999px';
        contentClone.style.width = '800px';
        
        // Apply PDF-specific styling for better readability
        contentClone.style.background = '#ffffff';
        contentClone.style.color = '#333333';
        contentClone.style.padding = '20px';
        
        // Improve visibility by adjusting styles specifically for PDF
        const applyPdfStyles = (element) => {
            // Set all text to dark color for better readability on white background
            element.querySelectorAll('*').forEach(el => {
                // Skip elements that already have inline color styles
                if (!el.style.color) {
                    el.style.color = '#333333';
                }
                
                // Fix background colors
                if (el.style.backgroundColor && 
                    (el.style.backgroundColor.includes('var(--bg') || 
                     el.style.backgroundColor.includes('#121212') ||
                     el.style.backgroundColor.includes('#1e1e2d') ||
                     el.style.backgroundColor.includes('#2a2a3a'))) {
                    el.style.backgroundColor = '#f8f8f8';
                }
                
                // Handle code blocks specifically
                if (el.tagName === 'PRE' || el.tagName === 'CODE') {
                    el.style.backgroundColor = '#f5f5f5';
                    el.style.border = '1px solid #e0e0e0';
                    el.style.color = '#333333';
                }
                
                // Make links visible
                if (el.tagName === 'A') {
                    el.style.color = '#0066cc';
                    el.style.textDecoration = 'underline';
                }
            });
            
            // Fix specific syntax highlighting elements for PDF
            element.querySelectorAll('.hljs').forEach(hljs => {
                hljs.style.backgroundColor = '#f8f8f8';
                hljs.style.color = '#333333';
                
                // Fix common syntax highlighting colors for PDF
                hljs.querySelectorAll('.hljs-keyword').forEach(el => el.style.color = '#0000cc');
                hljs.querySelectorAll('.hljs-string').forEach(el => el.style.color = '#008800');
                hljs.querySelectorAll('.hljs-number').forEach(el => el.style.color = '#aa0000');
                hljs.querySelectorAll('.hljs-comment').forEach(el => el.style.color = '#888888');
                hljs.querySelectorAll('.hljs-function').forEach(el => el.style.color = '#880000');
            });
        };
        
        document.body.appendChild(contentClone);
        
        // Apply PDF-specific styles
        applyPdfStyles(contentClone);
        
        // Add title and metadata to the PDF content
        const headerDiv = document.createElement('div');
        headerDiv.innerHTML = `
            <h1 style="color: #6e4ff6; font-size: 24px; margin-bottom: 10px;">${query}</h1>
            <div style="margin-bottom: 20px; font-size: 14px; color: #666;">
                <p><strong>Generated:</strong> ${date}</p>
                <p><strong>Mode:</strong> ${mode}</p>
                <p><strong>Source:</strong> Deep Research Lab</p>
            </div>
            <hr style="margin-bottom: 20px; border: 1px solid #eee;">
        `;
        contentClone.insertBefore(headerDiv, contentClone.firstChild);
        
        setTimeout(() => {
            try {
                // Use window.jspdf which is from the UMD bundle
                const { jsPDF } = window.jspdf;
                const pdf = new jsPDF('p', 'pt', 'a4');
                const pdfWidth = pdf.internal.pageSize.getWidth();
                const pdfHeight = pdf.internal.pageSize.getHeight();
                const margin = 40;
                const contentWidth = pdfWidth - 2 * margin;
                
                // Create a more efficient PDF generation approach that keeps text selectable
                const generateTextBasedPDF = async () => {
                    try {
                        // Get all text elements and handle them differently than images and special content
                        const elements = Array.from(contentClone.children);
                        let currentY = margin;
                        let pageNum = 1;
                        
                        // Function to add a page with header
                        const addPageWithHeader = (pageNum) => {
                            if (pageNum > 1) {
                                pdf.addPage();
                            }
                            pdf.setFontSize(8);
                            pdf.setTextColor(100, 100, 100);
                            pdf.text(`Deep Research - ${query} - Page ${pageNum}`, margin, pdfHeight - 20);
                        };
                        
                        addPageWithHeader(pageNum);
                        
                        // Process each element
                        for (const element of elements) {
                            // Simple text content - handled directly by jsPDF
                            if ((element.tagName === 'P' || element.tagName === 'DIV') && 
                                !element.querySelector('img, canvas, svg') &&
                                element.children.length === 0) {
                                
                                pdf.setFontSize(11);
                                pdf.setTextColor(0, 0, 0);
                                
                                const text = element.textContent.trim();
                                if (!text) continue; // Skip empty text
                                
                                const textLines = pdf.splitTextToSize(text, contentWidth);
                                
                                // Check if we need a new page
                                if (currentY + (textLines.length * 14) > pdfHeight - margin) {
                                    pageNum++;
                                    addPageWithHeader(pageNum);
                                    currentY = margin;
                                }
                                
                                pdf.text(textLines, margin, currentY + 12);
                                currentY += (textLines.length * 14) + 10;
                            } 
                            // Handle headings
                            else if (['H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(element.tagName)) {
                                const fontSize = {
                                    'H1': 24,
                                    'H2': 20,
                                    'H3': 16,
                                    'H4': 14,
                                    'H5': 12,
                                    'H6': 11
                                }[element.tagName];
                                
                                // Add heading text as native PDF text 
                                pdf.setFontSize(fontSize);
                                
                                // Use a different color for headings to match styling
                                if (element.tagName === 'H1') {
                                    pdf.setTextColor(110, 79, 246); // Purple for main headers
                                } else if (element.tagName === 'H2') {
                                    pdf.setTextColor(70, 90, 150); // Darker blue for H2
                                } else {
                                    pdf.setTextColor(0, 0, 0); // Black for other headings
                                }
                                
                                const text = element.textContent.trim();
                                if (!text) continue; // Skip empty headings
                                
                                const textLines = pdf.splitTextToSize(text, contentWidth);
                                
                                // Check if we need a new page
                                if (currentY + (textLines.length * (fontSize + 4)) > pdfHeight - margin) {
                                    pageNum++;
                                    addPageWithHeader(pageNum);
                                    currentY = margin + 40; // Reset Y position after header
                                }
                                
                                pdf.text(textLines, margin, currentY + fontSize);
                                currentY += (textLines.length * (fontSize + 4)) + 10;
                                
                                // Add a subtle underline for H1 and H2
                                if (element.tagName === 'H1' || element.tagName === 'H2') {
                                    pdf.setDrawColor(110, 79, 246, 0.5);
                                    pdf.setLineWidth(0.5);
                                    pdf.line(
                                        margin, 
                                        currentY - 5, 
                                        margin + Math.min(contentWidth, pdf.getTextWidth(text) * 1.2), 
                                        currentY - 5
                                    );
                                    currentY += 5; // Add a bit more space after underlined headings
                                }
                            }
                            // Handle lists
                            else if (element.tagName === 'UL' || element.tagName === 'OL') {
                                pdf.setFontSize(11);
                                pdf.setTextColor(0, 0, 0);
                                
                                const listItems = element.querySelectorAll('li');
                                let itemNumber = 1;
                                
                                for (const item of listItems) {
                                    const prefix = element.tagName === 'UL' ? '• ' : `${itemNumber}. `;
                                    const text = item.textContent.trim();
                                    
                                    if (!text) continue; // Skip empty list items
                                    
                                    // Split text to fit width, accounting for bullet/number indent
                                    const textLines = pdf.splitTextToSize(text, contentWidth - 15);
                                    
                                    // Check if we need a new page
                                    if (currentY + (textLines.length * 14) > pdfHeight - margin) {
                                        pageNum++;
                                        addPageWithHeader(pageNum);
                                        currentY = margin;
                                    }
                                    
                                    // Add the bullet/number
                                    pdf.text(prefix, margin, currentY + 12);
                                    
                                    // Add the text with indent
                                    pdf.text(textLines, margin + 15, currentY + 12);
                                    currentY += (textLines.length * 14) + 5;
                                    
                                    if (element.tagName === 'OL') itemNumber++;
                                }
                                
                                currentY += 5; // Extra space after list
                            }
                            // Handle code blocks as text
                            else if (element.tagName === 'PRE' || element.querySelector('pre')) {
                                const codeElement = element.tagName === 'PRE' ? element : element.querySelector('pre');
                                const codeText = codeElement.textContent.trim();
                                
                                if (!codeText) continue; // Skip empty code blocks
                                
                                // Use monospace font for code
                                pdf.setFont("courier", "normal");
                                pdf.setFontSize(9); // Smaller font for code
                                
                                // Calculate code block size
                                const codeLines = codeText.split('\n');
                                const lineHeight = 10; // Smaller line height for code
                                const codeBlockHeight = (codeLines.length * lineHeight) + 20; // Add padding
                                
                                // Add a background for the code block
                                if (currentY + codeBlockHeight > pdfHeight - margin) {
                                    pageNum++;
                                    addPageWithHeader(pageNum);
                                    currentY = margin;
                                }
                                
                                // Draw code block background
                                pdf.setFillColor(245, 245, 245); // Light gray background
                                pdf.rect(margin - 5, currentY, contentWidth + 10, codeBlockHeight, 'F');
                                
                                // Draw a border
                                pdf.setDrawColor(220, 220, 220);
                                pdf.setLineWidth(0.5);
                                pdf.rect(margin - 5, currentY, contentWidth + 10, codeBlockHeight, 'S');
                                
                                // Add the code text
                                pdf.setTextColor(0, 0, 0);
                                currentY += 10; // Add padding at top
                                
                                codeLines.forEach(line => {
                                    // Handle indentation by preserving leading spaces
                                    const spacePadding = line.match(/^(\s*)/)[0].length;
                                    const visibleLine = line.trimLeft();
                                    
                                    // Calculate width of space character
                                    const spaceWidth = pdf.getStringUnitWidth(' ') * 9 / pdf.internal.scaleFactor;
                                    
                                    pdf.text(visibleLine, margin + (spacePadding * spaceWidth), currentY);
                                    currentY += lineHeight;
                                });
                                
                                currentY += 10; // Add padding at bottom
                                
                                // Reset to normal font
                                pdf.setFont("helvetica", "normal");
                                pdf.setFontSize(11);
                            }
                            // Handle tables as text
                            else if (element.tagName === 'TABLE' || element.querySelector('table')) {
                                const tableElement = element.tagName === 'TABLE' ? element : element.querySelector('table');
                                
                                if (!tableElement) continue;
                                
                                // Get table rows
                                const rows = Array.from(tableElement.querySelectorAll('tr'));
                                if (rows.length === 0) continue;
                                
                                // Calculate column widths
                                const headerCells = Array.from(rows[0].querySelectorAll('th, td'));
                                const numColumns = headerCells.length;
                                
                                if (numColumns === 0) continue;
                                
                                // Default column width distribution (equal)
                                const colWidth = contentWidth / numColumns;
                                
                                // Start drawing table
                                let tableY = currentY + 10;
                                
                                // Check if we need a new page
                                if (tableY + (rows.length * 20) > pdfHeight - margin) {
                                    pageNum++;
                                    addPageWithHeader(pageNum);
                                    tableY = margin + 10;
                                    currentY = margin;
                                }
                                
                                // Draw table header
                                pdf.setFillColor(240, 240, 240);
                                pdf.rect(margin, tableY, contentWidth, 20, 'F');
                                
                                pdf.setFont("helvetica", "bold");
                                pdf.setFontSize(10);
                                pdf.setTextColor(0, 0, 0);
                                
                                headerCells.forEach((cell, index) => {
                                    const text = cell.textContent.trim();
                                    const x = margin + (index * colWidth) + 5;
                                    pdf.text(text, x, tableY + 13);
                                });
                                
                                // Draw horizontal line after header
                                pdf.setDrawColor(200, 200, 200);
                                pdf.setLineWidth(0.5);
                                pdf.line(margin, tableY + 20, margin + contentWidth, tableY + 20);
                                
                                tableY += 20;
                                
                                // Draw table rows
                                pdf.setFont("helvetica", "normal");
                                for (let i = 1; i < rows.length; i++) {
                                    // Check if we need a new page
                                    if (tableY + 20 > pdfHeight - margin) {
                                        // Draw bottom border for last row on current page
                                        pdf.line(margin, tableY, margin + contentWidth, tableY);
                                        
                                        // Add new page
                                        pageNum++;
                                        addPageWithHeader(pageNum);
                                        tableY = margin + 10;
                                        
                                        // Redraw header on new page
                                        pdf.setFillColor(240, 240, 240);
                                        pdf.rect(margin, tableY, contentWidth, 20, 'F');
                                        
                                        pdf.setFont("helvetica", "bold");
                                        headerCells.forEach((cell, index) => {
                                            const text = cell.textContent.trim();
                                            const x = margin + (index * colWidth) + 5;
                                            pdf.text(text, x, tableY + 13);
                                        });
                                        
                                        pdf.line(margin, tableY + 20, margin + contentWidth, tableY + 20);
                                        tableY += 20;
                                        pdf.setFont("helvetica", "normal");
                                    }
                                    
                                    // Get cells for this row
                                    const cells = Array.from(rows[i].querySelectorAll('td, th'));
                                    
                                    // Alternate row background for better readability
                                    if (i % 2 === 0) {
                                        pdf.setFillColor(250, 250, 250);
                                        pdf.rect(margin, tableY, contentWidth, 20, 'F');
                                    }
                                    
                                    // Add cell content
                                    cells.forEach((cell, index) => {
                                        const text = cell.textContent.trim();
                                        const x = margin + (index * colWidth) + 5;
                                        pdf.text(text, x, tableY + 13);
                                    });
                                    
                                    // Draw horizontal line after row
                                    pdf.line(margin, tableY + 20, margin + contentWidth, tableY + 20);
                                    tableY += 20;
                                }
                                
                                // Draw vertical lines for columns
                                for (let i = 0; i <= numColumns; i++) {
                                    const x = margin + (i * colWidth);
                                    pdf.line(x, currentY + 10, x, tableY);
                                }
                                
                                currentY = tableY + 10;
                            }
                            // Images still need to be handled as images
                            else if (element.tagName === 'IMG' || element.querySelector('img')) {
                                const imgElement = element.tagName === 'IMG' ? element : element.querySelector('img');
                                
                                if (!imgElement || !imgElement.src) continue;
                                
                                try {
                                    // Create a new image to get dimensions
                                    const img = new Image();
                                    img.src = imgElement.src;
                                    
                                    // Calculate dimensions
                                    const imgWidth = contentWidth;
                                    const imgHeight = img.height * (contentWidth / img.width);
                                    
                                    // Check if we need a new page
                                    if (currentY + imgHeight > pdfHeight - margin) {
                                        pageNum++;
                                        addPageWithHeader(pageNum);
                                        currentY = margin;
                                    }
                                    
                                    // Add image to PDF
                                    pdf.addImage(img.src, 'JPEG', margin, currentY, imgWidth, imgHeight);
                                    currentY += imgHeight + 10;
                                } catch (imgError) {
                                    console.error('Error adding image:', imgError);
                                    pdf.text("[Image could not be rendered]", margin, currentY + 12);
                                    currentY += 20;
                                }
                            }
                            // Other complex elements still use html2canvas as fallback
                            else {
                                try {
                                const canvas = await html2canvas(element, {
                                        scale: 2,
                                    useCORS: true,
                                    logging: false,
                                    backgroundColor: '#FFFFFF'
                                });
                                
                                const imgData = canvas.toDataURL('image/png');
                                    const imgWidth = contentWidth;
                                const imgHeight = (canvas.height * contentWidth) / canvas.width;
                                
                                if (currentY + imgHeight > pdfHeight - margin) {
                                    pageNum++;
                                    addPageWithHeader(pageNum);
                                    currentY = margin;
                                }
                                
                                    pdf.addImage(imgData, 'PNG', margin, currentY, imgWidth, imgHeight);
                                currentY += imgHeight + 10;
                                } catch (canvasError) {
                                    console.error('Error rendering complex element:', canvasError);
                                    pdf.text("[Complex content could not be rendered]", margin, currentY + 12);
                                    currentY += 20;
                                }
                            }
                        }
                        
                        // Download the PDF
                        const filename = `${query.replace(/[^a-z0-9]/gi, '_').substring(0, 30).toLowerCase()}_research.pdf`;
                        pdf.save(filename);
                        
                        // Clean up
                        document.body.removeChild(contentClone);
                        resultsContent.style.display = 'block';
                        loadingIndicator.remove();
                    } catch (error) {
                        console.error('Error generating PDF:', error);
                        alert('An error occurred while generating the PDF. Please try again.');
                        document.body.removeChild(contentClone);
                        resultsContent.style.display = 'block';
                        loadingIndicator.remove();
                    }
                };
                
                generateTextBasedPDF();
            } catch (error) {
                console.error('Error initializing PDF generation:', error);
                alert('An error occurred while preparing the PDF. Please try again.');
                document.body.removeChild(contentClone);
                resultsContent.style.display = 'block';
                loadingIndicator.remove();
            }
        }, 100);
    }
    
    // Function to generate PDF from a specific research ID
    async function generatePdfFromResearch(researchId) {
        try {
            // Load research details
            const detailsResponse = await fetch(getApiUrl(`/api/research/${researchId}`));
            const details = await detailsResponse.json();
            
            // Load the report content
            const reportResponse = await fetch(getApiUrl(`/api/report/${researchId}`));
            const reportData = await reportResponse.json();
            
            if (reportData.status === 'success') {
                // Create a temporary container to render the content
                const tempContainer = document.createElement('div');
                tempContainer.className = 'results-content pdf-optimized';
                tempContainer.style.display = 'none';
                document.body.appendChild(tempContainer);
                
                // Render markdown with optimized styles for PDF
                const renderedContent = marked.parse(reportData.content);
                tempContainer.innerHTML = renderedContent;
                
                // Apply syntax highlighting
                tempContainer.querySelectorAll('pre code').forEach((block) => {
                    hljs.highlightElement(block);
                });
                
                // Format date with duration
                let dateText = formatDate(
                    new Date(details.completed_at || details.created_at),
                    details.duration_seconds
                );
                
                // Set up data for PDF generation
                document.getElementById('result-query').textContent = details.query;
                document.getElementById('result-date').textContent = dateText;
                document.getElementById('result-mode').textContent = details.mode === 'quick' ? 'Quick Summary' : 'Detailed Report';
                
                // Replace the current content with our temporary content
                const resultsContent = document.getElementById('results-content');
                const originalContent = resultsContent.innerHTML;
                resultsContent.innerHTML = tempContainer.innerHTML;
                
                // Generate the PDF
                generatePdf();
                
                // Restore original content if we're not on the results page
                setTimeout(() => {
                    if (!document.getElementById('research-results').classList.contains('active')) {
                        resultsContent.innerHTML = originalContent;
                    }
                    document.body.removeChild(tempContainer);
                }, 500);
                
            } else {
                alert('Error loading report. Could not generate PDF.');
            }
        } catch (error) {
            console.error('Error generating PDF:', error);
            alert('An error occurred while generating the PDF. Please try again.');
        }
    }

    // Initialize the terminate button event listener
    const terminateBtn = document.getElementById('terminate-research-btn');
    if (terminateBtn) {
        terminateBtn.addEventListener('click', function() {
            if (currentResearchId) {
                terminateResearch(currentResearchId);
            } else {
                console.error('No active research ID found for termination');
                alert('No active research ID found. Please try again.');
            }
        });
    }
    
    // Initialize PDF download button
    const downloadPdfBtn = document.getElementById('download-pdf-btn');
    if (downloadPdfBtn) {
        downloadPdfBtn.addEventListener('click', generatePdf);
    }

    // Function to set up the research form
    function setupResearchForm() {
        const researchForm = document.getElementById('research-form');
        const notificationToggle = document.getElementById('notification-toggle');
        
        // Set notification state from toggle
        if (notificationToggle) {
            notificationsEnabled = notificationToggle.checked;
            
            // Listen for changes to the toggle
            notificationToggle.addEventListener('change', function() {
                notificationsEnabled = this.checked;
                // Store preference in localStorage for persistence
                localStorage.setItem('notificationsEnabled', notificationsEnabled);
            });
            
            // Load saved preference from localStorage
            const savedPref = localStorage.getItem('notificationsEnabled');
            if (savedPref !== null) {
                notificationsEnabled = savedPref === 'true';
                notificationToggle.checked = notificationsEnabled;
            }
        }
        
        // ... existing form setup ...
    }

    // Add event listener for view results button
    const viewResultsBtn = document.getElementById('view-results-btn');
    if (viewResultsBtn) {
        viewResultsBtn.addEventListener('click', () => {
            console.log('View results button clicked');
            if (currentResearchId) {
                loadResearch(currentResearchId);
            } else {
                console.error('No research ID available');
            }
        });
    }
    
    // Add listener for research_completed custom event
    document.addEventListener('research_completed', (event) => {
        console.log('Research completed event received:', event.detail);
        const data = event.detail;
        
        // Mark research as no longer in progress
        isResearchInProgress = false;
        
        // Hide terminate button
        const terminateBtn = document.getElementById('terminate-research-btn');
        if (terminateBtn) {
            terminateBtn.style.display = 'none';
        }
        
        // Update navigation
        updateNavigationBasedOnResearchStatus();
    });

    // Function to reset progress animations and UI elements
    function resetProgressAnimations() {
        // Reset the progress bar animation
        const progressFill = document.getElementById('progress-fill');
        if (progressFill) {
            // Force a reflow to reset the animation
            progressFill.style.display = 'none';
            progressFill.offsetHeight; // Trigger reflow
            progressFill.style.display = 'block';
        }
        
        // Reset any spinning icons
        const spinners = document.querySelectorAll('.fa-spinner.fa-spin');
        spinners.forEach(spinner => {
            const parent = spinner.parentElement;
            if (parent && parent.tagName === 'BUTTON') {
                if (parent.classList.contains('terminate-btn')) {
                    parent.innerHTML = '<i class="fas fa-stop-circle"></i> Terminate Research';
                    parent.disabled = false;
                }
            }
        });
        
        // Ensure the isTerminating flag is reset
        isTerminating = false;
    }

    // Create a dynamic favicon
    function createDynamicFavicon(emoji = '⚡') {
        console.log(`Creating dynamic favicon with emoji: ${emoji}`);
        
        // Create a canvas element
        const canvas = document.createElement('canvas');
        canvas.width = 32;
        canvas.height = 32;
        
        // Get the canvas context
        const ctx = canvas.getContext('2d');
        
        // Clear the canvas with a transparent background
        ctx.clearRect(0, 0, 32, 32);
        
        // Set the font size and font family
        ctx.font = '24px Arial';
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        
        // Draw the emoji in the center of the canvas
        ctx.fillText(emoji, 16, 16);
        
        // Convert canvas to favicon URL
        const faviconUrl = canvas.toDataURL('image/png');
        
        // Find existing favicon or create a new one
        let link = document.querySelector('link[rel="icon"]');
        if (!link) {
            link = document.createElement('link');
            link.rel = 'icon';
            link.id = 'dynamic-favicon';
            document.head.appendChild(link);
        }
        
        // Update the favicon
        link.type = 'image/x-icon';
        link.href = faviconUrl;
        
        return faviconUrl;
    }

    // Function to set favicon based on research mode
    function setFavicon(mode) {
        const emoji = mode === 'detailed' ? '🔬' : '⚡';
        return createDynamicFavicon(emoji);
    }

    // Global log tracking variables
    let consoleLogEntries = [];
    let logCount = 0;
    let lastLogMessage = null; // Track the last log message to prevent duplicates
    let lastLogTimestamp = null; // Track the last log timestamp
    let viewingResearchId = null; // Track which research ID is currently being viewed

    // Function to filter console logs by type
    function filterConsoleLogs(filterType = 'all') {
        console.log(`----- FILTER LOGS START (${filterType}) -----`);
        console.log(`Filtering logs by type: ${filterType}`);
        
        // Make sure the filter type is lowercase for consistency
        filterType = filterType.toLowerCase();
        
        // Get all log entries from the DOM
        const logEntries = document.querySelectorAll('.console-log-entry');
        console.log(`Found ${logEntries.length} log entries to filter`);
        
        // If no entries found, exit early
        if (logEntries.length === 0) {
            console.log('No log entries found to filter');
            console.log(`----- FILTER LOGS END (${filterType}) -----`);
            return;
        }
        
        let visibleCount = 0;
        
        // Apply filters
        logEntries.forEach(entry => {
            // Use the data attribute directly - this comes directly from the database
            const logType = entry.dataset.logType;
            
            // Determine visibility based on filter type
            let shouldShow = false;
            
            switch (filterType) {
                case 'all':
                    shouldShow = true;
                    break;
                case 'info':
                    shouldShow = logType === 'info';
                    break;
                case 'milestone':
                case 'milestones': // Handle plural form too
                    shouldShow = logType === 'milestone';
                    break;
                case 'error':
                case 'errors': // Handle plural form too
                    shouldShow = logType === 'error';
                    break;
                default:
                    shouldShow = true; // Default to showing everything
                    console.warn(`Unknown filter type: ${filterType}, showing all logs`);
            }
            
            // Set display style based on filter result
            entry.style.display = shouldShow ? '' : 'none';
            
            if (shouldShow) {
                visibleCount++;
            }
        });
        
        console.log(`Filtering complete. Showing ${visibleCount} of ${logEntries.length} logs with filter: ${filterType}`);
        
        // Show 'no logs' message if all logs are filtered out
        const consoleContainer = document.getElementById('console-log-container');
        if (consoleContainer && logEntries.length > 0) {
            // Remove any existing empty message
            const existingEmptyMessage = consoleContainer.querySelector('.empty-log-message');
            if (existingEmptyMessage) {
                existingEmptyMessage.remove();
            }
            
            // Add empty message if needed
            if (visibleCount === 0) {
                console.log(`Adding 'no logs' message for filter: ${filterType}`);
                const newEmptyMessage = document.createElement('div');
                newEmptyMessage.className = 'empty-log-message';
                newEmptyMessage.textContent = `No ${filterType} logs to display.`;
                consoleContainer.appendChild(newEmptyMessage);
            }
        }
        
        console.log(`----- FILTER LOGS END (${filterType}) -----`);
    }

    // Function to initialize the log panel
    function initializeLogPanel() {
        console.log('Initializing log panel');
        
        // Get DOM elements
        const logPanelToggle = document.getElementById('log-panel-toggle');
        const logPanelContent = document.getElementById('log-panel-content');
        const filterButtons = document.querySelectorAll('.filter-buttons .small-btn');
        
        // Check if elements exist
        if (!logPanelToggle || !logPanelContent) {
            console.error('Log panel elements not found');
            return;
        }
        
        console.log('Log panel elements found:', { 
            toggle: logPanelToggle ? 'Found' : 'Missing',
            content: logPanelContent ? 'Found' : 'Missing',
            filterButtons: filterButtons.length > 0 ? `Found ${filterButtons.length} buttons` : 'Missing'
        });
        
        // Set up toggle click handler
        logPanelToggle.addEventListener('click', function() {
            console.log('Log panel toggle clicked');
            
            // Toggle collapsed state
            logPanelContent.classList.toggle('collapsed');
            logPanelToggle.classList.toggle('collapsed');
            
            // Update toggle icon
            const toggleIcon = logPanelToggle.querySelector('.toggle-icon');
            if (toggleIcon) {
                if (logPanelToggle.classList.contains('collapsed')) {
                    toggleIcon.className = 'fas fa-chevron-right toggle-icon';
                } else {
                    toggleIcon.className = 'fas fa-chevron-down toggle-icon';
                    
                    // Scroll log container to bottom
                    const consoleContainer = document.getElementById('console-log-container');
                    if (consoleContainer) {
                        setTimeout(() => {
                            consoleContainer.scrollTop = consoleContainer.scrollHeight;
                        }, 10);
                    }
                }
            }
            
            console.log('Log panel is now ' + (logPanelContent.classList.contains('collapsed') ? 'collapsed' : 'expanded'));
        });
        
        // Initial state - collapsed
        logPanelContent.classList.add('collapsed');
        logPanelToggle.classList.add('collapsed');
        const toggleIcon = logPanelToggle.querySelector('.toggle-icon');
        if (toggleIcon) {
            toggleIcon.className = 'fas fa-chevron-right toggle-icon';
        }
        
        // Initial filtering - use a longer delay to ensure DOM is ready
        setTimeout(() => {
            console.log('Applying initial log filter: all');
            filterConsoleLogs('all');
        }, 300);
        
        console.log('Log panel initialization completed');
    }

    // Function to clear all console logs
    function clearConsoleLogs() {
        const consoleContainer = document.getElementById('console-log-container');
        if (!consoleContainer) return;
        
        console.log('Clearing console logs');
        
        // Reset the processed messages set to allow new logs after clearing
        window.processedMessages = new Set();
        
        // Clear the container
        consoleContainer.innerHTML = '<div class="empty-log-message">No logs yet. Research logs will appear here as they occur.</div>';
        
        // Reset the log entries array
        consoleLogEntries = [];
        
        // Reset the log count
        logCount = 0;
        updateLogIndicator();
        
        // Reset last message tracking
        lastLogMessage = null;
        lastLogTimestamp = null;
        
        // DO NOT reset viewingResearchId here, as clearing logs doesn't mean
        // we're changing which research we're viewing
        
        console.log('Console logs cleared');
    }

    // Function to determine if a log message is a milestone
    function isMilestoneLog(message, metadata) {
        if (!message) return false;
        
        // Critical milestones - main research flow points
        const criticalMilestones = [
            // Research start/end
            /^Research (started|complete)/i,
            /^Starting research/i,
            
            // Iteration markers
            /^Starting iteration \d+/i,
            /^Iteration \d+ complete/i,
            
            // Final completion
            /^Research completed successfully/i,
            /^Report generation complete/i,
            /^Writing research report to file/i
        ];
        
        // Check for critical milestones first
        const isCriticalMilestone = criticalMilestones.some(pattern => pattern.test(message));
        if (isCriticalMilestone) return true;
        
        // Check metadata phase for critical phases only
        const isCriticalPhase = metadata && (
            metadata.phase === 'init' ||
            metadata.phase === 'iteration_start' || 
            metadata.phase === 'iteration_complete' || 
            metadata.phase === 'complete' ||
            metadata.phase === 'report_generation' ||
            metadata.phase === 'report_complete'
        );
        
        return isCriticalPhase;
    }

    // Initialize the log panel when the application starts
    function initializeAppWithLogs() {
        // Original initializeApp function
        const originalInitializeApp = window.initializeApp || initializeApp;
        window.initializeApp = function() {
            // Call the original initialization
            originalInitializeApp();
            
            // Ensure global log variables are initialized
            window.consoleLogEntries = [];
            window.logCount = 0;
            window.lastLogMessage = null;
            window.lastLogTimestamp = null;
            
            // Initialize the log panel with a delay to ensure DOM is ready
            setTimeout(() => {
                initializeLogPanel();
                
                // Add an initial welcome log entry
                addConsoleLog('Research system initialized and ready', 'milestone');
                
                console.log('Log panel initialization completed');
            }, 100);
        };
    }

    // Call the initialization function immediately
    initializeAppWithLogs();

    // Function to get active research ID
    function getActiveResearchId() {
        return window.currentResearchId || currentResearchId;
    }

    // Function to update research duration on results display
    function updateResearchDuration(metadata) {
        if (!metadata || !metadata.started_at || !metadata.completed_at) return;
        
        try {
            // Parse ISO dates
            const startDate = new Date(metadata.started_at);
            const endDate = new Date(metadata.completed_at);
            
            // Calculate duration in seconds
            const durationMs = endDate - startDate;
            const durationSec = Math.floor(durationMs / 1000);
            
            // Format as minutes and seconds
            const minutes = Math.floor(durationSec / 60);
            const seconds = durationSec % 60;
            const formattedDuration = `${minutes}m ${seconds}s`;
            
            // Add to results metadata
            const resultsMetadata = document.querySelector('.results-metadata');
            if (resultsMetadata) {
                // Check if duration element already exists
                let durationEl = resultsMetadata.querySelector('.metadata-item.duration');
                
                if (!durationEl) {
                    // Create new duration element
                    durationEl = document.createElement('div');
                    durationEl.className = 'metadata-item duration';
                    
                    const labelEl = document.createElement('span');
                    labelEl.className = 'metadata-label';
                    labelEl.textContent = 'Duration:';
                    
                    const valueEl = document.createElement('span');
                    valueEl.className = 'metadata-value';
                    valueEl.id = 'result-duration';
                    
                    durationEl.appendChild(labelEl);
                    durationEl.appendChild(valueEl);
                    
                    // Insert after "Generated" metadata
                    const generatedEl = resultsMetadata.querySelector('.metadata-item:nth-child(2)');
                    if (generatedEl) {
                        resultsMetadata.insertBefore(durationEl, generatedEl.nextSibling);
                    } else {
                        resultsMetadata.appendChild(durationEl);
                    }
                }
                
                // Update duration value
                const durationValueEl = resultsMetadata.querySelector('#result-duration');
                if (durationValueEl) {
                    durationValueEl.textContent = formattedDuration;
                }
            }
            
            // Also add to research details metadata
            const detailsMetadata = document.querySelector('.research-metadata');
            if (detailsMetadata) {
                // Check if duration element already exists
                let durationEl = null;
                
                // Use querySelectorAll and iterate to find the element with "Duration" label
                const metadataItems = detailsMetadata.querySelectorAll('.metadata-item');
                for (let i = 0; i < metadataItems.length; i++) {
                    const labelEl = metadataItems[i].querySelector('.metadata-label');
                    if (labelEl && labelEl.textContent.includes('Duration')) {
                        durationEl = metadataItems[i];
                        break;
                    }
                }
                
                if (!durationEl) {
                    // Create new duration element
                    durationEl = document.createElement('div');
                    durationEl.className = 'metadata-item';
                    
                    const labelEl = document.createElement('span');
                    labelEl.className = 'metadata-label';
                    labelEl.textContent = 'Duration:';
                    
                    const valueEl = document.createElement('span');
                    valueEl.className = 'metadata-value';
                    valueEl.id = 'detail-duration';
                    
                    durationEl.appendChild(labelEl);
                    durationEl.appendChild(valueEl);
                    
                    // Insert after mode metadata
                    const modeEl = detailsMetadata.querySelector('.metadata-item:nth-child(3)');
                    if (modeEl) {
                        detailsMetadata.insertBefore(durationEl, modeEl.nextSibling);
                    } else {
                        detailsMetadata.appendChild(durationEl);
                    }
                }
                
                // Update duration value
                const durationValueEl = durationEl.querySelector('.metadata-value');
                if (durationValueEl) {
                    durationValueEl.textContent = formattedDuration;
                }
            }
            
            console.log(`Research duration: ${formattedDuration}`);
        } catch (error) {
            console.error('Error calculating research duration:', error);
        }
    }

    // Function to add a log entry to the console with reduced deduplication time window
    function addConsoleLog(message, type = 'info', metadata = null, forResearchId = null) {
        // Skip if identical to the last message to prevent duplication
        const currentTime = new Date().getTime();
        if (message === lastLogMessage && lastLogTimestamp && currentTime - lastLogTimestamp < 300) {
            // Skip duplicate message if it's within 300ms of the last one (reduced from 2000ms)
            return null;
        }
        
        // Skip if we're viewing a specific research and this log is for a different research
        if (viewingResearchId && forResearchId && viewingResearchId !== forResearchId) {
            console.log(`Skipping log for research ${forResearchId} because viewing ${viewingResearchId}`);
            return null;
        }
        
        // Update tracking variables
        lastLogMessage = message;
        lastLogTimestamp = currentTime;
        
        // Use the direct log addition function
        return addConsoleLogDirect(message, type, metadata);
    }

    // Function to update the log indicator count
    function updateLogIndicator() {
        const indicator = document.getElementById('log-indicator');
        if (indicator) {
            indicator.textContent = logCount;
        }
    }

    // New function to update log panel visibility based on current page
    function updateLogPanelVisibility(pageId) {
        console.log('Updating log panel visibility for page:', pageId);
        
        // Only show log panel on research progress and results pages
        if (pageId === 'research-progress' || pageId === 'research-results') {
            console.log('Showing log panel');
            // Let CSS handle the display
        } else {
            console.log('Hiding log panel');
            // Let CSS handle the display
        }
    }

    // Function to update the navigation UI based on active page
    function updateNavigationUI(pageId) {
        // Update sidebar navigation
        const sidebarNavItems = document.querySelectorAll('.sidebar-nav li');
        sidebarNavItems.forEach(item => {
            if (item.getAttribute('data-page') === pageId) {
                item.classList.add('active');
            } else {
                item.classList.remove('active');
            }
        });
        
        // Update mobile tab bar
        const mobileNavItems = document.querySelectorAll('.mobile-tab-bar li');
        mobileNavItems.forEach(item => {
            if (item.getAttribute('data-page') === pageId) {
                item.classList.add('active');
            } else {
                item.classList.remove('active');
            }
        });
    }

    // Function to check research status before polling
    async function checkResearchStatusBeforePolling(researchId) {
        try {
            // Get the current status from the server
            const response = await fetch(getApiUrl(`/api/research/${researchId}`));
            const data = await response.json();
            
            // If research is in_progress, start polling normally
            if (data.status === 'in_progress') {
                console.log(`Research ${researchId} is in progress, starting polling`);
                pollResearchStatus(researchId);
                window.connectToResearchSocket(researchId);
                return true;
            } 
            // If terminated or complete, update UI but don't start polling
            else if (data.status === 'suspended' || data.status === 'failed') {
                console.log(`Research ${researchId} is ${data.status}, not starting polling`);
                updateTerminationUIState('suspended', `Research was ${data.status}`);
                return false;
            }
            // If completed, don't start polling
            else if (data.status === 'completed') {
                console.log(`Research ${researchId} is completed, not starting polling`);
                return false;
            }
        } catch (error) {
            console.error(`Error checking research status: ${error}`);
            return false;
        }
        
        return false;
    }

    // Function to reset research state before starting a new research
    function resetResearchState() {
        // Clean up any existing research resources
        window.cleanupResearchResources();
        
        // Clear any previous polling intervals
        clearPollingInterval();
        
        // Reset research flags
        isResearchInProgress = false;
        currentResearchId = null;
        window.currentResearchId = null;
        
        // Clear console logs
        clearConsoleLogs();
        
        // Reset any UI elements
        const errorMessage = document.getElementById('error-message');
        if (errorMessage) {
            errorMessage.style.display = 'none';
            errorMessage.textContent = '';
        }
        
        // Hide the try again button if visible
        const tryAgainBtn = document.getElementById('try-again-btn');
        if (tryAgainBtn) {
            tryAgainBtn.style.display = 'none';
        }
        
        // Reset progress bar
        const progressFill = document.getElementById('progress-fill');
        if (progressFill) {
            progressFill.style.width = '0%';
        }
        
        // Reset progress percentage
        const progressPercentage = document.getElementById('progress-percentage');
        if (progressPercentage) {
            progressPercentage.textContent = '0%';
        }
        
        // Reset progress status
        const progressStatus = document.getElementById('progress-status');
        if (progressStatus) {
            progressStatus.textContent = 'Initializing research process...';
            progressStatus.className = 'progress-status';
        }
        
        // Reset the Start Research button 
        resetStartResearchButton();
        
        // Add initial log entry
        addConsoleLog('Preparing to start new research', 'info');
    }

    // Function to load research logs into the console log panel
    function loadLogsForResearch(researchId) {
        console.log(`Loading logs for research ${researchId}`);
        
        // Clear existing logs
        clearConsoleLogs();
        
        // Set the current viewing research ID
        viewingResearchId = researchId;
        
        // Fetch logs from the server for this research
        fetch(getApiUrl(`/api/research/${researchId}/logs`))
            .then(response => response.json())
            .then(data => {
                if (data.status === 'success' && Array.isArray(data.logs) && data.logs.length > 0) {
                    console.log(`Loaded ${data.logs.length} logs for research ${researchId}`);
                    
                    // Sort logs by timestamp if needed
                    data.logs.sort((a, b) => {
                        const timeA = new Date(a.time);
                        const timeB = new Date(b.time);
                        return timeA - timeB;
                    });
                    
                    // Add logs to the console
                    data.logs.forEach(log => {
                        let logType = 'info';
                        
                        // Use the type directly from the database if available
                        if (log.type) {
                            logType = log.type;
                        } else if (isMilestoneLog(log.message, log.metadata)) {
                            logType = 'milestone';
                        } else if (log.metadata && log.metadata.phase === 'error') {
                            logType = 'error';
                        }
                        
                        // Add to console without triggering the duplicate detection
                        // by directly creating the log entry
                        addConsoleLogDirect(log.message, logType, log.metadata, log.time);
                    });
                    
                    // Apply initial filter (all)
                    filterConsoleLogs('all');
                    
                    // Make sure the "All" button is selected
                    const allButton = document.querySelector('.filter-buttons .small-btn');
                    if (allButton) {
                        // Remove selected class from all buttons
                        document.querySelectorAll('.filter-buttons .small-btn').forEach(btn => {
                            btn.classList.remove('selected');
                        });
                        // Add selected class to the All button
                        allButton.classList.add('selected');
                    }
                } else {
                    console.log(`No logs found for research ${researchId}`);
                    // Add a message indicating no logs are available
                    const consoleContainer = document.getElementById('console-log-container');
                    if (consoleContainer) {
                        consoleContainer.innerHTML = '<div class="empty-log-message">No logs available for this research.</div>';
                    }
                }
            })
            .catch(error => {
                console.error(`Error loading logs for research ${researchId}:`, error);
                // Show error message in console log
                const consoleContainer = document.getElementById('console-log-container');
                if (consoleContainer) {
                    consoleContainer.innerHTML = '<div class="empty-log-message error-message">Failed to load logs. Please try again.</div>';
                }
            });
    }

    // New direct log addition function that bypasses duplicate detection
    function addConsoleLogDirect(message, type = 'info', metadata = null, timestamp = null) {
        // Get DOM elements
        const consoleContainer = document.getElementById('console-log-container');
        const template = document.getElementById('console-log-entry-template');
        
        if (!consoleContainer || !template) {
            console.error('Console log container or template not found');
            return null;
        }
        
        // Clear the empty message if it's the first log
        const emptyMessage = consoleContainer.querySelector('.empty-log-message');
        if (emptyMessage) {
            consoleContainer.removeChild(emptyMessage);
        }
        
        // Create a new log entry from the template
        const clone = document.importNode(template.content, true);
        const logEntry = clone.querySelector('.console-log-entry');
        
        // Make sure type is valid and standardized
        let validType = 'info';
        if (['info', 'milestone', 'error'].includes(type.toLowerCase())) {
            validType = type.toLowerCase();
        }
        
        // Add appropriate class based on type
        logEntry.classList.add(`log-${validType}`);
        
        // IMPORTANT: Store the log type directly as a data attribute
        logEntry.dataset.logType = validType;
        
        // Set the timestamp
        const actualTimestamp = timestamp ? new Date(timestamp).toLocaleTimeString() : new Date().toLocaleTimeString();
        const timestampEl = logEntry.querySelector('.log-timestamp');
        if (timestampEl) timestampEl.textContent = actualTimestamp;
        
        // Set the badge text based on type
        const badgeEl = logEntry.querySelector('.log-badge');
        if (badgeEl) {
            badgeEl.textContent = validType.toUpperCase();
        }
        
        // Process message to add search engine info if it's a search query
        let displayMessage = message;
        
        // Check if this is a search query message
        if (message && typeof message === 'string' && message.startsWith('Searching for:')) {
            // Determine search engine - add SearXNG by default since that's what we see in logs
            let searchEngine = 'SearXNG';
            
            // Check metadata if available for any search engine info
            if (metadata) {
                if (metadata.engine) searchEngine = metadata.engine;
                else if (metadata.search_engine) searchEngine = metadata.search_engine;
                else if (metadata.source) searchEngine = metadata.source;
                else if (metadata.phase && metadata.phase.includes('searxng')) searchEngine = 'SearXNG';
                else if (metadata.phase && metadata.phase.includes('google')) searchEngine = 'Google';
                else if (metadata.phase && metadata.phase.includes('bing')) searchEngine = 'Bing';
                else if (metadata.phase && metadata.phase.includes('duckduckgo')) searchEngine = 'DuckDuckGo';
            }
            
            // Append search engine info to message
            displayMessage = `${message} [Engine: ${searchEngine}]`;
        }
        
        // Set the message
        const messageEl = logEntry.querySelector('.log-message');
        if (messageEl) messageEl.textContent = displayMessage;
        
        // Add the log entry to the container
        consoleContainer.appendChild(logEntry);
        
        // Store the log entry for filtering
        consoleLogEntries.push({
            element: logEntry,
            type: validType,
            message: displayMessage,
            timestamp: actualTimestamp,
            researchId: viewingResearchId
        });
        
        // Update log count
        logCount++;
        updateLogIndicator();
        
        // Use setTimeout to ensure DOM updates before scrolling
        setTimeout(() => {
            // Scroll to the bottom
            consoleContainer.scrollTop = consoleContainer.scrollHeight;
        }, 0);
        
        return logEntry;
    }

    // Add a global function to filter logs directly from HTML
    window.filterLogsByType = function(filterType) {
        console.log('Direct filterLogsByType called with:', filterType);
        if (filterType && typeof filterConsoleLogs === 'function') {
            // Update the button styling for the selected filter
            const filterButtons = document.querySelectorAll('.filter-buttons .small-btn');
            if (filterButtons.length > 0) {
                // Remove 'selected' class from all buttons
                filterButtons.forEach(btn => {
                    btn.classList.remove('selected');
                });
                
                // Add 'selected' class to the clicked button
                const selectedButton = Array.from(filterButtons).find(
                    btn => btn.textContent.toLowerCase().includes(filterType) || 
                           (filterType === 'all' && btn.textContent.toLowerCase() === 'all')
                );
                
                if (selectedButton) {
                    selectedButton.classList.add('selected');
                }
            }
            
            // Apply the filter
            filterConsoleLogs(filterType);
        } else {
            console.error('Unable to filter logs - filterConsoleLogs function not available');
        }
    };

    // Function to check if there are any logs available
    window.checkIfLogsAvailable = function() {
        const logEntries = document.querySelectorAll('.console-log-entry');
        if (logEntries.length === 0) {
            console.log('No logs available to filter');
            return false;
        }
        return true;
    };

    // Add direct log panel toggle handler as backup
    const logPanelToggle = document.getElementById('log-panel-toggle');
    const logPanelContent = document.getElementById('log-panel-content');
    
    if (logPanelToggle && logPanelContent) {
        console.log('Adding direct DOM event listener to log panel toggle');
        
        logPanelToggle.addEventListener('click', function(event) {
            console.log('Log panel toggle clicked (direct handler)');
            event.preventDefault();
            event.stopPropagation();
            
            // Toggle collapsed state
            logPanelContent.classList.toggle('collapsed');
            logPanelToggle.classList.toggle('collapsed');
            
            // Update toggle icon
            const toggleIcon = logPanelToggle.querySelector('.toggle-icon');
            if (toggleIcon) {
                if (logPanelToggle.classList.contains('collapsed')) {
                    toggleIcon.className = 'fas fa-chevron-right toggle-icon';
                } else {
                    toggleIcon.className = 'fas fa-chevron-down toggle-icon';
                }
            }
            
            return false;
        });
    }
});