<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>任务详情 - AI 开发任务监控</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }

        html, body {
            height: 100%;
            overflow: hidden;
        }

        body {
            font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
            background: #f5f5f5;
            display: flex;
            flex-direction: column;
        }

        .container {
            max-width: 1600px;
            width: 100%;
            margin: 0 auto;
            padding: 15px 20px;
            height: calc(100vh - 30px);
            display: flex;
            flex-direction: column;
        }

        .header {
            background: white;
            padding: 15px 20px;
            border-radius: 8px;
            margin-bottom: 15px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
            flex-shrink: 0;
        }

        .header-top {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
        }

        .header-left {
            display: flex;
            align-items: center;
            gap: 15px;
            flex: 1;
        }

        .back-link {
            color: #3b82f6;
            text-decoration: none;
            font-size: 13px;
            white-space: nowrap;
        }

        .back-link:hover {
            text-decoration: underline;
        }

        .header h1 {
            font-size: 20px;
            color: #333;
            font-weight: 600;
        }

        .header-actions {
            display: flex;
            gap: 10px;
            align-items: center;
        }

        .btn {
            padding: 8px 16px;
            border: none;
            border-radius: 6px;
            font-size: 13px;
            cursor: pointer;
            transition: background 0.2s;
            white-space: nowrap;
        }

        .btn-danger {
            background: #ef4444;
            color: white;
        }

        .btn-danger:hover {
            background: #dc2626;
        }

        .btn-warning {
            background: #f59e0b;
            color: white;
        }

        .btn-warning:hover {
            background: #d97706;
        }

        .task-info {
            display: grid;
            grid-template-columns: repeat(6, 1fr);
            gap: 10px;
        }

        .info-card {
            background: #f9fafb;
            padding: 10px 12px;
            border-radius: 6px;
            border: 1px solid #e5e7eb;
        }

        .info-card label {
            display: block;
            font-size: 11px;
            color: #6b7280;
            margin-bottom: 4px;
            text-transform: uppercase;
            letter-spacing: 0.5px;
        }

        .info-card .value {
            font-size: 13px;
            color: #111827;
            font-weight: 500;
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }

        .terminal-wrapper {
            flex: 1;
            min-height: 0;
            background: #1e1e1e;
            border-radius: 8px;
            box-shadow: 0 4px 6px rgba(0,0,0,0.3);
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }

        .terminal-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 12px 16px;
            border-bottom: 1px solid #333;
            background: #252526;
            flex-shrink: 0;
        }

        .terminal-title {
            color: #fff;
            font-size: 13px;
            font-weight: 600;
        }

        .terminal-status {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .status-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: #6b7280;
        }

        .status-dot.active {
            background: #10b981;
            animation: pulse 2s infinite;
        }

        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }

        .status-text {
            color: #9ca3af;
            font-size: 12px;
        }

        #terminal-output {
            flex: 1;
            overflow-y: auto;
            font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
            font-size: 12px;
            line-height: 1.4;
            padding: 12px 16px;
        }

        #terminal-output::-webkit-scrollbar {
            width: 8px;
        }

        #terminal-output::-webkit-scrollbar-track {
            background: #1e1e1e;
        }

        #terminal-output::-webkit-scrollbar-thumb {
            background: #4b5563;
            border-radius: 4px;
        }

        #terminal-output::-webkit-scrollbar-thumb:hover {
            background: #6b7280;
        }

        .log-line {
            padding: 0;
            line-height: 1.3;
            white-space: pre-wrap;
            word-break: break-all;
            display: flex;
            align-items: flex-start;
        }

        .log-prefix {
            color: #9ca3af;
            font-size: 11px;
            flex-shrink: 0;
            margin-right: 8px;
            font-family: 'Menlo', 'Monaco', 'Courier New', monospace;
        }

        .log-prefix .INFO { color: #3b82f6; }
        .log-prefix .WARNING { color: #f59e0b; }
        .log-prefix .ERROR { color: #ef4444; }
        .log-prefix .DEBUG { color: #6b7280; }

        .log-line .message {
            color: #e5e7eb;
            flex: 1;
        }

        .loading {
            text-align: center;
            padding: 20px;
            color: #9ca3af;
            font-size: 13px;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .spinner {
            width: 32px;
            height: 32px;
            border: 3px solid #374151;
            border-top-color: #3b82f6;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin: 0 auto 12px;
        }

        .empty-state {
            text-align: center;
            padding: 30px;
            color: #6b7280;
            font-size: 13px;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <div class="header-top">
                <div class="header-left">
                    <a href="/dashboard" class="back-link">← 返回列表</a>
                    <h1 id="task-title">任务详情</h1>
                </div>
                <div class="header-actions" id="header-actions" style="display: none;">
                    <button class="btn btn-danger" id="cancel-btn" onclick="cancelTask()">取消任务</button>
                    <button class="btn btn-warning" id="retry-btn" onclick="retryTask()">重试任务</button>
                </div>
            </div>
            <div class="task-info" id="task-info">
                <div class="loading">
                    <div class="spinner"></div>
                    <div>加载中...</div>
                </div>
            </div>
        </div>

        <div class="terminal-wrapper">
            <div class="terminal-header">
                <div class="terminal-title">📋 实时日志</div>
                <div class="terminal-status">
                    <div class="status-dot" id="status-dot"></div>
                    <div class="status-text" id="status-text">连接中...</div>
                </div>
            </div>
            <div id="terminal-output">
                <div class="empty-state">等待日志...</div>
            </div>
        </div>
    </div>

    <script>
        const taskId = window.location.pathname.split('/').pop();
        let eventSource = null;
        let taskData = null;

        // 加载任务信息
        async function loadTaskInfo() {
            try {
                const response = await fetch(`/api/tasks/${taskId}`);
                const data = await response.json();
                taskData = data.task;

                // 更新标题
                document.getElementById('task-title').textContent = taskData.issue_title;

                // 更新任务信息
                const taskInfo = document.getElementById('task-info');
                taskInfo.innerHTML = `
                    <div class="info-card" title="${taskData.task_id}">
                        <label>任务 ID</label>
                        <div class="value">${taskData.task_id}</div>
                    </div>
                    <div class="info-card">
                        <label>Issue</label>
                        <div class="value">
                            <a href="${taskData.issue_url}" target="_blank" style="color: #3b82f6; text-decoration: none;">#${taskData.issue_number}</a>
                        </div>
                    </div>
                    <div class="info-card">
                        <label>状态</label>
                        <div class="value">${getStatusLabel(taskData.status)}</div>
                    </div>
                    <div class="info-card" title="${taskData.branch_name}">
                        <label>分支</label>
                        <div class="value">${taskData.branch_name}</div>
                    </div>
                    <div class="info-card">
                        <label>创建时间</label>
                        <div class="value">${formatTime(taskData.created_at)}</div>
                    </div>
                    <div class="info-card">
                        <label>执行时间</label>
                        <div class="value">${taskData.execution_time ? taskData.execution_time.toFixed(1) + 's' : '-'}</div>
                    </div>
                `;

                // 显示操作按钮
                const headerActions = document.getElementById('header-actions');
                const cancelBtn = document.getElementById('cancel-btn');
                const retryBtn = document.getElementById('retry-btn');

                if (taskData.status === 'running' || taskData.status === 'pending') {
                    headerActions.style.display = 'flex';
                    cancelBtn.style.display = 'inline-block';
                    retryBtn.style.display = 'none';
                } else if (taskData.status === 'failed') {
                    headerActions.style.display = 'flex';
                    cancelBtn.style.display = 'none';
                    retryBtn.style.display = 'inline-block';
                } else {
                    headerActions.style.display = 'none';
                }

            } catch (error) {
                console.error('加载任务信息失败:', error);
                document.getElementById('task-info').innerHTML = `
                    <div class="empty-state" style="grid-column: 1 / -1;">加载失败: ${error.message}</div>
                `;
            }
        }

        // 格式化时间
        function formatTime(dateStr) {
            const date = new Date(dateStr);
            const month = String(date.getMonth() + 1).padStart(2, '0');
            const day = String(date.getDate()).padStart(2, '0');
            const hours = String(date.getHours()).padStart(2, '0');
            const minutes = String(date.getMinutes()).padStart(2, '0');
            return `${month}-${day} ${hours}:${minutes}`;
        }

        // 获取状态标签
        function getStatusLabel(status) {
            const labels = {
                'pending': '⏳ 待处理',
                'running': '🔄 运行中',
                'completed': '✅ 已完成',
                'failed': '❌ 失败',
                'cancelled': '⏹️ 已取消',
            };
            return labels[status] || status;
        }

        // 连接实时日志流
        function connectLogStream() {
            const terminalOutput = document.getElementById('terminal-output');
            const statusDot = document.getElementById('status-dot');
            const statusText = document.getElementById('status-text');

            // 清空现有内容
            terminalOutput.innerHTML = '';

            // 创建 EventSource
            eventSource = new EventSource(`/api/tasks/${taskId}/logs/stream`);

            // 更新状态
            statusDot.classList.add('active');
            statusText.textContent = '实时接收中...';

            // 接收日志
            eventSource.onmessage = (event) => {
                const log = JSON.parse(event.data);
                appendLogToTerminal(log);
            };

            // 任务完成
            eventSource.addEventListener('done', (event) => {
                statusDot.classList.remove('active');
                statusText.textContent = '已完成';
                statusDot.style.background = '#10b981';
                eventSource.close();
                loadTaskInfo(); // 刷新任务信息
            });

            // 错误
            eventSource.addEventListener('error', (event) => {
                statusDot.classList.remove('active');
                statusText.textContent = '连接错误';
                statusDot.style.background = '#ef4444';
                eventSource.close();
            });

            // 连接错误
            eventSource.onerror = (error) => {
                console.error('EventSource error:', error);
                statusDot.classList.remove('active');
                statusText.textContent = '连接断开';
                statusDot.style.background = '#ef4444';
            };
        }

        // 添加日志到终端
        function appendLogToTerminal(log) {
            const terminalOutput = document.getElementById('terminal-output');

            // 移除空状态提示
            if (terminalOutput.querySelector('.empty-state')) {
                terminalOutput.innerHTML = '';
            }

            const timestamp = new Date(log.timestamp).toLocaleTimeString('zh-CN', { hour12: false });
            const logLine = document.createElement('div');
            logLine.className = 'log-line';
            logLine.innerHTML = `
                <span class="log-prefix">[${timestamp}] [${log.level}]</span>
                <span class="message">${escapeHtml(log.message)}</span>
            `;

            terminalOutput.appendChild(logLine);

            // 自动滚动到底部（使用 requestAnimationFrame 确保流畅）
            requestAnimationFrame(() => {
                terminalOutput.scrollTop = terminalOutput.scrollHeight;
            });
        }

        // HTML 转义
        function escapeHtml(text) {
            const div = document.createElement('div');
            div.textContent = text;
            return div.innerHTML;
        }

        // 取消任务
        async function cancelTask() {
            if (!confirm('确定要取消此任务吗？')) return;

            try {
                const response = await fetch(`/api/tasks/${taskId}/cancel`, { method: 'POST' });
                const data = await response.json();

                if (data.success) {
                    alert('任务已取消');
                    loadTaskInfo();
                } else {
                    alert('取消失败: ' + data.message);
                }
            } catch (error) {
                alert('取消失败: ' + error.message);
            }
        }

        // 重试任务
        async function retryTask() {
            if (!confirm('确定要重试此任务吗？')) return;

            try {
                const response = await fetch(`/api/tasks/${taskId}/retry`, { method: 'POST' });
                const data = await response.json();

                if (data.success) {
                    alert(data.message);
                    loadTaskInfo();
                    connectLogStream(); // 重新连接日志流
                } else {
                    alert('重试失败: ' + data.message);
                }
            } catch (error) {
                alert('重试失败: ' + error.message);
            }
        }

        // 初始化
        loadTaskInfo();
        connectLogStream();
    </script>
</body>
</html>
