<!DOCTYPE html>
<html lang="pt-BR" data-theme="dark">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>VPS AI Dashboard</title>
    <!-- Favicon -->
    <link rel="icon"
        href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'%3E%3Ctext y='.9em' font-size='90'%3E%F0%9F%A4%96%3C/text%3E%3C/svg%3E">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
    <style>
        :root {
            --bg-base: #0f172a;
            --bg-card: rgba(30, 41, 59, 0.8);
            --bg-input: rgba(15, 23, 42, 0.5);
            --border: rgba(255, 255, 255, 0.08);
            --accent: #3b82f6;
            --accent-hover: #60a5fa;
            --accent-glow: rgba(59, 130, 246, 0.25);
            --text-main: #f8fafc;
            --text-muted: #94a3b8;
            --danger: #ef4444;
            --danger-bg: rgba(239, 68, 68, 0.15);
            --success: #10b981;
            --shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
            --radius: 12px;
            --transition: 0.25s ease;
        }

        /* Custom Scrollbar */
        ::-webkit-scrollbar { width: 8px; }
        ::-webkit-scrollbar-track { background: var(--bg-base); }
        ::-webkit-scrollbar-thumb { 
            background: var(--border); 
            border-radius: 4px; 
            border: 2px solid var(--bg-base); 
        }
        ::-webkit-scrollbar-thumb:hover { background: var(--accent); }

        /* Scrollbar Fix for Firefox / Modern Browsers */
        @supports (scrollbar-width: thin) {
            * {
                scrollbar-width: thin;
                scrollbar-color: var(--accent) transparent;
            }
        }

        @keyframes pulse {
            0% {
                transform: scale(1);
                opacity: 1;
            }

            50% {
                transform: scale(1.1);
                opacity: 0.7;
            }

            100% {
                transform: scale(1);
                opacity: 1;
            }
        }

        [data-theme="light"] {
            --bg-base: #f1f5f9;
            --bg-card: #ffffff;
            --bg-input: #e2e8f0;
            --border: rgba(0, 0, 0, 0.08);
            --accent: #2563eb;
            --accent-hover: #1d4ed8;
            --accent-glow: rgba(37, 99, 235, 0.2);
            --text-main: #1e3a5f;
            --text-muted: #64748b;
            --shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
        }

        /* Global SVG Presentation */
        svg {
            fill: none;
            stroke: currentColor;
            stroke-width: 2;
            stroke-linecap: round;
            stroke-linejoin: round;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            background-color: var(--bg-base);
            color: var(--text-main);
            min-height: 100vh;
            transition: background-color var(--transition), color var(--transition);
            line-height: 1.5;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            padding: 1rem;
        }

        /* Header */
        header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            padding: 1rem 0;
            margin-bottom: 1rem;
            border-bottom: 1px solid var(--border);
        }

        .logo {
            display: flex;
            align-items: center;
            gap: 0.75rem;
        }

        .logo svg {
            width: 32px;
            height: 32px;
            color: var(--accent);
        }

        .logo h1 {
            font-size: 1.25rem;
            font-weight: 700;
            background: linear-gradient(135deg, var(--accent), #8b5cf6);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }

        .header-actions {
            display: flex;
            align-items: center;
            gap: 1rem;
        }

        .status-badge {
            display: flex;
            align-items: center;
            gap: 0.5rem;
            padding: 0.4rem 0.75rem;
            background: rgba(16, 185, 129, 0.15);
            color: var(--success);
            border-radius: 20px;
            font-size: 0.75rem;
            font-weight: 600;
        }

        .status-badge::before {
            content: '';
            width: 6px;
            height: 6px;
            background: var(--success);
            border-radius: 50%;
            box-shadow: 0 0 6px var(--success);
        }

        .status-badge.offline {
            background: var(--danger-bg);
            color: var(--danger);
        }

        .status-badge.offline::before {
            background: var(--danger);
            box-shadow: 0 0 6px var(--danger);
        }

        .theme-toggle {
            display: flex;
            align-items: center;
            justify-content: center;
            width: 36px;
            height: 36px;
            background: var(--bg-card);
            border: 1px solid var(--border);
            border-radius: 8px;
            cursor: pointer;
            transition: all var(--transition);
            color: var(--text-main);
        }

        .theme-toggle:hover {
            background: var(--accent);
            border-color: var(--accent);
            color: white;
        }

        .theme-toggle svg {
            width: 18px;
            height: 18px;
        }

        /* Cards */
        .card {
            background: var(--bg-card);
            border: 1px solid var(--border);
            border-radius: var(--radius);
            padding: 1rem;
            box-shadow: var(--shadow);
            transition: all var(--transition);
        }

        /* Stats Grid */
        .stats-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
            gap: 0.75rem;
            margin-bottom: 1rem;
        }

        .stat-card h3 {
            font-size: 0.7rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.05em;
            color: var(--text-muted);
            margin-bottom: 0.5rem;
        }

        .stat-value {
            font-size: 1.5rem;
            font-weight: 700;
            margin-bottom: 0.5rem;
        }

        .progress-bar-bg {
            height: 6px;
            background: var(--bg-input);
            border-radius: 3px;
            overflow: hidden;
        }

        .progress-bar {
            height: 100%;
            background: var(--accent);
            border-radius: 3px;
            transition: width 0.5s ease;
        }

        .progress-bar.warning {
            background: #f59e0b;
        }

        .progress-bar.danger {
            background: var(--danger);
        }

        /* Section Title */
        .section-title {
            font-size: 0.85rem;
            font-weight: 600;
            color: var(--text-muted);
            margin: 1.25rem 0 0.75rem;
            text-transform: uppercase;
            letter-spacing: 0.05em;
        }

        /* Actions Grid */
        .actions-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
            gap: 0.5rem;
            margin-bottom: 1rem;
        }

        .btn {
            display: flex;
            align-items: center;
            justify-content: center;
            gap: 0.5rem;
            padding: 0.65rem 1rem;
            background: var(--bg-card);
            border: 1px solid var(--border);
            border-radius: 8px;
            color: var(--text-main);
            font-size: 0.8rem;
            font-weight: 500;
            cursor: pointer;
            transition: all var(--transition);
        }

        .btn svg {
            width: 16px;
            height: 16px;
            flex-shrink: 0;
        }

        .btn:hover {
            background: var(--accent);
            border-color: var(--accent);
            transform: translateY(-1px);
            box-shadow: 0 4px 12px var(--accent-glow);
        }

        .btn:active {
            transform: translateY(0);
        }

        .btn-danger {
            border-color: rgba(239, 68, 68, 0.3);
            color: var(--danger);
        }

        .btn-danger:hover {
            background: var(--danger);
            border-color: var(--danger);
            color: white;
        }

        .btn-primary {
            background: var(--accent);
            border-color: var(--accent);
            color: white;
        }

        .btn-primary:hover {
            background: var(--accent-hover);
        }

        /* Config Form */
        .config-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
            gap: 0.75rem;
            margin-bottom: 0.75rem;
        }

        .form-group label {
            display: block;
            font-size: 0.7rem;
            font-weight: 600;
            text-transform: uppercase;
            letter-spacing: 0.05em;
            color: var(--text-muted);
            margin-bottom: 0.35rem;
        }

        .form-input {
            width: 100%;
            padding: 0.6rem 0.75rem;
            background: var(--bg-input);
            border: 1px solid var(--border);
            border-radius: 8px;
            color: var(--text-main);
            font-size: 0.85rem;
            transition: border-color var(--transition);
        }

        .form-input:focus {
            outline: none;
            border-color: var(--accent);
        }

        select.form-input {
            cursor: pointer;
        }

        /* Chat & Insights Layout */
        .chat-layout {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 1rem;
            height: clamp(400px, 60vh, 800px);
            margin-bottom: 2rem;
        }

        .chat-wrapper {
            display: flex;
            flex-direction: column;
            background: var(--bg-card);
            border: 1px solid var(--border);
            border-radius: var(--radius);
            overflow: hidden;
        }

        .insights-wrapper {
            display: flex;
            flex-direction: column;
            background: var(--bg-card);
            border: 2px solid var(--accent-glow);
            border-radius: var(--radius);
            overflow: hidden;
            box-shadow: 0 0 20px rgba(59, 130, 246, 0.1);
        }

        .insights-header {
            padding: 0.75rem 1rem;
            background: rgba(59, 130, 246, 0.05);
            border-bottom: 1px solid var(--border);
            display: flex;
            align-items: center;
            gap: 0.5rem;
            font-weight: 600;
            color: var(--accent);
            font-size: 0.9rem;
        }

        .insights-content {
            flex: 1;
            padding: 1.25rem;
            overflow-y: auto;
            font-size: 0.9rem;
        }

        .insights-content h3 {
            margin-bottom: 1rem;
            color: var(--accent);
        }

        .insights-content table {
            width: 100%;
            border-collapse: collapse;
            margin: 1rem 0;
            background: var(--bg-input);
            border-radius: 8px;
            overflow: hidden;
        }

        .insights-content th,
        .insights-content td {
            padding: 0.75rem;
            text-align: left;
            border-bottom: 1px solid var(--border);
        }

        .insights-content th {
            background: rgba(59, 130, 246, 0.1);
            color: var(--accent);
            font-size: 0.75rem;
            text-transform: uppercase;
        }

        .insights-placeholder {
            height: 100%;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            color: var(--text-muted);
            text-align: center;
            padding: 2rem;
        }

        .chat-messages {
            flex: 1;
            overflow-y: auto;
            padding: 0.75rem;
            display: flex;
            flex-direction: column;
            gap: 0.5rem;
        }

        .chat-bubble {
            max-width: 80%;
            padding: 0.6rem 0.9rem;
            border-radius: 12px;
            font-size: 0.85rem;
            line-height: 1.4;
        }

        .bubble-ai {
            background: rgba(59, 130, 246, 0.1);
            border: 1px solid rgba(59, 130, 246, 0.2);
            align-self: flex-start;
            border-bottom-left-radius: 4px;
        }

        .bubble-user {
            background: var(--accent);
            color: white;
            align-self: flex-end;
            border-bottom-right-radius: 4px;
        }

        .chat-input-area {
            display: flex;
            gap: 0.5rem;
            padding-top: 0.75rem;
            border-top: 1px solid var(--border);
        }

        .chat-input {
            flex: 1;
            padding: 0.6rem 0.75rem;
            background: var(--bg-input);
            border: 1px solid var(--border);
            border-radius: 8px;
            color: var(--text-main);
            font-size: 0.85rem;
        }

        .chat-input:focus {
            outline: none;
            border-color: var(--accent);
        }

        .chat-input::placeholder {
            color: var(--text-muted);
        }

        /* Toast */
        #toast {
            position: fixed;
            bottom: 1rem;
            right: 1rem;
            padding: 0.75rem 1.25rem;
            background: var(--success);
            color: white;
            border-radius: 8px;
            font-size: 0.85rem;
            font-weight: 500;
            opacity: 0;
            transform: translateY(10px);
            transition: all 0.3s ease;
            pointer-events: none;
            z-index: 1000;
        }

        #toast.show {
            opacity: 1;
            transform: translateY(0);
        }

        #toast.error {
            background: var(--danger);
        }

        /* Responsive */
        @media (max-width: 640px) {
            .container {
                padding: 0.75rem;
            }

            header {
                flex-direction: column;
                gap: 0.75rem;
                text-align: center;
            }

            .header-actions {
                width: 100%;
                justify-content: center;
            }

            .stats-grid {
                grid-template-columns: 1fr;
            }

            .actions-grid {
                grid-template-columns: 1fr 1fr;
            }

            .config-grid {
                grid-template-columns: 1fr;
            }

            .chat-wrapper {
                height: 300px;
            }

            .chat-bubble {
                max-width: 90%;
            }

            .btn {
                padding: 0.6rem 0.75rem;
                font-size: 0.75rem;
            }
        }

        @media (max-width: 380px) {
            .actions-grid {
                grid-template-columns: 1fr;
            }
        }

        #login-overlay { 
            position: fixed; 
            inset: 0; 
            background: #060a12; 
            z-index: 9999; 
            display: flex; 
            align-items: center; 
            justify-content: center; 
            flex-direction: column;
        }

        .login-card {
            width: 90%;
            max-width: 400px;
            padding: 2.5rem;
            text-align: center;
            border: 1px solid var(--accent);
            box-shadow: 0 0 30px var(--accent-glow);
            background: var(--bg-card);
        }

        .login-icon {
            font-size: 3rem;
            margin-bottom: 1rem;
        }

        .login-title {
            margin-bottom: 1rem;
            font-size: 1.5rem;
            font-weight: 700;
            background: linear-gradient(135deg, var(--accent), #8b5cf6);
            -webkit-background-clip: text;
            -webkit-text-fill-color: transparent;
            background-clip: text;
        }

        .login-desc {
            color: var(--text-muted);
            margin-bottom: 1.5rem;
            font-size: 0.85rem;
        }

        .login-input {
            margin-bottom: 1rem;
            text-align: center;
            font-size: 1.1rem;
            letter-spacing: 0.2rem;
        }

        /* Utilities */
        .hidden { display: none !important; }
        .w-full { width: 100%; }
        .text-center { text-align: center; }
        .mt-2 { margin-top: 0.5rem; }
        .opacity-60 { opacity: 0.6; }

        .theme-icon { width: 18px; height: 18px; }
        .recording-dot {
            width: 8px;
            height: 8px;
            background: var(--danger);
            border-radius: 50%;
            display: inline-block;
            animation: pulse 1s infinite;
        }
        .mic-active { color: var(--danger) !important; border-color: var(--danger) !important; }
        
        .fade-in { animation: fadeIn 0.4s ease-out; }
        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        /* Novas classes para substituir estilos inline */
        .login-error { margin-top: 10px; font-size: 0.75rem; color: var(--danger); font-weight: bold; text-transform: uppercase; }
        .status-bar-info { margin-bottom: 1rem; padding: 0.75rem; background: var(--bg-input); border-radius: 8px; font-size: 0.85rem; display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; }
        .status-bar-success { margin-bottom: 1rem; padding: 0.5rem 0.75rem; background: var(--success); opacity: 0.15; border-radius: 6px; font-size: 0.75rem; }
        .btn-xs { padding: 0.4rem 0.75rem; font-size: 0.75rem; }
        .config-section-card { padding: 1rem; background: var(--bg-input); border-radius: 8px; border: 1px solid var(--border); }
        .config-section-title { margin-bottom: 0.75rem; font-size: 0.9rem; display: flex; align-items: center; gap: 0.25rem; }
        .config-section-title.accent { color: var(--accent); }
        .config-section-title.success { color: var(--success); }
        .config-section-icon { vertical-align: middle; }
        .mt-4 { margin-top: 1rem; }
        .flex-between { display: flex; justify-content: space-between; align-items: center; margin-bottom: 1rem; }
        .text-sm-muted { font-size: 0.85rem; color: var(--text-muted); }
        .scroll-y-auto { overflow-y: auto; }
        .max-h-300 { max-height: 300px; }
        .p-4 { padding: 1rem; }
        .chat-input-container { padding: 0.75rem; gap: 0.5rem; }
        .vnc-link { color: var(--accent); font-size: 0.75rem; text-decoration: none; display: flex; align-items: center; gap: 0.25rem; }
        .vnc-link:hover { text-decoration: underline; }
        @keyframes blink-red { 0% { background-color: var(--danger); box-shadow: 0 0 0px var(--danger); } 50% { background-color: #ff4d4d; box-shadow: 0 0 15px #ff4d4d; } 100% { background-color: var(--danger); box-shadow: 0 0 0px var(--danger); } }
        .vnc-active-blink { animation: blink-red 2s infinite ease-in-out !important; color: white !important; }
    </style>
</head>

<body>
    <!-- Login Suspenso -->
    <div id="login-overlay">
        <div class="login-card fade-in">
            <div class="login-icon">🔒</div>
            <h2 class="login-title">BOT VPS TERMINAL</h2>
            <p class="login-desc">DNS restrito. Digite a senha de acesso.</p>
            <input type="password" id="login-pass" class="form-input login-input" placeholder="••••••••" autofocus>
            <button type="button" class="btn btn-primary w-full mt-2" onclick="checkAuth()">ACESSAR HUB</button>
            <div id="login-error" class="hidden login-error">Senha Incorreta</div>
        </div>
    </div>

    <div class="container">
        <header>
            <div class="logo">
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                    <path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" />
                </svg>
                <h1>VPS AI Dashboard</h1>
            </div>
            <div class="header-actions">
                <div class="status-badge" id="bot-status">Online</div>
                <button type="button" class="theme-toggle" onclick="toggleTheme()" aria-label="Alternar tema">
                    <svg id="icon-sun" class="theme-icon hidden" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <circle cx="12" cy="12" r="5" />
                        <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
                    </svg>
                    <svg id="icon-moon" class="theme-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z" />
                    </svg>
                </button>
            </div>
        </header>

        <main>
            <div class="stats-grid">
                <div class="card stat-card">
                    <h3>CPU</h3>
                    <div class="stat-value" id="cpu-val">--%</div>
                    <div class="progress-bar-bg">
                        <div class="progress-bar" id="cpu-bar"></div>
                    </div>
                </div>
                <div class="card stat-card">
                    <h3>RAM</h3>
                    <div class="stat-value" id="ram-val">-- / -- GB</div>
                    <div class="progress-bar-bg">
                        <div class="progress-bar" id="ram-bar"></div>
                    </div>
                </div>
                <div class="card stat-card">
                    <h3>Disk</h3>
                    <div class="stat-value" id="disk-val">--%</div>
                    <div class="progress-bar-bg">
                        <div class="progress-bar" id="disk-bar"></div>
                    </div>
                </div>
            </div>

            <div class="section-title">Ações Rápidas</div>
            <div class="actions-grid">
                <button type="button" class="btn" onclick="executeAction('ping')">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path d="M22 12h-4l-3 9L9 3l-3 9H2" />
                    </svg>
                    Ping
                </button>
                <button type="button" class="btn" id="btn-test-llm" onclick="testLLMSpeed()">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path d="M12 2a10 10 0 1 0 10 10H12V2z" />
                        <path d="M12 2a10 10 0 0 1 10 10h-2a8 8 0 0 0-8-8V2z" />
                        <path d="M12 12V2.5l5.5 5.5" />
                    </svg>
                    Testar LLM
                </button>
                <button type="button" class="btn" onclick="executeAction('restart_bot')">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path d="M23 4v6h-6M1 20v-6h6" />
                        <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" />
                    </svg>
                    Reiniciar
                </button>
                <button type="button" class="btn" onclick="executeAction('clear_cache')">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path
                            d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" />
                    </svg>
                    Limpar Cache
                </button>
                <button type="button" class="btn btn-danger" onclick="executeAction('reboot_vps')">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />
                    </svg>
                    Reboot VPS
                </button>
                <button type="button" class="btn" id="vnc-toggle-btn" onclick="executeAction('toggle_vnc')">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
                        <line x1="8" y1="21" x2="16" y2="21"/>
                        <line x1="12" y1="17" x2="12" y2="21"/>
                    </svg>
                    <span id="vnc-toggle-text">Ligar VNC</span>
                </button>
                <a href="https://vnc.claw.reifonas.cloud/vnc.html" target="_blank" rel="noopener noreferrer" id="vnc-link" class="vnc-link hidden">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="12" height="12"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
                    Abrir VNC
                </a>
            </div>

            <div class="section-title">Configuração AI</div>
            <div class="card">
                <div class="config-grid">
                    <div class="form-group">
                        <label for="active_provider">Provider Ativo</label>
                        <select id="active_provider" aria-label="Provider Ativo" class="form-input" onchange="toggleProviderFields()">
                            <option value="minimax">MiniMax (Hermes - Externo)</option>
                            <option value="openrouter">OpenRouter (Externo)</option>
                            <option value="ollama">Ollama (Local-Interno)</option>
                        </select>
                    </div>
                    <div class="form-group" id="group-openrouter-model">
                        <label for="openrouter_model">Modelo OpenRouter</label>
                        <input type="text" id="openrouter_model" class="form-input" placeholder="ex: qwen/qwen-2.5-72b-instruct">
                    </div>
                </div>
                <button type="button" class="btn btn-primary" onclick="saveConfiguration()">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                        <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
                        <polyline points="17 21 17 13 7 13 7 21" />
                        <polyline points="7 3 7 8 15 8" />
                    </svg>
                    Salvar
                </button>
            </div>

            <!-- ORCHESTRATOR CONFIG -->
            <div class="section-title">Orquestrador AI (Planner + Executor)</div>
            <div class="card">
                <div class="status-bar-info">
                    <strong>Status:</strong> <span id="orchestrator-status">Carregando...</span>
                    <button type="button" class="btn btn-xs" onclick="syncFromRepo()">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14"><path d="M23 4v6h-6M1 20v-6h6"/><path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/></svg>
                        Sync Repo
                    </button>
                    <button type="button" class="btn btn-xs" onclick="syncCredentials()">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14"><path d="M3 6h18M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/></svg>
                        Sync Local
                    </button>
                </div>
                <div class="status-bar-success">
                    <strong>Repo Gitea:</strong> <span id="repo-status">Carregando...</span>
                </div>
                
                <div class="config-grid">
                    <!-- PLANNER CONFIG -->
                    <div class="config-section-card">
                        <h4 class="config-section-title accent">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" class="config-section-icon"><path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/></svg>
                            Planner (Planejador)
                        </h4>
                        <div class="form-group">
                            <label for="planner_provider">Provider</label>
                            <select id="planner_provider" aria-label="Provider do Planner" class="form-input" onchange="loadPlannerModels()">
                                <option value="gemini">Gemini (Google)</option>
                                <option value="openai">OpenAI (GPT-4)</option>
                                <option value="anthropic">Anthropic (Claude)</option>
                                <option value="ollama">Ollama (Local)</option>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="planner_model">Modelo</label>
                            <select id="planner_model" aria-label="Modelo do Planner" class="form-input">
                                <option value="">Carregando...</option>
                            </select>
                        </div>
                    </div>
                    
                    <!-- EXECUTOR CONFIG -->
                    <div class="config-section-card">
                        <h4 class="config-section-title success">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" class="config-section-icon"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2"/></svg>
                            Executor (Executor)
                        </h4>
                        <div class="form-group">
                            <label for="executor_provider">Provider</label>
                            <select id="executor_provider" aria-label="Provider do Executor" class="form-input" onchange="loadExecutorModels()">
                                <option value="ollama" selected>Ollama (Local)</option>
                                <option value="gemini">Gemini (Google)</option>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="executor_model">Modelo</label>
                            <select id="executor_model" aria-label="Modelo do Executor" class="form-input">
                                <option value="">Carregando...</option>
                            </select>
                        </div>
                    </div>
                </div>
                
                <div class="mt-4">
                    <button type="button" class="btn btn-primary" onclick="saveLLMConfig()">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                            <path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z" />
                            <polyline points="17 21 17 13 7 13 7 21" />
                            <polyline points="7 3 7 8 15 8" />
                        </svg>
                        Salvar Config LLM
                    </button>
                </div>
            </div>

            <!-- CREDENCIAIS CARREGADAS -->
            <div class="section-title">Credenciais Carregadas</div>
            <div class="card">
                <div class="flex-between">
                    <span class="text-sm-muted">
                        Credenciais sincronizadas dos serviços (Coolify, Gitea, Supabase, etc)
                    </span>
                    <button type="button" class="btn btn-xs" onclick="loadCredentials()">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="14" height="14">
                            <path d="M23 4v6h-6M1 20v-6h6"/>
                            <path d="M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15"/>
                        </svg>
                        Atualizar
                    </button>
                </div>
                <div id="credentials-container" class="hidden">
                    <div id="credentials-list" class="max-h-300 scroll-y-auto"></div>
                </div>
                <div id="credentials-loading" class="text-center p-4 text-sm-muted">
                    Clique em "Atualizar" para carregar as credenciais
                </div>
            </div>

            <div class="section-title">Terminal & Insights da IA</div>
            <div class="chat-layout">
                <!-- Coluna 1: Chat Técnico -->
                <div class="chat-wrapper">
                    <div class="chat-messages" id="chat-box">
                        <div class="chat-bubble bubble-ai">
                            Olá! Sou o VPS Agent. Como posso ajudar com seu servidor? Tudo o que eu fizer aparecerá aqui
                            no
                            terminal técnico.
                        </div>
                    </div>
                    <div class="chat-input-area chat-input-container">
                        <input type="text" id="chat-input" aria-label="Comando do chat" class="chat-input"
                            placeholder="Comande sua VPS aqui..." onkeypress="handleKeyPress(event)">

                        <button type="button" class="btn" id="audio-btn" aria-label="Gravar Áudio"
                            onclick="toggleRecording()" title="Gravar Áudio">
                            <svg id="mic-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                                <path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z" />
                                <path d="M19 10v2a7 7 0 0 1-14 0v-2M12 19v4M8 23h8" />
                            </svg>
                            <span id="recording-dot" class="recording-dot hidden"></span>
                        </button>

                        <button type="button" class="btn btn-primary" aria-label="Enviar" onclick="sendChat()">
                            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
                                <line x1="22" y1="2" x2="11" y2="13" />
                                <polygon points="22 2 15 22 11 13 2 9 22 2" />
                            </svg>
                        </button>
                    </div>
                </div>

                <!-- Coluna 2: Painel de Insights (Refinado) -->
                <div class="insights-wrapper">
                    <div class="insights-header">
                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="18" height="18">
                            <path d="M21 12V7a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v10a2 2 0 0 0 2 2h7" />
                            <line x1="16" y1="5" x2="16" y2="19" />
                            <line x1="2" x2="16" y2="12" />
                        </svg>
                        Painel de Insights Visuais
                    </div>
                    <div class="insights-content" id="insights-panel">
                        <div class="insights-placeholder">
                            <div class="login-icon" role="img" aria-label="Gráfico de Insights">📊</div>
                            <p>Aguardando dados estruturados...</p>
                            <small class="mt-2 opacity-60">Peça algo como "status dos containers" para ver o refinamento aqui.</small>
                        </div>
                    </div>
                </div>
        </main>
    </div>

    <div id="toast">Ação executada!</div>

    <script>
        let webPassword = '1234'; // Senha padrão suspensa
        let chatHistory = []; // Memória da conversa na Web

        // Helper para chamadas de API com autenticação
        async function apiFetch(url, options = {}) {
            if (!options.headers) options.headers = {};
            options.headers['X-Web-Password'] = webPassword;

            const res = await fetch(url, options);
            return res;
        }

        function initDashboard() {
            fetchStats();
            loadConfig();
            loadOrchestratorStatus();
            loadVNCStatus();
            loadLLMModels().then(function() {
                loadLLMConfig();
            });
        }

        async function loadVNCStatus() {
            try {
                const res = await apiFetch('/api/vnc_status');
                const data = await res.json();
                const btn = document.getElementById('vnc-toggle-btn');
                const txt = document.getElementById('vnc-toggle-text');
                const lnk = document.getElementById('vnc-link');
                if (data.vnc_status === 'on') {
                    txt.textContent = 'Desligar VNC';
                    btn.classList.add('vnc-active-blink');
                    btn.classList.add('btn-danger');
                    btn.classList.remove('btn-success');
                    if (lnk) lnk.classList.remove('hidden');
                } else {
                    txt.textContent = 'Ligar VNC';
                    btn.classList.remove('vnc-active-blink');
                    btn.classList.remove('btn-danger');
                    btn.classList.remove('btn-success');
                    if (lnk) lnk.classList.add('hidden');
                }
            } catch (e) {}
        }

        // Theme management
        function toggleTheme() {
            const html = document.documentElement;
            const isDark = html.dataset.theme !== 'light';
            html.dataset.theme = isDark ? 'light' : 'dark';
            localStorage.setItem('theme', html.dataset.theme);
            updateThemeIcon(!isDark);
        }

        function updateThemeIcon(isLight) {
            const sun = document.getElementById('icon-sun');
            const moon = document.getElementById('icon-moon');
            if (isLight) {
                sun.classList.remove('hidden');
                moon.classList.add('hidden');
            } else {
                sun.classList.add('hidden');
                moon.classList.remove('hidden');
            }
        }

        const savedTheme = localStorage.getItem('theme');
        if (savedTheme) {
            document.documentElement.dataset.theme = savedTheme;
            updateThemeIcon(savedTheme === 'light');
        }

        // Stats
        async function fetchStats() {
            try {
                const res = await apiFetch('/api/status');
                const data = await res.json();

                const cpuVal = document.getElementById('cpu-val');
                const cpuBar = document.getElementById('cpu-bar');
                if (cpuVal) cpuVal.textContent = data.cpu + '%';
                if (cpuBar) {
                    cpuBar.style.width = data.cpu + '%';
                    cpuBar.className = 'progress-bar' + (data.cpu > 80 ? ' danger' : data.cpu > 60 ? ' warning' : '');
                }

                const ramVal = document.getElementById('ram-val');
                const ramBar = document.getElementById('ram-bar');
                if (ramVal) ramVal.textContent = data.ram.used + ' / ' + data.ram.total + ' GB';
                if (ramBar) ramBar.style.width = data.ram.percent + '%';

                const diskVal = document.getElementById('disk-val');
                const diskBar = document.getElementById('disk-bar');
                if (diskVal) diskVal.textContent = data.disk.percent + '%';
                if (diskBar) {
                    diskBar.style.width = data.disk.percent + '%';
                    diskBar.className = 'progress-bar' + (data.disk.percent > 90 ? ' danger' : data.disk.percent > 75 ? ' warning' : '');
                }

                const status = document.getElementById('bot-status');
                if (status) {
                    status.textContent = 'Online';
                    status.classList.remove('offline');
                }
            } catch (e) {
                const status = document.getElementById('bot-status');
                if (status) {
                    status.textContent = 'Offline';
                    status.classList.add('offline');
                }
            }
        }
        setInterval(() => { fetchStats(); }, 3000);

        // Actions
        async function executeAction(type) {
            const messages = {
                reboot_vps: '⚠️ Confirma reboot CRÍTICO da VPS?',
                clear_cache: 'Limpar cache do servidor?',
                restart_bot: 'Reiniciar o agente AI?',
                toggle_vnc: null
            };

            if (messages[type] && !confirm(messages[type])) return;

            try {
                const res = await apiFetch('/api/action', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ type })
                });
                const data = await res.json();
                showToast(data.message || 'Ação executada!');
            } catch (e) {
                showToast('Erro ao executar.', true);
            }
        }

        function showToast(msg, isError = false) {
            const toast = document.getElementById('toast');
            if (!toast) return;
            toast.textContent = msg;
            toast.className = isError ? 'error show' : 'show';
            setTimeout(() => toast.classList.remove('show'), 3000);
        }

        async function sendChat() {
            const input = document.getElementById('chat-input');
            const text = input.value.trim();
            if (!text) return;

            addBubble(text, 'user');
            input.value = '';

            try {
                const res = await apiFetch('/api/chat', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ text, history: chatHistory })
                });
                const data = await res.json();
                processAIReply(data.reply);
            } catch (e) {
                addBubble('Erro ao contatar servidor.', 'ai');
            }
        }

        function processAIReply(fullText) {
            // Separa a parte técnica do resumo (RESUMO:)
            const refinedMatch = fullText.match(/RESUMO:\s*([\s\S]*)/i);

            let technicalPart = fullText;
            if (refinedMatch) {
                technicalPart = fullText.substring(0, refinedMatch.index).trim();
                const refinedContent = refinedMatch[1].trim();
                updateInsightsPanel(refinedContent);
            }

            if (technicalPart) {
                addBubble(technicalPart, 'ai');
            }
        }

        function updateInsightsPanel(markdown) {
            const panel = document.getElementById('insights-panel');
            if (!panel) return;

            // Garante que temos a senha (tenta pegar do global ou do localStorage se precisar)
            const activePwd = webPassword || localStorage.getItem('vps_web_password') || '';

            // Transforma caminhos da VPS (![alt](/host_root/...) em links da nossa API segura
            // Ex: /host_root/root/img.jpg -> /api/host_file?pwd=...&path=/host_root/root/img.jpg
            let mdWithAuth = markdown.replace(/!\[(.*?)\]\((\/host_root\/.*?)\)/g, (match, alt, path) => {
                return `![${alt}](/api/host_file?pwd=${encodeURIComponent(activePwd)}&path=${encodeURIComponent(path)})`;
            });

            // Fallback para qualquer outro caso que tenha sobrado do prefixo antigo
            mdWithAuth = mdWithAuth.replace(/\/api\/host_file\?path=/g, '/api/host_file?pwd=' + encodeURIComponent(activePwd) + '&path=');

            // Renderiza o Markdown para HTML usando marked.js
            panel.innerHTML = `<div class="animate-fade-in">${marked.parse(mdWithAuth)}</div>`;
        }

        function handleKeyPress(e) {
            if (e.key === 'Enter') sendChat();
        }

        function addBubble(text, sender) {
            const box = document.getElementById('chat-box');
            if (!box) return;
            const div = document.createElement('div');
            div.className = 'chat-bubble bubble-' + sender;
            div.textContent = text;
            box.appendChild(div);
            box.scrollTop = box.scrollHeight;

            // Atualiza o histórico local (limita a 10 mensagens)
            if (sender === 'user') {
                chatHistory.push({ user: text, bot: "" });
            } else if (chatHistory.length > 0) {
                chatHistory[chatHistory.length - 1].bot = text;
            }
            if (chatHistory.length > 10) chatHistory.shift();
        }

        async function loadConfig() {
            try {
                const res = await apiFetch('/api/config');
                const data = await res.json();
                const provider = document.getElementById('active_provider');
                const model = document.getElementById('openrouter_model');
                
                if (provider) provider.value = data.active_provider || 'minimax';
                if (model) model.value = data.openrouter_model || 'qwen/qwen-2.5-72b-instruct';
                
                toggleProviderFields();
            } catch (e) { }
        }

        function toggleProviderFields() {
            const provider = document.getElementById('active_provider').value;
            const modelGroup = document.getElementById('group-openrouter-model');
            if (modelGroup) {
                modelGroup.style.display = (provider === 'openrouter') ? 'block' : 'none';
            }
        }

        async function saveConfig() {
            const provider = document.getElementById('active_provider').value;
            const model = document.getElementById('openrouter_model').value.trim();

            try {
                const res = await apiFetch('/api/config', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({ active_provider: provider, openrouter_model: model })
                });
                if (res.ok) {
                    showToast('Configurações salvas!');
                    loadConfig();
                } else {
                    throw new Error();
                }
            } catch (e) {
                showToast('Erro ao salvar.', true);
            }
        }

        // ================== ORCHESTRATOR LLM CONFIG ==================
        
        let availableModels = {};
        
        async function loadOrchestratorStatus() {
            try {
                const res = await apiFetch('/api/orchestrator-status');
                const data = await res.json();
                
                const statusEl = document.getElementById('orchestrator-status');
                if (statusEl) {
                    statusEl.innerHTML = '<strong>Planner:</strong> ' + data.planner.name + ' | <strong>Executor:</strong> ' + data.executor.name + ' | <strong>Ferramentas:</strong> ' + data.available_tools;
                }
                
                // Repo status
                const repoEl = document.getElementById('repo-status');
                if (repoEl) {
                    const creds = data.credentials || {};
                    const giteaRepo = creds.gitea_repo || {};
                    if (giteaRepo.available) {
                        repoEl.innerHTML = '<span style="color: var(--success);">✅ Online</span> - ' + giteaRepo.services_count + ' serviço(s) disponível(is)';
                    } else {
                        repoEl.innerHTML = '<span style="color: var(--text-muted);">⏳ Sincronizando...</span>';
                    }
                }
            } catch (e) {
                const statusEl = document.getElementById('orchestrator-status');
                if (statusEl) statusEl.textContent = 'Erro ao carregar';
            }
        }
        
        async function syncFromRepo() {
            try {
                const res = await apiFetch('/api/sync-from-repo', { method: 'POST' });
                const data = await res.json();
                if (data.status === 'synced') {
                    showToast('Repo sincronizado! ' + data.services_count + ' serviços carregados');
                } else {
                    showToast('Erro ao sincronizar repo: ' + data.status, true);
                }
                loadOrchestratorStatus();
                loadCredentials();
            } catch (e) {
                showToast('Erro ao sincronizar repo.', true);
            }
        }
        
        async function loadLLMModels() {
            try {
                const res = await apiFetch('/api/llm-models');
                availableModels = await res.json();
            } catch (e) {
                console.error('Erro ao carregar modelos:', e);
            }
        }
        
        async function loadLLMConfig() {
            try {
                const res = await apiFetch('/api/llm-config');
                const data = await res.json();
                
                // Planner
                const plannerProvider = document.getElementById('planner_provider');
                const plannerModel = document.getElementById('planner_model');
                if (plannerProvider) plannerProvider.value = data.planner.provider;
                await loadPlannerModels();
                if (plannerModel && data.planner.model) {
                    plannerModel.value = data.planner.model;
                }
                
                // Executor
                const executorProvider = document.getElementById('executor_provider');
                const executorModel = document.getElementById('executor_model');
                if (executorProvider) executorProvider.value = data.executor.provider;
                await loadExecutorModels();
                if (executorModel && data.executor.model) {
                    executorModel.value = data.executor.model;
                }
            } catch (e) {
                console.error('Erro ao carregar config LLM:', e);
            }
        }
        
        function populateModelSelect(selectEl, models) {
            if (!selectEl) return;
            selectEl.innerHTML = '';
            
            if (!models || models.length === 0) {
                selectEl.innerHTML = '<option value="">Nenhum modelo</option>';
                return;
            }
            
            models.forEach(function(model) {
                const opt = document.createElement('option');
                opt.value = model;
                opt.textContent = model;
                selectEl.appendChild(opt);
            });
        }
        
        async function loadPlannerModels() {
            const provider = document.getElementById('planner_provider')?.value;
            const modelSelect = document.getElementById('planner_model');
            if (!modelSelect) return;
            
            modelSelect.innerHTML = '<option value="">Carregando...</option>';
            
            if (provider === 'ollama') {
                const models = availableModels.models?.find(function(p) { return p.provider === 'ollama'; })?.models || [];
                populateModelSelect(modelSelect, models.length > 0 ? models : ['qwen2.5-coder:1.5b', 'llama3.1:8b', 'codellama:13b']);
            } else {
                const fixedModels = {
                    gemini: ['gemini-2.5-flash', 'gemini-2.0-pro', 'gemini-1.5-flash'],
                    openai: ['gpt-4o', 'gpt-4-turbo', 'gpt-3.5-turbo'],
                    anthropic: ['claude-3-5-sonnet-20241022', 'claude-3-5-haiku-20241022', 'claude-3-opus-20240229']
                };
                populateModelSelect(modelSelect, fixedModels[provider] || []);
            }
        }
        
        async function loadExecutorModels() {
            const provider = document.getElementById('executor_provider')?.value;
            const modelSelect = document.getElementById('executor_model');
            if (!modelSelect) return;
            
            modelSelect.innerHTML = '<option value="">Carregando...</option>';
            
            if (provider === 'ollama') {
                const models = availableModels.models?.find(function(p) { return p.provider === 'ollama'; })?.models || [];
                populateModelSelect(modelSelect, models.length > 0 ? models : ['qwen2.5-coder:1.5b', 'llama3.1:8b', 'codellama:13b']);
            } else if (provider === 'gemini') {
                populateModelSelect(modelSelect, ['gemini-2.5-flash', 'gemini-2.0-pro']);
            } else {
                populateModelSelect(modelSelect, []);
            }
        }
        
        async function saveLLMConfig() {
            const plannerProvider = document.getElementById('planner_provider')?.value;
            const plannerModel = document.getElementById('planner_model')?.value;
            const executorProvider = document.getElementById('executor_provider')?.value;
            const executorModel = document.getElementById('executor_model')?.value;
            
            try {
                const res = await apiFetch('/api/llm-config', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        planner_provider: plannerProvider,
                        planner_model: plannerModel,
                        executor_provider: executorProvider,
                        executor_model: executorModel
                    })
                });
                
                if (res.ok) {
                    showToast('Config LLM salva! Planner: ' + plannerProvider + ', Executor: ' + executorProvider);
                    loadOrchestratorStatus();
                } else {
                    throw new Error();
                }
            } catch (e) {
                showToast('Erro ao salvar config LLM.', true);
            }
        }
        
        async function syncCredentials() {
            try {
                const res = await apiFetch('/api/sync-credentials', {
                    method: 'POST'
                });
                const data = await res.json();
                showToast('Credenciais sincronizadas! Services: ' + Object.keys(data.services || {}).length);
            } catch (e) {
                showToast('Erro ao sincronizar.', true);
            }
        }
        
        async function loadCredentials() {
            const loadingEl = document.getElementById('credentials-loading');
            const containerEl = document.getElementById('credentials-container');
            const listEl = document.getElementById('credentials-list');
            
            if (loadingEl) loadingEl.innerHTML = 'Carregando...';
            
            try {
                // Sync first
                await apiFetch('/api/sync-credentials', { method: 'POST' });
                
                // Get orchestrator status which has services info
                const res = await apiFetch('/api/orchestrator-status');
                const data = await res.json();
                
                const services = data.credentials || {};
                const serviceNames = {
                    coolify: 'Coolify (Orquestrador)',
                    supabase: 'Supabase (BaaS)',
                    gitea: 'Gitea (Git Server)',
                    logto: 'Logto (Autenticação)'
                };
                
                let html = '<div style="display: grid; gap: 1rem;">';
                
                for (const [key, info] of Object.entries(services)) {
                    const name = serviceNames[key] || key;
                    const status = info.exists ? '<span style="color: var(--success);">Disponivel</span>' : '<span style="color: var(--danger);">Nao disponivel</span>';
                    const keysCount = info.keys_count || 0;
                    
                    html += `
                        <div style="padding: 1rem; background: var(--bg-input); border-radius: 8px; border: 1px solid var(--border);">
                            <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 0.5rem;">
                                <strong style="color: var(--accent);">${name}</strong>
                                ${status}
                            </div>
                            <div style="font-size: 0.75rem; color: var(--text-muted); margin-bottom: 0.5rem;">
                                Caminho: <code style="background: var(--bg-base); padding: 0.1rem 0.3rem; border-radius: 4px;">${info.path || 'N/A'}</code>
                            </div>
                            <div style="font-size: 0.75rem; color: var(--text-muted);">
                                ${keysCount} chave(s) encontrada(s)
                            </div>
                        </div>
                    `;
                }
                
                html += '</div>';
                
                if (loadingEl) loadingEl.style.display = 'none';
                if (containerEl) containerEl.style.display = 'block';
                if (listEl) listEl.innerHTML = html;
                
            } catch (e) {
                if (loadingEl) {
                    loadingEl.innerHTML = 'Erro ao carregar credenciais';
                    loadingEl.style.color = 'var(--danger)';
                }
                console.error('Erro ao carregar credenciais:', e);
            }
        }
        
        async function copyToClipboard(text, label) {
            try {
                await navigator.clipboard.writeText(text);
                showToast(label + ' copiado!');
            } catch (e) {
                showToast('Erro ao copiar.', true);
            }
        }

        async function testLLMSpeed() {
            const btn = document.getElementById('btn-test-llm');
            const originalContent = btn.innerHTML;
            btn.innerHTML = '⚡ Testando...';
            btn.disabled = true;

            try {
                const res = await apiFetch('/api/test_llm');
                const data = await res.json();
                if (data.status === 'success') {
                    showToast(`✅ LLM Online! Resposta em ${data.latency}s`);
                    btn.innerHTML = `✅ ${data.latency}s`;
                    setTimeout(() => { btn.innerHTML = originalContent; btn.disabled = false; }, 5000);
                } else {
                    throw new Error(data.message);
                }
            } catch (e) {
                showToast("❌ Erro no Teste LLM: " + e.message, true);
                btn.innerHTML = '❌ Falhou';
                btn.classList.add('btn-danger');
                setTimeout(() => {
                    btn.innerHTML = originalContent;
                    btn.disabled = false;
                    btn.classList.remove('btn-danger');
                }, 5000);
            }
        }

        window.saveConfiguration = saveConfig;
        window.sendMessage = sendChat;
        window.executeAction = executeAction;
        window.testLLMSpeed = testLLMSpeed;

        // --- AUDIO SYSTEM ---
        let mediaRecorder;
        let audioChunks = [];
        let isRecording = false;

        async function toggleRecording() {
            if (!isRecording) {
                try {
                    const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
                    mediaRecorder = new MediaRecorder(stream);
                    audioChunks = [];

                    mediaRecorder.ondataavailable = (event) => {
                        audioChunks.push(event.data);
                    };

                    mediaRecorder.onstop = async () => {
                        const audioBlob = new Blob(audioChunks, { type: 'audio/webm' });
                        await uploadAudio(audioBlob);
                    };

                    mediaRecorder.start();
                    isRecording = true;
                    updateMicUI(true);
                } catch (err) {
                    showToast("Erro ao acessar microfone", true);
                }
            } else {
                mediaRecorder.stop();
                mediaRecorder.stream.getTracks().forEach(t => t.stop());
                isRecording = false;
                updateMicUI(false);
            }
        }

        function updateMicUI(active) {
            const dot = document.getElementById('recording-dot');
            const btn = document.getElementById('audio-btn');

            if (active) {
                dot.classList.remove('hidden');
                btn.classList.add('mic-active');
            } else {
                dot.classList.add('hidden');
                btn.classList.remove('mic-active');
            }
        }

        async function uploadAudio(blob) {
            const formData = new FormData();
            formData.append('audio', blob, 'voice.webm');

            showToast("✨ Transcrevendo áudio...");

            try {
                const res = await apiFetch('/api/chat-audio', {
                    method: 'POST',
                    body: formData
                });
                const data = await res.json();

                if (data.text) {
                    addBubble(data.text, 'user');
                    processAIReply(data.reply);

                    // Se o bot retornou áudio, toca ele
                    if (data.audio_url) {
                        const audio = new Audio(data.audio_url + '?t=' + Date.now());
                        audio.play();
                    }
                }
            } catch (e) {
                showToast("Erro ao processar áudio", true);
            }
        }

        window.toggleRecording = toggleRecording;

        function checkAuth() {
            const pass = document.getElementById('login-pass').value;
            if (pass === '@@Gi05Br;;') {
                sessionStorage.setItem('botAuth', 'true');
                document.getElementById('login-overlay').classList.add('hidden');
                initDashboard();
            } else {
                document.getElementById('login-error').classList.remove('hidden');
                setTimeout(() => document.getElementById('login-error').classList.add('hidden'), 2000);
            }
        }

        // Enter key support
        document.getElementById('login-pass').addEventListener('keypress', (e) => {
            if (e.key === 'Enter') checkAuth();
        });

        // Skip auth if already logged in via session
        if (sessionStorage.getItem('botAuth') === 'true') {
            document.getElementById('login-overlay').classList.add('hidden');
            initDashboard();
        }
    </script>
</body>

</html>