<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PlanAI Dispatcher Dashboard</title>
    <style>
        :root {
            --bg-color: #ffffff;
            --text-color: #333333;
            --header-color: #2c3e50;
            --task-list-bg: #f9f9f9;
            --task-item-bg: #ffffff;
            --border-color: #dddddd;
        }

        [data-theme="dark"] {
            --bg-color: #1a1a1a;
            --text-color: #e0e0e0;
            --header-color: #61dafb;
            --task-list-bg: #2a2a2a;
            --task-item-bg: #333333;
            --border-color: #444444;
        }

        body {
            font-family: Arial, sans-serif;
            line-height: 1.6;
            color: var(--text-color);
            background-color: var(--bg-color);
            max-width: 800px;
            margin: 0 auto;
            padding: 20px;
            transition: background-color 0.3s ease, color 0.3s ease;
        }

        h1,
        h2 {
            color: var(--header-color);
        }

        .task-list {
            background-color: var(--task-list-bg);
            border: 1px solid var(--border-color);
            border-radius: 4px;
            padding: 10px;
            margin-bottom: 20px;
        }

        .task-item {
            background-color: var(--task-item-bg);
            border: 1px solid var(--border-color);
            border-radius: 4px;
            padding: 10px;
            margin-bottom: 10px;
        }

        .task-item:last-child {
            margin-bottom: 0;
        }

        #theme-toggle {
            position: fixed;
            top: 20px;
            right: 20px;
            padding: 10px;
            background-color: var(--header-color);
            color: var(--bg-color);
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }

        .task-item {
            cursor: pointer;
        }

        .provenance-info {
            display: none;
            background-color: var(--task-list-bg);
            border: 1px solid var(--border-color);
            border-radius: 4px;
            padding: 10px;
            margin-top: 10px;
        }

        .provenance-info h4 {
            margin-top: 0;
        }

        .provenance-info ul {
            padding-left: 20px;
        }

        .input-provenance-item {
            margin-bottom: 15px;
            border-left: 2px solid var(--border-color);
            padding-left: 10px;
        }

        .nested-object {
            margin-left: 20px;
        }
    </style>
</head>


<body>
    <button id="theme-toggle">Toggle Dark Mode</button>
    <h1>PlanAI Dispatcher Dashboard</h1>
    <button id="quit-button">Quit</button>

    <h2>Queued Tasks</h2>
    <div id="queued-tasks" class="task-list"></div>

    <h2>Active Tasks</h2>
    <div id="active-tasks" class="task-list"></div>

    <h2>Completed Tasks</h2>
    <div id="completed-tasks" class="task-list"></div>

    <script>
        let eventSource;
        let reconnectAttempt = 0;

        function setupEventSource() {
            eventSource = new EventSource("/stream");

            eventSource.onmessage = function (event) {
                const data = JSON.parse(event.data);
                updateTaskLists(data);
                reconnectAttempt = 0;
            };

            eventSource.onerror = function (error) {
                eventSource.close();
                const timeout = Math.min(16000, Math.pow(2, reconnectAttempt) * 1000);
                reconnectAttempt++;
                setTimeout(setupEventSource, timeout);
            };
        }

        setupEventSource();

        function updateTaskLists(data) {
            updateTaskList('queued-tasks', data.queued);
            updateTaskList('active-tasks', data.active);
            updateTaskList('completed-tasks', data.completed);
        }

        function updateTaskList(elementId, tasks) {
            const element = document.getElementById(elementId);
            tasks.forEach(task => {
                let taskElement = document.getElementById(`task-${task.id}`);
                if (!taskElement) {
                    taskElement = document.createElement('div');
                    taskElement.id = `task-${task.id}`;
                    taskElement.className = 'task-item';
                    element.appendChild(taskElement);
                }
                taskElement.innerHTML = `
                <div class="task-item" onclick="toggleProvenance('${task.id}')">
                    <strong>ID:</strong> ${task.id}<br>
                    <strong>Type:</strong> ${task.type}<br>
                    <strong>Worker:</strong> ${task.worker}
                    <div id="provenance-${task.id}" class="provenance-info">
                        <h4>Provenance:</h4>
                        <ul>
                            ${task.provenance.map(p => `<li>${p}</li>`).join('')}
                        </ul>
                        <h4>Input Provenance:</h4>
                        <ul>
                            ${task.input_provenance.map(inputTask => `
                                <li class="input-provenance-item">
                                    ${renderObject(inputTask)}
                                </li>
                            `).join('')}
                        </ul>
                    </div>
                </div>
            `;
            });

            // Remove tasks that no longer exist
            Array.from(element.children).forEach(child => {
                const taskId = child.id.replace('task-', '');
                if (!tasks.some(task => task.id === taskId)) {
                    element.removeChild(child);
                }
            });
        }

        function renderObject(obj, indent = '') {
            return Object.entries(obj).map(([key, value]) => {
                if (value === null) return `${indent}<strong>${key}:</strong> null`;
                if (typeof value === 'object') {
                    return `
                        ${indent}<strong>${key}:</strong>
                        <div class="nested-object">
                            ${renderObject(value, indent + '  ')}
                        </div>
                    `;
                }
                return `${indent}<strong>${key}:</strong> ${JSON.stringify(value)}`;
            }).join('<br>');
        }

        function toggleProvenance(taskId) {
            const provenanceElement = document.getElementById(`provenance-${taskId}`);
            if (provenanceElement) {
                provenanceElement.style.display = provenanceElement.style.display === 'none' ? 'block' : 'none';
            }
        }


        document.getElementById('quit-button').addEventListener('click', function () {
            fetch('/quit', { method: 'POST' })
                .then(response => response.json())
                .then(data => {
                    if (data.status === 'ok') {
                        alert('Quit signal sent. The application will shut down soon.');
                    }
                });
        });
        // Theme toggle functionality
        const themeToggle = document.getElementById('theme-toggle');
        const prefersDarkScheme = window.matchMedia("(prefers-color-scheme: dark)");

        function setTheme(theme) {
            document.body.setAttribute('data-theme', theme);
            localStorage.setItem('theme', theme);
        }

        // Check for saved theme preference or use the system preference
        const savedTheme = localStorage.getItem('theme');
        if (savedTheme) {
            setTheme(savedTheme);
        } else if (prefersDarkScheme.matches) {
            setTheme('dark');
        }

        // Toggle theme when button is clicked
        themeToggle.addEventListener('click', () => {
            const currentTheme = document.body.getAttribute('data-theme');
            setTheme(currentTheme === 'dark' ? 'light' : 'dark');
        });
    </script>
</body>

</html>