<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>NIA Control Center</title>
    <link rel="icon" href="https://trynia.ai/favicon.ico" type="image/x-icon">
    <script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
    <script src="https://cdn.tailwindcss.com"></script>
    <!-- Add Geist Font CSS -->
    <link rel="stylesheet" href="https://geistfont.vercel.app/geist.css">
    <script>
        tailwind.config = {
            darkMode: 'class', // Enable class-based dark mode
            theme: {
                extend: {
                    colors: {
                        // Light Theme (Previously B&W)
                        'light-bg': '#FFFFFF',
                        'light-text': '#111827', // Use a slightly softer black (gray-900)
                        'light-border': '#D1D5DB', // Gray-300
                        'light-secondary-bg': '#F3F4F6', // Gray-100
                        'light-secondary-text': '#374151', // Gray-700
                        'light-hover-bg': '#E5E7EB', // Gray-200
                        'light-hover-border': '#9CA3AF', // Gray-400
                        'light-active-bg': '#D1D5DB', // Gray-300

                        // Dark Theme
                        'dark-bg': '#111827', // Gray-900
                        'dark-text': '#E5E7EB', // Gray-200
                        'dark-border': '#374151', // Gray-700
                        'dark-secondary-bg': '#1F2937', // Gray-800
                        'dark-secondary-text': '#9CA3AF', // Gray-400
                        'dark-hover-bg': '#374151', // Gray-700
                        'dark-hover-border': '#6B7280', // Gray-500
                        'dark-active-bg': '#4B5563', // Gray-600

                        // Accent colors (can remain consistent or have dark variants)
                        'accent-yellow': '#F59E0B', // Amber-500
                        'accent-green': '#10B981', // Emerald-500
                        'accent-red': '#EF4444',   // Red-500
                    },
                    fontFamily: {
                        // Use Geist font families - nice and skinny
                        sans: ['Geist UltraLight', 'system-ui', 'sans-serif'],
                        mono: ['Geist Mono', 'ui-monospace', 'monospace'],
                        thin: ['Geist UltraLight', 'Geist', 'system-ui', 'sans-serif'],
                    },
                    fontWeight: {
                        hairline: '100',
                        thin: '200',
                        light: '300',
                    },
                    borderRadius: {
                        'lg': '0.5rem',
                        'md': '0.375rem',
                        'xl': '0.75rem',
                    }
                }
            }
        }
    </script>
    <style>
        /* Register custom property for smooth animation */
        @property --angle {
          syntax: '<angle>';
          initial-value: 0deg;
          inherits: false;
        }

        @keyframes spin {
          to {
            --angle: 360deg;
          }
        }

        /* Add position relative for pseudo-element positioning */
        .browser-column {
          position: relative;
        }

        /* Style for the animated border pseudo-element */
        .browser-column::before {
          content: '';
          position: absolute;
          inset: -2px; /* Adjust thickness of the border glow */
          z-index: -1; /* Position behind the main element */
          border-radius: inherit; /* Match parent's rounded corners */
          background: conic-gradient(
            from var(--angle),
            /* Use theme colors, adjust transparency as needed */
            theme('colors.accent-green' / 0),
            theme('colors.accent-green' / 1),
            theme('colors.accent-green' / 0) 60% /* Adjust fade point */
          );
          opacity: 0; /* Hidden by default */
          transition: opacity 0.4s ease-in-out;
        }

        /* Style when agent is running */
        .browser-column.is-running::before {
          opacity: 0.8; /* Make it visible, adjust subtlety */
          animation: spin 3s linear infinite;
        }

        /* Custom scrollbar styles for light/dark modes */
        ::-webkit-scrollbar {
            width: 8px;
            height: 8px;
        }
        ::-webkit-scrollbar-track {
            background: theme('colors.light-secondary-bg');
            border-radius: 4px;
        }
        .dark ::-webkit-scrollbar-track {
            background: theme('colors.dark-secondary-bg');
        }
        ::-webkit-scrollbar-thumb {
            background: theme('colors.light-border');
            border-radius: 4px;
            border: 2px solid theme('colors.light-secondary-bg'); /* Creates padding around thumb */
        }
        .dark ::-webkit-scrollbar-thumb {
            background: theme('colors.dark-border');
            border-color: theme('colors.dark-secondary-bg');
        }
        ::-webkit-scrollbar-thumb:hover {
            background: theme('colors.light-hover-border');
        }
        .dark ::-webkit-scrollbar-thumb:hover {
            background: theme('colors.dark-hover-border');
        }
        .auto-scroll-toggle:checked + div {
            /* Use a neutral gray or black for checked state in B&W */
            background-color: theme('colors.accent-green'); /* Use accent for clarity */
        }
        .auto-scroll-toggle:checked + div .dot {
            transform: translateX(1.25rem); /* Adjust based on w-10 */
        }

        /* Basic styles for theme toggle icons */
        .theme-icon {
             width: 1.25rem; /* Size matches other header icons */
             height: 1.25rem;
             stroke-width: 1.5;
        }
    </style>
