<!DOCTYPE html>
<html lang="zh-CN" class="dark">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{{ title }}</title>

    <!-- Favicon -->
    <link rel="icon" type="image/svg+xml" href="/static/icon.svg">
    <link rel="apple-touch-icon" href="/static/icon.svg">

    <!-- Tailwind CSS (local) -->
    <script src="/static/js/vendor/tailwindcss.js"></script>
    <script>
        tailwind.config = {
            darkMode: 'class',
            theme: {
                extend: {
                    fontFamily: {
                        sans: ['DM Sans', '-apple-system', 'BlinkMacSystemFont', 'sans-serif'],
                        mono: ['JetBrains Mono', 'SF Mono', 'Consolas', 'monospace'],
                    },
                    colors: {
                        surface: {
                            base: '#0b0e14',
                            raised: '#111620',
                            overlay: '#171d2b',
                            muted: '#1e2636',
                        }
                    },
                }
            }
        }
    </script>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=DM+Sans:ital,opsz,wght@0,9..40,300;0,9..40,400;0,9..40,500;0,9..40,600;0,9..40,700;1,9..40,400&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
    <style>
        ::-webkit-scrollbar { width: 6px; height: 6px; }
        ::-webkit-scrollbar-track { background: transparent; }
        ::-webkit-scrollbar-thumb { background: rgba(255,255,255,0.1); border-radius: 3px; }
        ::-webkit-scrollbar-thumb:hover { background: rgba(255,255,255,0.18); }
        ::selection { background: rgba(59,130,246,0.2); }

        .glow-line::after {
            content: '';
            position: absolute;
            bottom: -1px; left: 0; right: 0;
            height: 1px;
            background: linear-gradient(90deg, transparent, #3b82f6, transparent);
            opacity: 0.3;
        }

        .tab-active-dot::after {
            content: '';
            position: absolute;
            bottom: -1px; left: 50%;
            transform: translateX(-50%);
            width: 16px; height: 2px;
            border-radius: 1px;
            background: #3b82f6;
        }

        textarea::placeholder { white-space: pre-line; }
        select option { background: #111620; color: #e2e8f0; }

        @keyframes breathe {
            0%, 100% { opacity: 0.35; transform: scale(1); }
            50% { opacity: 0.1; transform: scale(1.5); }
        }

        /* Markdown styles */
        .md h1 { font-size: 1.7em; font-weight: 700; color: #e2e8f0; margin: 0.4em 0 0.3em; border-bottom: 1px solid rgba(255,255,255,0.06); padding-bottom: 6px; }
        .md h2 { font-size: 1.4em; font-weight: 600; color: #e2e8f0; margin: 0.5em 0 0.25em; border-bottom: 1px solid rgba(255,255,255,0.06); padding-bottom: 4px; }
        .md h3 { font-size: 1.2em; font-weight: 600; color: #e2e8f0; margin: 0.4em 0 0.2em; }
        .md h4 { font-size: 1.05em; font-weight: 600; color: #e2e8f0; margin: 0.35em 0 0.15em; }
        .md p { margin: 0.4em 0; color: #8494a7; line-height: 1.6; }
        .md ul { padding-left: 1.4em; margin: 0.3em 0; color: #8494a7; list-style-type: disc; }
        .md ol { padding-left: 1.4em; margin: 0.3em 0; color: #8494a7; list-style-type: decimal; }
        .md li { margin: 0.15em 0; line-height: 1.55; }
        .md li::marker { color: #e2e8f0; }
        .md li > ul, .md li > ol { margin: 0; padding-left: 1.2em; }
        .md strong { color: #e2e8f0; font-weight: 600; }
        .md em { color: #e2e8f0; }
        .md del, .md s { color: #506078; text-decoration: line-through; }
        .md code { font-family: 'JetBrains Mono', monospace; font-size: 0.85em; background: rgba(255,255,255,0.06); padding: 0.2em 0.45em; border-radius: 4px; color: #60a5fa; }
        .md pre { background: #0b0e14; border: 1px solid rgba(255,255,255,0.06); border-radius: 10px; padding: 14px 16px; margin: 0.6em 0; overflow-x: auto; }
        .md pre code { background: none; padding: 0; color: #e2e8f0; font-size: 0.85em; line-height: 1.55; }
        .md blockquote { border-left: 3px solid #3b82f6; margin: 0.6em 0; padding: 0.5em 1em; background: rgba(59,130,246,0.06); border-radius: 0 8px 8px 0; color: #8494a7; font-style: italic; }
        .md blockquote strong { font-style: normal; }
        .md a { color: #60a5fa; text-decoration: none; }
        .md a:hover { text-decoration: underline; }
        .md hr { border: none; border-top: 1px solid rgba(255,255,255,0.06); margin: 1.2em 0; }
        .md table { width: 100%; border-collapse: collapse; margin: 0.6em 0; border: 1px solid rgba(255,255,255,0.06); border-radius: 8px; overflow: hidden; }
        .md th { background: #171d2b; font-weight: 600; color: #e2e8f0; padding: 8px 12px; border: 1px solid rgba(255,255,255,0.06); text-align: left; }
        .md td { padding: 6px 12px; border: 1px solid rgba(255,255,255,0.06); color: #8494a7; }
        .md tr:nth-child(2n) { background: rgba(255,255,255,0.02); }
        .md > *:first-child { margin-top: 0; }
    </style>
</head>
<body class="bg-surface-base text-slate-200 font-sans h-screen flex flex-col overflow-hidden antialiased">

    <!-- ===== TOP BAR ===== -->
    <header class="glow-line relative flex items-center justify-between px-5 h-11 bg-surface-raised border-b border-white/[0.06] shrink-0 z-50">
        <div class="flex items-center gap-4">
            <div class="flex items-center gap-2">
                <div class="w-5 h-5 rounded-[5px] bg-gradient-to-br from-blue-500 to-violet-500 flex items-center justify-center text-xs font-bold text-white">M</div>
                <span class="text-[14px] font-semibold tracking-tight">MCP Feedback</span>
            </div>
            <div class="flex items-center gap-2.5 text-xs text-slate-500">
                <span class="hidden sm:inline font-mono text-xs text-slate-400 bg-surface-overlay px-2 py-0.5 rounded cursor-pointer hover:bg-blue-500/10 hover:text-blue-400 transition truncate max-w-[200px]">{{ project_directory }}</span>
                <span class="font-mono text-xs text-slate-400 bg-surface-overlay px-2 py-0.5 rounded cursor-pointer hover:bg-blue-500/10 hover:text-blue-400 transition">{{ session_id[:8] if session_id else '--' }}</span>
            </div>
        </div>
        <div id="connStatus" class="flex items-center gap-1.5 text-xs font-medium text-amber-400">
            <div id="connDot" class="relative w-[7px] h-[7px]">
                <div id="connDotInner" class="absolute inset-0 rounded-full bg-amber-400"></div>
                <div id="connDotPulse" class="absolute -inset-[3px] rounded-full bg-amber-400 opacity-30 animate-[breathe_2.5s_ease-in-out_infinite]"></div>
            </div>
            <span id="connText">连接中...</span>
        </div>
    </header>

    <!-- ===== TAB NAV ===== -->
    <nav class="flex items-center gap-0.5 px-5 py-2 bg-surface-base border-b border-white/[0.06] shrink-0" id="tabNav">
        <button class="tab-btn tab-active-dot relative px-4 py-2 text-[14px] font-medium rounded-full text-slate-200 bg-surface-overlay shadow-sm ring-1 ring-white/[0.06] transition-all"
                data-tab="workspace">工作区</button>
        <button class="tab-btn px-4 py-2 text-[14px] font-medium rounded-full text-slate-500 hover:text-slate-400 hover:bg-surface-overlay transition-all"
                data-tab="sessions">会话管理</button>
        <div class="w-px h-4 bg-white/[0.06] mx-1.5"></div>
        <button class="tab-btn px-4 py-2 text-[14px] font-medium rounded-full text-slate-500 hover:text-slate-400 hover:bg-surface-overlay transition-all"
                data-tab="settings">设定</button>
        <button class="tab-btn px-4 py-2 text-[14px] font-medium rounded-full text-slate-500 hover:text-slate-400 hover:bg-surface-overlay transition-all"
                data-tab="about">关于</button>
    </nav>

    <!-- ===== CONTENT AREA: flex-1, min-h-0 so children can fill ===== -->
    <div class="flex-1 min-h-0 flex flex-col">

        <!-- WORKSPACE: fixed left-right layout, always occupying the full area when visible -->
        <div id="page-workspace" class="page flex-1 min-h-0 flex flex-row p-4 sm:p-5 gap-4 overflow-hidden">
            <!-- AI Summary (left) -->
            <div class="flex-1 min-w-0 flex flex-col bg-surface-raised border border-white/[0.06] rounded-2xl overflow-hidden hover:border-white/[0.08] transition">
                <div class="flex items-center justify-between px-5 py-3.5 border-b border-white/[0.06] shrink-0">
                    <span class="text-[14px] font-semibold text-slate-300">AI 工作摘要</span>
                    <span id="newTag" class="text-[11px] font-bold uppercase tracking-wide text-white bg-gradient-to-r from-blue-500 to-violet-500 px-2.5 py-0.5 rounded-full shadow-[0_2px_8px_rgba(59,130,246,0.4)]">NEW</span>
                </div>
                <div id="summaryContent" class="flex-1 overflow-y-auto px-5 py-4 text-[15px] leading-relaxed md">{{ summary }}</div>
            </div>

            <!-- Feedback (right) -->
            <div class="flex-1 min-w-0 flex flex-col bg-surface-raised border border-white/[0.06] rounded-2xl overflow-hidden hover:border-white/[0.08] transition">
                <div class="flex items-center justify-between px-5 py-3.5 border-b border-white/[0.06] shrink-0">
                    <span class="text-[14px] font-semibold text-slate-300">提供反馈</span>
                </div>
                <div class="flex-1 min-h-0 p-3 flex flex-col gap-2">
                    <textarea id="feedbackText" class="flex-1 min-h-0 w-full bg-surface-base border border-white/[0.06] rounded-xl px-4 py-3 text-[15px] leading-relaxed text-slate-200 resize-none transition-all outline-none focus:border-blue-500/40 focus:shadow-[0_0_20px_rgba(59,130,246,0.12),inset_0_0_0_1px_rgba(59,130,246,0.4)] placeholder:text-slate-600"
                        placeholder="在这里输入你的反馈...&#10;&#10;按 Ctrl+Enter 快速提交&#10;按 Ctrl+V 粘贴剪贴板图片"></textarea>
                    <div id="imagePreview" class="hidden flex-wrap gap-2"></div>
                </div>
                <input type="file" id="imageInput" accept="image/*" multiple class="hidden">
                <div class="flex items-center justify-between shrink-0 px-4 pb-3">
                    <div class="flex items-center gap-2.5">
                        <button id="attachBtn" onclick="document.getElementById('imageInput').click()" class="flex items-center gap-1.5 text-xs font-medium text-slate-500 bg-surface-overlay border border-dashed border-white/[0.06] rounded-lg px-3.5 py-2 hover:text-blue-400 hover:border-blue-500/40 hover:bg-blue-500/[0.08] transition">
                            <svg class="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8"><rect x="3" y="3" width="18" height="18" rx="3"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="M21 15l-5-5L5 21"/></svg>
                            附件图片
                        </button>
                        <span id="imageCount" class="hidden text-xs text-blue-400"></span>
                        <span class="text-xs text-slate-600"><kbd class="font-mono text-[11px] bg-surface-overlay px-1.5 py-0.5 rounded border border-white/[0.06]">⌘</kbd> + <kbd class="font-mono text-[11px] bg-surface-overlay px-1.5 py-0.5 rounded border border-white/[0.06]">Enter</kbd> 提交</span>
                    </div>
                    <button id="submitBtn" onclick="submitFeedback()" class="text-[14px] font-semibold text-white bg-gradient-to-br from-blue-500 to-violet-500 rounded-lg px-7 py-2.5 hover:-translate-y-0.5 hover:shadow-[0_4px_16px_rgba(59,130,246,0.35)] active:translate-y-0 transition-all relative overflow-hidden group">
                        <span class="absolute inset-0 bg-gradient-to-br from-white/10 to-transparent opacity-0 group-hover:opacity-100 transition-opacity"></span>
                        <span class="relative">提交反馈</span>
                    </button>
                </div>
            </div>
        </div>

        <!-- SESSIONS -->
        <div id="page-sessions" class="page hidden flex-1 min-h-0 overflow-y-auto p-5 space-y-4">
            <div id="sessionsContainer">
                <div class="text-xs text-slate-600 text-center py-8">加载中...</div>
            </div>
        </div>

        <!-- SETTINGS -->
        <div id="page-settings" class="page hidden flex-1 min-h-0 overflow-y-auto p-5 space-y-4">
            <div class="bg-surface-raised border border-white/[0.06] rounded-2xl overflow-hidden hover:border-white/[0.08] transition">
                <div class="flex items-center gap-2.5 px-[18px] py-3.5 border-b border-white/[0.06]">
                    <div class="w-[3px] h-5 rounded-sm bg-emerald-500"></div>
                    <span class="text-sm font-semibold text-slate-200">语言设定</span>
                </div>
                <div class="px-[18px] divide-y divide-white/[0.06]">
                    <div class="flex items-center justify-between py-3.5">
                        <div><div class="text-[14px] font-medium text-slate-200 mb-0.5">界面语言</div><div class="text-xs text-slate-500">选择界面显示语言</div></div>
                        <select class="font-sans text-[14px] text-slate-200 bg-surface-base border border-white/[0.06] rounded px-3 py-[7px] min-w-[140px] outline-none focus:border-blue-500 transition cursor-pointer"><option>简体中文</option><option>繁體中文</option><option>English</option></select>
                    </div>
                </div>
            </div>
            <div class="bg-surface-raised border border-white/[0.06] rounded-2xl overflow-hidden hover:border-white/[0.08] transition">
                <div class="flex items-center gap-2.5 px-[18px] py-3.5 border-b border-white/[0.06]">
                    <div class="w-[3px] h-5 rounded-sm bg-amber-500"></div>
                    <span class="text-sm font-semibold text-slate-200">自动定时提交</span>
                </div>
                <div class="px-[18px] divide-y divide-white/[0.06]">
                    <div class="flex items-center justify-between py-3.5">
                        <div><div class="text-[14px] font-medium text-slate-200 mb-0.5">启用自动提交</div><div class="text-xs text-slate-500">在指定时间后自动提交选定的提示词</div></div>
                        <button class="relative w-11 h-6 bg-surface-muted border border-white/[0.06] rounded-full cursor-pointer transition-colors" onclick="this.classList.toggle('!bg-blue-500');this.classList.toggle('!border-blue-500');this.querySelector('div').classList.toggle('translate-x-5')">
                            <div class="absolute top-[2px] left-[2px] w-[18px] h-[18px] bg-white rounded-full shadow transition-transform"></div>
                        </button>
                    </div>
                    <div class="flex items-center justify-between py-3.5">
                        <div><div class="text-[14px] font-medium text-slate-200 mb-0.5">倒数时间</div><div class="text-xs text-slate-500">范围：1 ~ 86400 秒</div></div>
                        <div class="flex items-center gap-1.5">
                            <input type="number" value="30" min="1" max="86400" class="font-mono text-[14px] text-slate-200 bg-surface-base border border-white/[0.06] rounded px-3 py-[7px] w-[100px] outline-none focus:border-blue-500 transition">
                            <span class="text-xs text-slate-500">秒</span>
                        </div>
                    </div>
                </div>
            </div>
            <div class="bg-surface-raised border border-white/[0.06] rounded-2xl overflow-hidden hover:border-white/[0.08] transition">
                <div class="flex items-center gap-2.5 px-[18px] py-3.5 border-b border-white/[0.06]">
                    <div class="w-[3px] h-5 rounded-sm bg-violet-500"></div>
                    <span class="text-sm font-semibold text-slate-200">通知与音效</span>
                </div>
                <div class="px-[18px] divide-y divide-white/[0.06]">
                    <div class="flex items-center justify-between py-3.5">
                        <div><div class="text-[14px] font-medium text-slate-200 mb-0.5">浏览器通知</div><div class="text-xs text-slate-500">新会话到达时发送桌面通知</div></div>
                        <button class="relative w-11 h-6 bg-blue-500 border border-blue-500 rounded-full cursor-pointer transition-colors" onclick="this.classList.toggle('!bg-surface-muted');this.classList.toggle('!border-white/[0.06]');this.querySelector('div').classList.toggle('translate-x-5')">
                            <div class="absolute top-[2px] left-[2px] w-[18px] h-[18px] bg-white rounded-full shadow transition-transform translate-x-5"></div>
                        </button>
                    </div>
                    <div class="flex items-center justify-between py-3.5">
                        <div><div class="text-[14px] font-medium text-slate-200 mb-0.5">提示音</div><div class="text-xs text-slate-500">新会话到达时播放提示音</div></div>
                        <button class="relative w-11 h-6 bg-blue-500 border border-blue-500 rounded-full cursor-pointer transition-colors" onclick="this.classList.toggle('!bg-surface-muted');this.classList.toggle('!border-white/[0.06]');this.querySelector('div').classList.toggle('translate-x-5')">
                            <div class="absolute top-[2px] left-[2px] w-[18px] h-[18px] bg-white rounded-full shadow transition-transform translate-x-5"></div>
                        </button>
                    </div>
                </div>
            </div>
            <div class="bg-surface-raised border border-white/[0.06] rounded-2xl overflow-hidden hover:border-white/[0.08] transition">
                <div class="flex items-center gap-2.5 px-[18px] py-3.5 border-b border-white/[0.06]">
                    <div class="w-[3px] h-5 rounded-sm bg-red-500"></div>
                    <span class="text-sm font-semibold text-slate-200">进阶设定</span>
                </div>
                <div class="px-[18px]">
                    <div class="flex items-center justify-between py-3.5">
                        <div><div class="text-[14px] font-medium text-slate-200 mb-0.5">重置设定</div><div class="text-xs text-slate-500">清除所有已保存的设定，恢复预设状态</div></div>
                        <button class="text-xs font-medium text-red-400 border border-red-400/30 rounded px-3 py-1.5 hover:bg-red-500/10 transition">重置</button>
                    </div>
                </div>
            </div>
        </div>

        <!-- ABOUT -->
        <div id="page-about" class="page hidden flex-1 min-h-0 overflow-y-auto p-5 space-y-4">
            <div class="text-center pt-8 pb-4">
                <div class="w-12 h-12 rounded-[14px] bg-gradient-to-br from-blue-500 to-violet-500 inline-flex items-center justify-center text-[22px] text-white font-extrabold mb-3 shadow-[0_6px_20px_rgba(59,130,246,0.3)]">M</div>
                <div class="text-xl font-bold text-slate-200 mb-1">MCP Feedback Enhanced</div>
                <span class="font-mono text-xs text-blue-400 bg-blue-500/[0.12] px-2.5 py-0.5 rounded-full">v{{ version }}</span>
                <p class="text-[14px] text-slate-400 max-w-md mx-auto mt-3 leading-relaxed">
                    MCP 交互式反馈收集工具，提供 Web UI 供用户与 AI 代理交互。<br>
                    支持 Markdown 摘要、图片上传、多语言、会话管理等功能。
                </p>
                <div class="flex justify-center gap-2.5 mt-3">
                    <a href="https://github.com/Minidoracat/mcp-feedback-enhanced" target="_blank" class="text-xs font-semibold text-white bg-blue-500 hover:bg-blue-400 rounded-lg px-5 py-2 hover:-translate-y-0.5 transition-all inline-flex items-center gap-1.5">GitHub</a>
                    <a href="https://discord.gg/ACjf9Q58" target="_blank" class="text-xs font-semibold text-white bg-[#5865F2] hover:brightness-110 rounded-lg px-5 py-2 hover:-translate-y-0.5 transition-all inline-flex items-center gap-1.5">Discord</a>
                </div>
            </div>
            <div class="bg-surface-raised border border-white/[0.06] rounded-2xl overflow-hidden">
                <div class="flex items-center gap-2.5 px-[18px] py-3.5 border-b border-white/[0.06]">
                    <div class="w-[3px] h-5 rounded-sm bg-blue-500"></div>
                    <span class="text-sm font-semibold text-slate-200">致谢与贡献</span>
                </div>
                <div class="px-[18px] py-3.5 text-xs text-slate-400 leading-relaxed">
                    感谢原作者 Fábio Ferreira 创建了原始的 interactive-feedback-mcp 项目。
                    本增强版本由 Minidoracat 开发和维护，大幅扩展了项目功能。
                    同时感谢 sanshao85 的 mcp-feedback-collector 项目提供的 UI 设计灵感。
                </div>
            </div>
        </div>

    </div>

    <!-- ===== BOTTOM STATS PANEL ===== -->
    <div id="bottomPanel" class="bg-surface-raised border-t border-white/[0.06] shrink-0 overflow-hidden transition-all duration-[400ms]" style="max-height: 36px;">
        <div class="flex items-center justify-between px-5 py-2 cursor-pointer select-none" onclick="toggleBottom()">
            <span class="text-xs font-medium text-slate-400">统计</span>
            <span id="bottomArrow" class="text-[11px] text-slate-500 transition-transform duration-300">▼</span>
        </div>
        <div class="grid grid-cols-[repeat(auto-fit,minmax(140px,1fr))] gap-2.5 px-5 pb-3.5">
            <div class="flex flex-col gap-0.5 p-2.5 bg-surface-base rounded border border-white/[0.06]">
                <span class="text-[11px] text-slate-500 uppercase tracking-wider">连接时间</span>
                <span class="font-mono text-sm font-semibold text-blue-400">--:--</span>
            </div>
            <div class="flex flex-col gap-0.5 p-2.5 bg-surface-base rounded border border-white/[0.06]">
                <span class="text-[11px] text-slate-500 uppercase tracking-wider">重连次数</span>
                <span class="font-mono text-sm font-semibold text-blue-400">0</span>
            </div>
            <div class="flex flex-col gap-0.5 p-2.5 bg-surface-base rounded border border-white/[0.06]">
                <span class="text-[11px] text-slate-500 uppercase tracking-wider">消息数</span>
                <span class="font-mono text-sm font-semibold text-blue-400">0</span>
            </div>
            <div class="flex flex-col gap-0.5 p-2.5 bg-surface-base rounded border border-white/[0.06]">
                <span class="text-[11px] text-slate-500 uppercase tracking-wider">延迟</span>
                <span class="font-mono text-sm font-semibold text-blue-400">--ms</span>
            </div>
            <div class="flex flex-col gap-0.5 p-2.5 bg-surface-base rounded border border-white/[0.06]">
                <span class="text-[11px] text-slate-500 uppercase tracking-wider">会话数</span>
                <span class="font-mono text-sm font-semibold text-blue-400">0</span>
            </div>
            <div class="flex flex-col gap-0.5 p-2.5 bg-surface-base rounded border border-white/[0.06]">
                <span class="text-[11px] text-slate-500 uppercase tracking-wider">状态</span>
                <span class="font-mono text-sm font-semibold text-blue-400">等待中</span>
            </div>
        </div>
    </div>

    <!-- ===== SCRIPTS ===== -->
    <script src="/static/js/vendor/marked.min.js"></script>
    <script>
        // --- Connection status ---
        function setConnStatus(state) {
            var el = document.getElementById('connStatus');
            var inner = document.getElementById('connDotInner');
            var pulse = document.getElementById('connDotPulse');
            var text = document.getElementById('connText');
            if (!el) return;

            var map = {
                connecting: { color: 'amber', label: '连接中...' },
                connected:  { color: 'emerald', label: '已连接' },
                disconnected: { color: 'red', label: '已断开' }
            };
            var info = map[state] || map.connecting;
            var c = info.color;

            el.className = 'flex items-center gap-1.5 text-xs font-medium text-' + c + '-400';
            inner.className = 'absolute inset-0 rounded-full bg-' + c + '-400';
            pulse.className = 'absolute -inset-[3px] rounded-full bg-' + c + '-400 opacity-30 animate-[breathe_2.5s_ease-in-out_infinite]';
            text.textContent = info.label;
        }

        // --- WebSocket ---
        var ws = null;
        var wsReady = false;

        function connectWebSocket() {
            setConnStatus('connecting');
            var protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
            ws = new WebSocket(protocol + '//' + location.host + '/ws');

            ws.onopen = function() {
                wsReady = true;
                setConnStatus('connected');
                console.log('WebSocket connected');
            };

            ws.onmessage = function(event) {
                var data = JSON.parse(event.data);
                if (data.type === 'session_updated' && data.session_info) {
                    var el = document.getElementById('summaryContent');
                    if (el && typeof marked !== 'undefined') {
                        el.innerHTML = marked.parse(data.session_info.summary || '');
                    }
                    var tag = document.getElementById('newTag');
                    if (tag) tag.style.display = '';

                    var btn = document.getElementById('submitBtn');
                    if (btn) {
                        btn.querySelector('.relative').textContent = '提交反馈';
                        btn.classList.remove('from-emerald-500', 'to-emerald-600', 'opacity-70', 'cursor-not-allowed');
                        btn.classList.add('from-blue-500', 'to-violet-500');
                        btn.disabled = false;
                    }
                }
            };

            ws.onclose = function() {
                wsReady = false;
                setConnStatus('disconnected');
                console.log('WebSocket closed, reconnecting in 3s...');
                setTimeout(connectWebSocket, 3000);
            };

            ws.onerror = function() {
                wsReady = false;
                setConnStatus('disconnected');
            };
        }

        // --- Images ---
        var pendingImages = [];

        function addImageFromFile(file) {
            if (!file || !file.type.startsWith('image/')) return;
            var reader = new FileReader();
            reader.onload = function(e) {
                var name = file.name || ('paste-' + Date.now() + '.png');
                pendingImages.push({ data: e.target.result, name: name });
                renderImagePreviews();
            };
            reader.readAsDataURL(file);
        }

        function removeImage(idx) {
            pendingImages.splice(idx, 1);
            renderImagePreviews();
        }

        function renderImagePreviews() {
            var container = document.getElementById('imagePreview');
            var counter = document.getElementById('imageCount');
            if (!container) return;

            if (pendingImages.length === 0) {
                container.classList.add('hidden');
                container.innerHTML = '';
                if (counter) counter.classList.add('hidden');
                return;
            }

            container.classList.remove('hidden');
            container.style.display = 'flex';
            if (counter) {
                counter.textContent = pendingImages.length + ' 张图片';
                counter.classList.remove('hidden');
            }

            container.innerHTML = pendingImages.map(function(img, i) {
                return '<div class="relative group">' +
                    '<img src="' + img.data + '" class="w-16 h-16 object-cover rounded-lg border border-white/[0.06]">' +
                    '<button onclick="removeImage(' + i + ')" class="absolute -top-1.5 -right-1.5 w-5 h-5 bg-red-500 text-white rounded-full text-[11px] leading-none flex items-center justify-center opacity-0 group-hover:opacity-100 transition">&times;</button>' +
                    '</div>';
            }).join('');
        }

        // --- Submit ---
        function submitFeedback() {
            var textarea = document.getElementById('feedbackText');
            var feedback = textarea ? textarea.value.trim() : '';
            if (!feedback && pendingImages.length === 0) return;

            if (!wsReady || !ws) {
                alert('WebSocket 未连接，请稍后重试');
                return;
            }

            var imagesPayload = pendingImages.map(function(img) {
                var raw = img.data;
                var base64Only = raw.indexOf(',') !== -1 ? raw.split(',')[1] : raw;
                var byteLen = Math.floor(base64Only.length * 3 / 4);
                return { name: img.name, data: base64Only, size: byteLen };
            });

            ws.send(JSON.stringify({
                type: 'submit_feedback',
                feedback: feedback,
                images: imagesPayload,
                settings: {}
            }));

            textarea.value = '';
            pendingImages = [];
            renderImagePreviews();

            var tag = document.getElementById('newTag');
            if (tag) tag.style.display = 'none';

            var btn = document.getElementById('submitBtn');
            if (btn) {
                btn.querySelector('.relative').textContent = '已提交';
                btn.classList.remove('from-blue-500', 'to-violet-500');
                btn.classList.add('from-emerald-500', 'to-emerald-600');
                btn.disabled = true;
                btn.classList.add('opacity-70', 'cursor-not-allowed');
            }
        }

        // --- Init ---
        document.addEventListener('DOMContentLoaded', function() {
            // Render Markdown summary
            var el = document.getElementById('summaryContent');
            if (el && el.textContent.trim() && typeof marked !== 'undefined') {
                el.innerHTML = marked.parse(el.textContent);
            }

            // Connect WebSocket
            connectWebSocket();

            // File input change handler
            var fileInput = document.getElementById('imageInput');
            if (fileInput) {
                fileInput.addEventListener('change', function(e) {
                    Array.from(e.target.files).forEach(addImageFromFile);
                    e.target.value = '';
                });
            }

            // Keyboard shortcuts + paste
            var textarea = document.getElementById('feedbackText');
            if (textarea) {
                textarea.addEventListener('keydown', function(e) {
                    if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') {
                        e.preventDefault();
                        submitFeedback();
                    }
                });

                textarea.addEventListener('paste', function(e) {
                    var items = (e.clipboardData || e.originalEvent.clipboardData).items;
                    for (var i = 0; i < items.length; i++) {
                        if (items[i].type.indexOf('image') !== -1) {
                            e.preventDefault();
                            addImageFromFile(items[i].getAsFile());
                            break;
                        }
                    }
                });
            }
        });

        // --- Sessions ---
        var sessionsLoaded = false;

        function loadSessions() {
            fetch('/api/all-sessions')
                .then(function(r) { return r.json(); })
                .then(function(data) {
                    sessionsLoaded = true;
                    renderSessions(data.sessions || []);
                })
                .catch(function() {
                    document.getElementById('sessionsContainer').innerHTML =
                        '<div class="text-xs text-red-400 text-center py-8">加载失败</div>';
                });
        }

        function formatTime(ms) {
            if (!ms) return '--:--:--';
            var d = new Date(ms);
            return d.toLocaleTimeString('zh-CN', { hour12: false });
        }

        function statusLabel(status, isCurrent) {
            var map = {
                waiting: { text: '等待中', cls: 'text-amber-400 bg-amber-400/10 border-amber-400/20' },
                active: { text: '活跃', cls: 'text-emerald-400 bg-emerald-400/10 border-emerald-400/20' },
                completed: { text: '已完成', cls: 'text-blue-400 bg-blue-400/10 border-blue-400/20' },
                timeout: { text: '超时', cls: 'text-red-400 bg-red-400/10 border-red-400/20' },
                error: { text: '错误', cls: 'text-red-400 bg-red-400/10 border-red-400/20' }
            };
            var info = map[status] || map.waiting;
            return '<span class="text-[11px] font-semibold uppercase tracking-wide ' + info.cls + ' border px-2.5 py-0.5 rounded-full">' + info.text + '</span>';
        }

        function renderSessionCard(s, isCurrent) {
            var borderCls = isCurrent ? 'border-blue-500/30 bg-gradient-to-br from-blue-500/[0.06] to-transparent' : 'border-white/[0.06]';
            var sid = s.session_id.substring(0, 8);
            return '<div class="bg-surface-raised border ' + borderCls + ' rounded-2xl p-4 hover:shadow-lg transition">' +
                '<div class="flex items-center justify-between mb-2">' +
                    '<span class="font-mono text-xs text-blue-400 bg-blue-500/[0.12] px-2.5 py-0.5 rounded-full">' + sid + '</span>' +
                    statusLabel(s.status, isCurrent) +
                '</div>' +
                '<div class="text-xs text-slate-500 space-y-0.5">' +
                    '<div>创建时间：' + formatTime(s.created_at) + '</div>' +
                    '<div>项目：' + (s.project_directory || '--') + '</div>' +
                '</div>' +
                '<div class="flex gap-2 mt-3">' +
                    '<button onclick="showSessionDetail(\'' + s.session_id + '\')" class="text-xs font-medium text-slate-400 border border-white/[0.06] rounded px-3 py-1.5 hover:text-slate-200 hover:border-blue-500 hover:bg-blue-500/10 transition">查看详情</button>' +
                '</div>' +
            '</div>';
        }

        // Session detail modal
        var allSessionsCache = [];

        function showSessionDetail(sessionId) {
            var s = allSessionsCache.find(function(x) { return x.session_id === sessionId; });
            if (!s) return;

            var overlay = document.createElement('div');
            overlay.className = 'fixed inset-0 bg-black/60 z-[100] flex items-center justify-center p-6';
            overlay.onclick = function(e) { if (e.target === overlay) overlay.remove(); };

            var summaryHtml = s.summary && typeof marked !== 'undefined' ? marked.parse(s.summary) : (s.summary || '无摘要');

            overlay.innerHTML = '<div class="bg-surface-raised border border-white/[0.06] rounded-2xl max-w-2xl w-full max-h-[80vh] flex flex-col overflow-hidden">' +
                '<div class="flex items-center justify-between px-5 py-4 border-b border-white/[0.06] shrink-0">' +
                    '<span class="text-sm font-semibold text-slate-200">会话详情</span>' +
                    '<button onclick="this.closest(\'.fixed\').remove()" class="text-slate-500 hover:text-slate-300 text-lg">&times;</button>' +
                '</div>' +
                '<div class="flex-1 overflow-y-auto p-5 space-y-4">' +
                    '<div class="grid grid-cols-2 gap-3 text-xs">' +
                        '<div class="text-slate-500">会话 ID</div><div class="font-mono text-slate-300">' + s.session_id + '</div>' +
                        '<div class="text-slate-500">状态</div><div>' + statusLabel(s.status) + '</div>' +
                        '<div class="text-slate-500">创建时间</div><div class="text-slate-300">' + formatTime(s.created_at) + '</div>' +
                        '<div class="text-slate-500">最后活动</div><div class="text-slate-300">' + formatTime(s.last_activity) + '</div>' +
                        '<div class="text-slate-500">项目</div><div class="text-slate-300 break-all">' + (s.project_directory || '--') + '</div>' +
                    '</div>' +
                    '<div class="border-t border-white/[0.06] pt-4">' +
                        '<div class="text-xs font-semibold text-slate-400 mb-2 uppercase tracking-wider">AI 工作摘要</div>' +
                        '<div class="md text-[14px] leading-relaxed">' + summaryHtml + '</div>' +
                    '</div>' +
                '</div>' +
            '</div>';

            document.body.appendChild(overlay);
        }

        function renderSessions(sessions) {
            allSessionsCache = sessions;
            var container = document.getElementById('sessionsContainer');
            if (!container) return;

            var currentSessions = sessions.filter(function(s) { return s.is_current; });
            var historySessions = sessions.filter(function(s) { return !s.is_current; });

            var html = '';

            html += '<span class="text-xs font-semibold uppercase tracking-wider text-slate-400 block mb-3">当前会话</span>';
            if (currentSessions.length > 0) {
                currentSessions.forEach(function(s) { html += renderSessionCard(s, true); });
            } else {
                html += '<div class="text-xs text-slate-600 text-center py-4">无活跃会话</div>';
            }

            html += '<span class="text-xs font-semibold uppercase tracking-wider text-slate-400 pt-4 block mb-3">历史会话</span>';
            if (historySessions.length > 0) {
                html += '<div class="space-y-3">';
                historySessions.forEach(function(s) { html += renderSessionCard(s, false); });
                html += '</div>';
            } else {
                html += '<div class="text-xs text-slate-600 text-center py-4">暂无历史会话</div>';
            }

            html += '<span class="text-xs font-semibold uppercase tracking-wider text-slate-400 pt-4 block mb-3">统计</span>';
            html += '<div class="grid grid-cols-2 gap-3">' +
                '<div class="bg-surface-raised border border-white/[0.06] rounded-xl p-4 text-center">' +
                    '<span class="font-mono text-2xl font-semibold text-blue-400 block mb-1">' + sessions.length + '</span>' +
                    '<span class="text-xs text-slate-500 uppercase tracking-wider">总会话数</span>' +
                '</div>' +
                '<div class="bg-surface-raised border border-white/[0.06] rounded-xl p-4 text-center">' +
                    '<span class="font-mono text-2xl font-semibold text-blue-400 block mb-1">' + currentSessions.length + '</span>' +
                    '<span class="text-xs text-slate-500 uppercase tracking-wider">活跃会话</span>' +
                '</div>' +
            '</div>';

            container.innerHTML = html;
        }

        // --- Tab switching ---
        document.getElementById('tabNav').addEventListener('click', function(e) {
            var btn = e.target.closest('.tab-btn');
            if (!btn) return;
            var name = btn.dataset.tab;

            document.querySelectorAll('.page').forEach(function(p) { p.classList.add('hidden'); });
            document.querySelectorAll('.tab-btn').forEach(function(b) {
                b.className = 'tab-btn px-4 py-2 text-[14px] font-medium rounded-full text-slate-500 hover:text-slate-400 hover:bg-surface-overlay transition-all';
            });

            document.getElementById('page-' + name).classList.remove('hidden');
            btn.className = 'tab-btn tab-active-dot relative px-4 py-2 text-[14px] font-medium rounded-full text-slate-200 bg-surface-overlay shadow-sm ring-1 ring-white/[0.06] transition-all';

            if (name === 'sessions') loadSessions();
        });

        // --- Bottom stats panel ---
        var panelOpen = false;
        function toggleBottom() {
            panelOpen = !panelOpen;
            document.getElementById('bottomPanel').style.maxHeight = panelOpen ? '180px' : '36px';
            document.getElementById('bottomArrow').style.transform = panelOpen ? 'rotate(180deg)' : '';
        }
    </script>
</body>
</html>