</head>
<body class="font-light bg-light-bg text-light-text dark:bg-dark-bg dark:text-dark-text font-sans flex flex-col h-screen overflow-hidden transition-colors duration-200">
    <!-- Header -->
    <header class="bg-light-secondary-bg dark:bg-dark-secondary-bg border-b border-light-border dark:border-dark-border text-light-text dark:text-dark-text p-3 flex justify-between items-center flex-shrink-0 rounded-b-none">
        <h1 class="text-lg font-mono font-semibold flex items-center">
            <img src="https://trynia.ai/favicon.ico" alt="NIA Favicon" class="h-6 w-6 mr-2 inline-block align-middle"> <!-- Increased size -->
            <span class="font-sans"><a href="https://trynia.ai" target="_blank" class="hover:underline">NIA Control Center</a></span> <!-- Applied font-sans -->
        </h1>
        <div class="flex items-center space-x-4">
            <!-- Browser Navigation Buttons -->
            <div class="flex space-x-2">
                <button id="back-button" class="bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-3 py-1 transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                    ← Back
                </button>
                <button id="forward-button" class="bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-3 py-1 transition-all duration-300 disabled:opacity-50 disabled:cursor-not-allowed" disabled>
                    Forward →
                </button>
            </div>
            <!-- Agent Control Buttons -->
            <div class="flex space-x-2">
                <!-- Style buttons with black/white/gray -->
                <button id="pause-agent-btn" class="bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-3 py-1 transition-all duration-300 disabled:opacity-50">
                    ⏸️ Pause
                </button>
                <button id="resume-agent-btn" class="bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-3 py-1 transition-all duration-300 disabled:opacity-50">
                    ▶️ Resume
                </button>
                <button id="stop-agent-btn" class="bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-3 py-1 transition-all duration-300 disabled:opacity-50">
                    ⏹️ Stop
                </button>
            </div>

            <!-- View Mode Toggle -->
            <div class="flex items-center">
                <span class="mr-2 text-xs">View:</span>
                <button id="view-toggle" class="bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-3 py-1 transition-all duration-300">
                    <span class="separated-label">Split</span>
                    <span class="joined-label hidden">Joined</span>
                </button>
            </div>

            <!-- Auto-scroll Toggle -->
            <label class="flex items-center cursor-pointer">
                <span class="text-xs mr-2">Scroll:</span>
                <div class="relative">
                    <input type="checkbox" id="auto-scroll-toggle" class="sr-only auto-scroll-toggle" checked>
                    <div class="block bg-light-border dark:bg-dark-border w-10 h-5 rounded-full transition-colors duration-300"></div>
                    <div class="dot absolute left-0.5 top-0.5 bg-white dark:bg-gray-300 w-4 h-4 rounded-full transition-transform duration-300 transform translate-x-0"></div>
                </div>
            </label>

            <!-- Theme Toggle Button -->
            <button id="theme-toggle" type="button" class="text-light-secondary-text dark:text-dark-secondary-text hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg focus:outline-none rounded-lg text-sm p-1.5">
                <svg id="theme-toggle-dark-icon" class="hidden theme-icon" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path></svg>
                <svg id="theme-toggle-light-icon" class="hidden theme-icon" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" fill-rule="evenodd" clip-rule="evenodd"></path></svg>
            </button>
        </div>
    </header>

    <!-- Main Content Area -->
    <main id="separated-view" class="container mx-auto px-4 max-w-full flex-grow grid grid-cols-1 md:grid-cols-2 gap-4 py-4 overflow-hidden">
        <!-- Browser View Column -->
        <div class="browser-column bg-light-secondary-bg dark:bg-dark-secondary-bg border border-light-border dark:border-dark-border rounded-lg flex flex-col overflow-hidden h-full shadow-sm">
             <div class="log-header bg-light-secondary-bg dark:bg-dark-secondary-bg border-b border-light-border dark:border-dark-border p-2 flex justify-between items-center text-sm font-medium flex-shrink-0 rounded-t-lg">
                <h2 class="text-light-secondary-text dark:text-dark-secondary-text font-semibold">🌐 Browser Agent View (Interactive)</h2> <!-- Slightly darker text for header -->
            </div>
            <div class="bg-light-secondary-bg dark:bg-dark-secondary-bg px-3 py-2 border-t border-light-border dark:border-dark-border">
                <div id="url-task-info" class="text-xs font-mono">
                    <div id="current-url" class="truncate">
                        <span class="text-light-secondary-text dark:text-dark-secondary-text font-semibold">URL:</span>
                        <a id="url-display" href="#" target="_blank" class="text-light-text dark:text-dark-text hover:underline"></a>
                    </div>
                    <div id="current-task" class="truncate">
                        <span class="text-light-secondary-text dark:text-dark-secondary-text font-semibold">Task:</span>
                        <span id="task-display" class="text-light-text dark:text-dark-text"></span>
                    </div>
                </div>
            </div>
            <div id="browser-view-container" class="flex-grow overflow-auto p-1 bg-light-secondary-bg dark:bg-dark-secondary-bg flex items-center justify-center rounded-b-lg">
                 <img id="browser-view-img" src="" alt="Browser Agent View (Interactive)" class="max-w-full max-h-full object-contain border border-light-border dark:border-dark-border cursor-crosshair shadow-inner rounded-md" tabindex="0"/>
            </div>
        </div>

        <!-- Log Columns Container -->
        <div class="logs-wrapper flex flex-col gap-4 overflow-hidden h-full">
            <!-- Agent & Status Logs -->
            <div class="log-column bg-light-secondary-bg dark:bg-dark-secondary-bg border border-light-border dark:border-dark-border rounded-lg flex flex-col overflow-hidden flex-1 shadow-sm">
                 <div class="log-header bg-light-secondary-bg dark:bg-dark-secondary-bg border-b border-light-border dark:border-dark-border p-2 flex justify-between items-center text-sm font-medium flex-shrink-0 rounded-t-lg">
                    <h2 class="text-light-secondary-text dark:text-dark-secondary-text font-semibold">🚦 Agent & Status</h2>
                    <button class="copy-button bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-2 py-0.5" data-target="agent-log-container">Copy</button>
                </div>
                <div id="agent-log-container" class="log-container flex-grow overflow-y-auto p-3 font-mono text-xs leading-relaxed text-light-text dark:text-dark-text rounded-b-lg"></div> <!-- Ensure log text is black -->
            </div>
            <!-- Console Logs -->
            <div class="log-column bg-light-secondary-bg dark:bg-dark-secondary-bg border border-light-border dark:border-dark-border rounded-lg flex flex-col overflow-hidden flex-1 shadow-sm">
                 <div class="log-header bg-light-secondary-bg dark:bg-dark-secondary-bg border-b border-light-border dark:border-dark-border p-2 flex justify-between items-center text-sm font-medium flex-shrink-0 rounded-t-lg">
                    <h2 class="text-light-secondary-text dark:text-dark-secondary-text font-semibold">🖥️ Console</h2>
                    <button class="copy-button bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-2 py-0.5" data-target="console-log-container">Copy</button>
                </div>
                <div id="console-log-container" class="log-container flex-grow overflow-y-auto p-3 font-mono text-xs leading-relaxed text-light-text dark:text-dark-text rounded-b-lg"></div> <!-- Ensure log text is black -->
            </div>
            <!-- Network Activity -->
            <div class="log-column bg-light-secondary-bg dark:bg-dark-secondary-bg border border-light-border dark:border-dark-border rounded-lg flex flex-col overflow-hidden flex-1 shadow-sm">
                 <div class="log-header bg-light-secondary-bg dark:bg-dark-secondary-bg border-b border-light-border dark:border-dark-border p-2 flex justify-between items-center text-sm font-medium flex-shrink-0 rounded-t-lg">
                    <h2 class="text-light-secondary-text dark:text-dark-secondary-text font-semibold">↔️ Network (XHR/Fetch)</h2>
                    <button class="copy-button bg-light-bg dark:bg-dark-bg hover:bg-light-hover-bg dark:hover:bg-dark-hover-bg text-light-text dark:text-dark-text text-xs border border-light-border dark:border-dark-border hover:border-light-hover-border dark:hover:border-dark-hover-border rounded-md px-2 py-0.5" data-target="network-log-container">Copy</button>
                </div>
                <div id="network-log-container" class="log-container flex-grow overflow-y-auto p-3 font-mono text-xs leading-relaxed text-light-text dark:text-dark-text rounded-b-lg"></div> <!-- Ensure log text is black -->
            </div>
        </div> <!-- End logs-wrapper -->
    </main>

    <!-- Socket.IO Client Script -->
    <script>
        // Tab ID for this dashboard instance
        const tabId = Date.now().toString() + Math.random().toString(36).substring(2, 8);
        
        // --- Theme Handling --- V
        const themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon');
        const themeToggleLightIcon = document.getElementById('theme-toggle-light-icon');
        const themeToggleButton = document.getElementById('theme-toggle');

        // Function to apply the theme (sets class on <html> and updates icon)
        function applyTheme(theme) {
            if (theme === 'dark') {
                document.documentElement.classList.add('dark');
                themeToggleLightIcon.classList.remove('hidden');
                themeToggleDarkIcon.classList.add('hidden');
                localStorage.setItem('color-theme', 'dark');
            } else {
                document.documentElement.classList.remove('dark');
                themeToggleDarkIcon.classList.remove('hidden');
                themeToggleLightIcon.classList.add('hidden');
                localStorage.setItem('color-theme', 'light');
            }
        }

        // Determine initial theme on page load
        const savedTheme = localStorage.getItem('color-theme');
        const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;

        if (savedTheme) {
            applyTheme(savedTheme);
        } else {
            applyTheme(prefersDark ? 'dark' : 'light');
        }

        // Add listener for the theme toggle button
        themeToggleButton.addEventListener('click', () => {
            const currentTheme = localStorage.getItem('color-theme') || (prefersDark ? 'dark' : 'light');
            applyTheme(currentTheme === 'dark' ? 'light' : 'dark');
        });
        // --- Theme Handling --- ^

        console.log('Initializing dashboard script...');

        const socket = io();

        socket.on('connect', () => {
            console.log('SocketIO connected! Socket ID:', socket.id);
        });

        socket.on('connect_error', (error) => {
            console.error('SocketIO connection error:', error);
        });

        socket.on('disconnect', (reason) => {
            console.warn('SocketIO disconnected! Reason:', reason);
        });

        // DOM Elements
        const agentLogEl = document.getElementById('agent-log-container');
        const consoleLogEl = document.getElementById('console-log-container');
        const networkLogEl = document.getElementById('network-log-container');
        const browserViewImg = document.getElementById('browser-view-img');
        const browserColumnEl = document.querySelector('.browser-column'); // Get browser column element
        const urlDisplayEl = document.getElementById('url-display');
        const taskDisplayEl = document.getElementById('task-display');

        console.log('Browser view image element:', browserViewImg ? 'Found' : 'Not found');

        // Auto-scroll toggle
        const autoScrollToggle = document.getElementById('auto-scroll-toggle');

        // Helper to append a log line to a container
        function appendLog(el, text) {
            if (!el) {
                console.error("Log element not found, cannot append:", text);
                return;
            }
            const line = document.createElement('div');
            line.textContent = text;
            el.appendChild(line);
            // Keep the log length reasonable
            if (el.children.length > 2000) {
                el.firstChild.remove();
            }
            if (autoScrollToggle.checked) {
                el.scrollTop = el.scrollHeight;
            }
        }

        // Receive log messages
        socket.on('log_message', (payload) => {
            if (!payload) return;
            const { data, type } = payload;
            switch (type) {
                case 'console':
                    appendLog(consoleLogEl, data);
                    break;
                case 'network':
                    appendLog(networkLogEl, data);
                    break;
                case 'agent':
                case 'status': // fall-through – status also in agent column
                default:
                    appendLog(agentLogEl, data);
                    break;
            }
        });

        // Receive browser view updates
        socket.on('browser_update', (payload) => {
            if (!payload || !payload.data) {
                if (browserViewImg) browserViewImg.src = ''; // Clear image
                return;
            }
            if (!browserViewImg) {
                console.error('browserViewImg element not found when trying to update');
                return;
            }
            try {
                const previousSrc = browserViewImg.src;
                if (payload.data !== previousSrc) {
                    browserViewImg.src = payload.data;
                }
                browserViewImg.onload = () => {}; // No need to log success every time
                browserViewImg.onerror = (error) => {
                    console.error('Browser view image failed to load:', error);
                };
            } catch (error) {
                console.error('Error setting browserViewImg.src:', error);
            }
        });

        // --- Input Event Handling ---
        if (browserViewImg) {
            function getScaledCoordinates(event) {
                if (!browserViewImg.naturalWidth || !browserViewImg.naturalHeight || !browserViewImg.clientWidth || !browserViewImg.clientHeight) {
                    return null;
                }
                const rect = browserViewImg.getBoundingClientRect();
                const scaleX = browserViewImg.naturalWidth / browserViewImg.clientWidth;
                const scaleY = browserViewImg.naturalHeight / browserViewImg.clientHeight;
                const x = Math.max(0, Math.min(browserViewImg.naturalWidth, Math.round((event.clientX - rect.left) * scaleX)));
                const y = Math.max(0, Math.min(browserViewImg.naturalHeight, Math.round((event.clientY - rect.top) * scaleY)));
                return { x, y };
            }

            browserViewImg.addEventListener('click', (event) => {
                const coords = getScaledCoordinates(event);
                if (!coords) return;
                const buttonName = event.button === 0 ? 'left' : event.button === 1 ? 'middle' : 'right';
                const inputData = { type: 'click', details: { x: coords.x, y: coords.y, button: buttonName, clickCount: event.detail } };
                console.debug("Emitting browser click:", inputData.details);
                socket.emit('browser_input', inputData);
                event.preventDefault();
                browserViewImg.focus();
            });

            browserViewImg.addEventListener('wheel', (event) => {
                const coords = getScaledCoordinates(event);
                const eventCoords = coords || { x: 0, y: 0 };
                const inputData = { type: 'scroll', details: { x: eventCoords.x, y: eventCoords.y, deltaX: event.deltaX, deltaY: event.deltaY } };
                console.debug("Emitting browser scroll:", inputData.details);
                socket.emit('browser_input', inputData);
                event.preventDefault();
            });

            browserViewImg.addEventListener('keydown', (event) => {
                const inputData = { type: 'keydown', details: { key: event.key, code: event.code, altKey: event.altKey, ctrlKey: event.ctrlKey, metaKey: event.metaKey, shiftKey: event.shiftKey } };
                console.debug(`KeyDown: Key=${event.key}, Code=${event.code}`);
                socket.emit('browser_input', inputData);
                const nonModifierKeyPressed = !event.metaKey && !event.ctrlKey && !event.altKey;
                const isProblematicKey = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' ', 'Tab', 'Enter', 'Backspace', 'Delete', 'Home', 'End', 'PageUp', 'PageDown'].includes(event.key);
                if (nonModifierKeyPressed && isProblematicKey) {
                    event.preventDefault();
                }
            });

            browserViewImg.addEventListener('keyup', (event) => {
                 const inputData = { type: 'keyup', details: { key: event.key, code: event.code, altKey: event.altKey, ctrlKey: event.ctrlKey, metaKey: event.metaKey, shiftKey: event.shiftKey } };
                 console.debug(`KeyUp: Key=${event.key}, Code=${event.code}`);
                 socket.emit('browser_input', inputData);
                 const nonModifierKeyPressed = !event.metaKey && !event.ctrlKey && !event.altKey;
                 const isProblematicKey = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', ' ', 'Tab', 'Enter', 'Backspace', 'Delete', 'Home', 'End', 'PageUp', 'PageDown'].includes(event.key);
                 if (nonModifierKeyPressed && isProblematicKey) {
                    event.preventDefault();
                 }
            });
        }

        // View toggle
        const viewToggleBtn = document.getElementById('view-toggle');
        const separatedView = document.getElementById('separated-view');
        let joinedMode = false;
        viewToggleBtn.addEventListener('click', () => {
            joinedMode = !joinedMode;
            const browserColumn = separatedView.querySelector('.browser-column');
            const logsWrapper = separatedView.querySelector('.logs-wrapper');
            const separatedLabel = viewToggleBtn.querySelector('.separated-label');
            const joinedLabel = viewToggleBtn.querySelector('.joined-label');

            if (joinedMode) {
                separatedView.classList.remove('md:grid-cols-2');
                separatedView.classList.add('grid-rows-[auto,1fr]');
                browserColumn.classList.add('md:col-span-1');
                logsWrapper.classList.add('md:col-span-1');
                joinedLabel.classList.remove('hidden');
                separatedLabel.classList.add('hidden');
                console.log("Switched to Joined View");
            } else {
                separatedView.classList.remove('grid-rows-[auto,1fr]');
                separatedView.classList.add('md:grid-cols-2');
                joinedLabel.classList.add('hidden');
                separatedLabel.classList.remove('hidden');
                console.log("Switched to Split View");
            }
        });

        // Copy to clipboard buttons
        document.querySelectorAll('.copy-button').forEach(btn => {
            btn.addEventListener('click', () => {
                const targetId = btn.getAttribute('data-target');
                const targetEl = document.getElementById(targetId);
                if (!targetEl) return;
                const text = Array.from(targetEl.children).map(node => node.textContent).join('\n');
                navigator.clipboard.writeText(text).then(() => {
                    const originalText = btn.textContent;
                    btn.textContent = 'Copied!';
                    btn.classList.add('bg-accent-green', 'text-white', 'dark:text-gray-900'); // Feedback style
                    setTimeout(() => {
                        btn.textContent = originalText;
                        btn.classList.remove('bg-accent-green', 'text-white', 'dark:text-gray-900');
                    }, 1500);
                }).catch((err) => {
                    console.error('Failed to copy:', err);
                    const originalText = btn.textContent;
                    btn.textContent = 'Failed';
                    btn.classList.add('bg-accent-red', 'text-white', 'dark:text-gray-900'); // Feedback style
                    setTimeout(() => {
                        btn.textContent = originalText;
                        btn.classList.remove('bg-accent-red', 'text-white', 'dark:text-gray-900');
                     }, 2000);
                });
            });
        });

        // Agent control buttons
        const pauseAgentBtn = document.getElementById('pause-agent-btn');
        const resumeAgentBtn = document.getElementById('resume-agent-btn');
        const stopAgentBtn = document.getElementById('stop-agent-btn');

        pauseAgentBtn?.addEventListener('click', () => {
            console.log('Pause agent button clicked');
            socket.emit('agent_control', { action: 'pause' });
            appendLog(agentLogEl, "⏸️ Pause agent requested");
        });

        resumeAgentBtn?.addEventListener('click', () => {
            console.log('Resume agent button clicked');
            socket.emit('agent_control', { action: 'resume' });
            appendLog(agentLogEl, "▶️ Resume agent requested");
        });

        stopAgentBtn?.addEventListener('click', () => {
            console.log('Stop agent button clicked');
            socket.emit('agent_control', { action: 'stop' });
            appendLog(agentLogEl, "⏹️ Stop agent requested");
        });

        // Receive agent state updates
        socket.on('agent_state', (payload) => {
            if (payload && payload.state && pauseAgentBtn && resumeAgentBtn && stopAgentBtn && browserColumnEl) {
                const { paused, stopped } = payload.state;
                const isRunning = !paused && !stopped;

                pauseAgentBtn.disabled = paused || stopped;
                resumeAgentBtn.disabled = !paused || stopped;
                stopAgentBtn.disabled = stopped;

                // Toggle running indicator class on browser column
                if (isRunning) {
                    browserColumnEl.classList.add('is-running');
                } else {
                    browserColumnEl.classList.remove('is-running');
                }

                const stateMessage = stopped ? "⏹️ Agent is STOPPED" : paused ? "⏸️ Agent is PAUSED" : "▶️ Agent is RUNNING";
                const lastLog = agentLogEl?.lastChild?.textContent;
                if (!lastLog || !lastLog.includes(stateMessage)) {
                    appendLog(agentLogEl, stateMessage);
                }
            }
        });

        // Fetch URL and task information from the server
        function fetchUrlAndTask() {
            fetch('/get_url_task')
                .then(response => {
                    if (!response.ok) {
                        throw new Error('Network response was not ok: ' + response.statusText);
                    }
                    return response.json();
                })
                .then(data => {
                    
                    // Update the URL display
                    if (urlDisplayEl && data.url) {
                        urlDisplayEl.textContent = data.url || '';
                    }
                    
                    // Update the task display
                    if (taskDisplayEl && data.task) {
                        taskDisplayEl.textContent = data.task || '';
                    }
                })
                .catch(error => {
                    console.error("Error fetching URL/task:", error);
                });
        }

        // Register this tab with server and handle refresh requests
        document.addEventListener('DOMContentLoaded', function() {
            // Tell server this tab is active
            socket.emit('register_dashboard_tab', { tabId: tabId });
            
            // Fetch URL and task data initially
            fetchUrlAndTask();
            
            // Set up periodic refresh of URL and task data
            setInterval(fetchUrlAndTask, 5000); // Refresh every 5 seconds
            
            // Listen for refresh requests
            socket.on('refresh_dashboard', function(data) {
                console.log('Received refresh request from server');
                // Reload the page
                window.location.reload();
            });
            
            // Set ping interval to keep tab registration active
            setInterval(function() {
                socket.emit('dashboard_ping', { tabId: tabId });
            }, 5000); // Ping every 5 seconds
            
            // Handle page visibility changes
            document.addEventListener('visibilitychange', function() {
                if (document.visibilityState === 'visible') {
                    socket.emit('dashboard_visible', { tabId: tabId });
                    // Also refresh URL and task when tab becomes visible
                    fetchUrlAndTask();
                }
            });
        });

        console.log('Dashboard script initialised.');
    </script>
</body>
</html>
