<!DOCTYPE html>
<!--
  Familiar - Self-hosted AI Agent
  Copyright (c) 2026 George Scott Foley
  
  Licensed under the MIT License
  For commercial licensing, contact: licensing@familiar.ai
-->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Familiar Dashboard</title>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" rel="stylesheet">
    <style>
        :root {
            --bg-dark: #0f0f1a;
            --bg-card: #1a1a2e;
            --bg-input: #252540;
            --accent: #e94560;
            --accent-hover: #ff6b6b;
            --text: #eaeaea;
            --text-dim: #888;
            --success: #4ade80;
            --warning: #fbbf24;
            --error: #f87171;
            --border: #333;
        }
        
        * { margin: 0; padding: 0; box-sizing: border-box; }
        
        body {
            font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif;
            background: var(--bg-dark);
            color: var(--text);
            min-height: 100vh;
        }
        
        /* Layout */
        .app {
            display: grid;
            grid-template-columns: 240px 1fr 320px;
            grid-template-rows: 64px 1fr;
            height: 100vh;
        }
        
        @media (max-width: 1200px) {
            .app { grid-template-columns: 240px 1fr; }
            .right-panel { display: none; }
        }
        
        @media (max-width: 768px) {
            .app { grid-template-columns: 1fr; }
            .sidebar { display: none; }
        }
        
        /* Header */
        header {
            grid-column: 1 / -1;
            background: var(--bg-card);
            border-bottom: 1px solid var(--border);
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 24px;
        }
        
        .logo {
            display: flex;
            align-items: center;
            gap: 12px;
            font-size: 1.25rem;
            font-weight: 700;
        }
        
        .logo i { color: var(--accent); }
        
        .status-badge {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 8px 16px;
            background: var(--bg-input);
            border-radius: 20px;
            font-size: 0.875rem;
        }
        
        .status-dot {
            width: 8px;
            height: 8px;
            border-radius: 50%;
            background: var(--success);
            animation: pulse 2s infinite;
        }
        
        @keyframes pulse {
            0%, 100% { opacity: 1; }
            50% { opacity: 0.5; }
        }
        
        /* Sidebar */
        .sidebar {
            background: var(--bg-card);
            border-right: 1px solid var(--border);
            padding: 20px 12px;
            overflow-y: auto;
        }
        
        .nav-section {
            margin-bottom: 24px;
        }
        
        .nav-section h4 {
            font-size: 0.7rem;
            text-transform: uppercase;
            color: var(--text-dim);
            padding: 0 12px;
            margin-bottom: 8px;
        }
        
        .nav-item {
            display: flex;
            align-items: center;
            gap: 12px;
            padding: 12px;
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.2s;
            color: var(--text-dim);
        }
        
        .nav-item:hover {
            background: var(--bg-input);
            color: var(--text);
        }
        
        .nav-item.active {
            background: var(--accent);
            color: white;
        }
        
        .nav-item i { width: 20px; text-align: center; }
        
        /* Main content */
        main {
            display: flex;
            flex-direction: column;
            overflow: hidden;
        }
        
        .panel {
            flex: 1;
            padding: 24px;
            overflow-y: auto;
            display: none;
        }
        
        .panel.active { display: block; }
        
        .panel-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 24px;
        }
        
        .panel-header h2 {
            font-size: 1.5rem;
        }
        
        /* Chat */
        #chat-panel {
            display: none;
            flex-direction: column;
        }
        
        #chat-panel.active { display: flex; }
        
        .messages {
            flex: 1;
            overflow-y: auto;
            padding: 24px;
            display: flex;
            flex-direction: column;
            gap: 16px;
        }
        
        .message {
            max-width: 75%;
            padding: 14px 18px;
            border-radius: 16px;
            line-height: 1.5;
        }
        
        .message.user {
            align-self: flex-end;
            background: var(--accent);
            border-bottom-right-radius: 4px;
        }
        
        .message.assistant {
            align-self: flex-start;
            background: var(--bg-card);
            border-bottom-left-radius: 4px;
        }
        
        .message pre {
            background: var(--bg-dark);
            padding: 12px;
            border-radius: 8px;
            margin-top: 8px;
            overflow-x: auto;
            font-size: 0.875rem;
        }
        
        .chat-input-wrap {
            display: flex;
            gap: 12px;
            padding: 20px 24px;
            background: var(--bg-card);
            border-top: 1px solid var(--border);
        }
        
        .chat-input {
            flex: 1;
            padding: 14px 18px;
            border: none;
            border-radius: 12px;
            background: var(--bg-input);
            color: var(--text);
            font-size: 1rem;
        }
        
        .chat-input:focus {
            outline: 2px solid var(--accent);
        }
        
        .send-btn {
            padding: 14px 24px;
            border: none;
            border-radius: 12px;
            background: var(--accent);
            color: white;
            cursor: pointer;
            font-weight: 600;
            display: flex;
            align-items: center;
            gap: 8px;
            transition: background 0.2s;
        }
        
        .send-btn:hover { background: var(--accent-hover); }
        
        .send-btn:disabled {
            opacity: 0.5;
            cursor: not-allowed;
        }
        
        /* Cards */
        .card {
            background: var(--bg-card);
            border-radius: 12px;
            padding: 20px;
            margin-bottom: 16px;
        }
        
        .card h3 {
            font-size: 0.875rem;
            color: var(--text-dim);
            margin-bottom: 12px;
        }
        
        .stat-row {
            display: flex;
            justify-content: space-between;
            padding: 10px 0;
            border-bottom: 1px solid var(--border);
        }
        
        .stat-row:last-child { border-bottom: none; }
        
        .stat-value { color: var(--accent); font-weight: 600; }
        
        /* Lists */
        .list-item {
            display: flex;
            align-items: flex-start;
            gap: 12px;
            padding: 14px;
            background: var(--bg-card);
            border-radius: 10px;
            margin-bottom: 10px;
        }
        
        .list-item .icon {
            width: 40px;
            height: 40px;
            border-radius: 10px;
            background: var(--bg-input);
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
        }
        
        .list-item .content { flex: 1; }
        .list-item .title { font-weight: 500; }
        .list-item .meta { font-size: 0.8rem; color: var(--text-dim); margin-top: 4px; }
        
        /* Task specific */
        .task-checkbox {
            width: 22px;
            height: 22px;
            border: 2px solid var(--accent);
            border-radius: 6px;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            flex-shrink: 0;
        }
        
        .task-checkbox.done {
            background: var(--success);
            border-color: var(--success);
        }
        
        .task-checkbox.done i { color: white; }
        
        .priority-urgent { color: var(--error); }
        .priority-high { color: var(--warning); }
        .priority-normal { color: var(--success); }
        
        /* Toggle */
        .toggle {
            width: 48px;
            height: 26px;
            background: var(--bg-input);
            border-radius: 13px;
            cursor: pointer;
            position: relative;
            transition: background 0.3s;
        }
        
        .toggle.on { background: var(--success); }
        
        .toggle::after {
            content: '';
            position: absolute;
            width: 22px;
            height: 22px;
            background: white;
            border-radius: 50%;
            top: 2px;
            left: 2px;
            transition: left 0.3s;
        }
        
        .toggle.on::after { left: 24px; }
        
        /* Right panel */
        .right-panel {
            background: var(--bg-card);
            border-left: 1px solid var(--border);
            padding: 20px;
            overflow-y: auto;
        }
        
        /* Node item */
        .node-item {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px;
            background: var(--bg-input);
            border-radius: 8px;
            margin-bottom: 8px;
        }
        
        .node-dot {
            width: 10px;
            height: 10px;
            border-radius: 50%;
            background: var(--success);
        }
        
        .node-dot.offline { background: var(--error); }
        
        /* Buttons */
        .btn {
            padding: 10px 20px;
            border: none;
            border-radius: 8px;
            cursor: pointer;
            font-weight: 500;
            transition: all 0.2s;
        }
        
        .btn-primary {
            background: var(--accent);
            color: white;
        }
        
        .btn-primary:hover { background: var(--accent-hover); }
        
        .btn-secondary {
            background: var(--bg-input);
            color: var(--text);
        }
        
        .btn-secondary:hover { background: var(--border); }
        
        /* Inputs */
        input, select, textarea {
            padding: 12px 16px;
            border: none;
            border-radius: 8px;
            background: var(--bg-input);
            color: var(--text);
            font-size: 1rem;
            width: 100%;
        }
        
        input:focus, select:focus, textarea:focus {
            outline: 2px solid var(--accent);
        }
        
        /* Modal */
        .modal-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0,0,0,0.7);
            display: none;
            align-items: center;
            justify-content: center;
            z-index: 100;
        }
        
        .modal-overlay.show { display: flex; }
        
        .modal {
            background: var(--bg-card);
            border-radius: 16px;
            padding: 24px;
            width: 90%;
            max-width: 500px;
        }
        
        .modal h3 { margin-bottom: 20px; }
        
        .modal .form-group {
            margin-bottom: 16px;
        }
        
        .modal .form-group label {
            display: block;
            margin-bottom: 6px;
            font-size: 0.875rem;
            color: var(--text-dim);
        }
        
        .modal .actions {
            display: flex;
            gap: 12px;
            justify-content: flex-end;
            margin-top: 24px;
        }
        
        /* Loading */
        .loading {
            text-align: center;
            padding: 40px;
            color: var(--text-dim);
        }
        
        .spinner {
            display: inline-block;
            width: 30px;
            height: 30px;
            border: 3px solid var(--bg-input);
            border-top-color: var(--accent);
            border-radius: 50%;
            animation: spin 1s linear infinite;
        }
        
        @keyframes spin {
            to { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div class="app">
        <!-- Header -->
        <header>
            <div class="logo">
                <i class="fas fa-dragon"></i>
                <span>Pi Agent</span>
            </div>
            <div class="status-badge">
                <div class="status-dot" id="status-dot"></div>
                <span id="status-text">Connecting...</span>
            </div>
        </header>
        
        <!-- Sidebar -->
        <nav class="sidebar">
            <div class="nav-section">
                <h4>Main</h4>
                <div class="nav-item active" data-panel="chat">
                    <i class="fas fa-comments"></i>
                    <span>Chat</span>
                </div>
                <div class="nav-item" data-panel="briefing">
                    <i class="fas fa-sun"></i>
                    <span>Briefing</span>
                </div>
                <div class="nav-item" data-panel="email">
                    <i class="fas fa-envelope"></i>
                    <span>Email Triage</span>
                </div>
            </div>
            
            <div class="nav-section">
                <h4>Manage</h4>
                <div class="nav-item" data-panel="tasks">
                    <i class="fas fa-check-square"></i>
                    <span>Tasks</span>
                </div>
                <div class="nav-item" data-panel="memory">
                    <i class="fas fa-brain"></i>
                    <span>Memory</span>
                </div>
                <div class="nav-item" data-panel="skills">
                    <i class="fas fa-puzzle-piece"></i>
                    <span>Skills</span>
                </div>
            </div>
            
            <div class="nav-section">
                <h4>System</h4>
                <div class="nav-item" data-panel="nodes">
                    <i class="fas fa-network-wired"></i>
                    <span>Mesh Nodes</span>
                </div>
                <div class="nav-item" data-panel="settings">
                    <i class="fas fa-cog"></i>
                    <span>Settings</span>
                </div>
            </div>
        </nav>
        
        <!-- Main Content -->
        <main>
            <!-- Chat Panel -->
            <div id="chat-panel" class="panel active">
                <div class="messages" id="messages">
                    <div class="message assistant">
                        <p>👋 Hi! I'm your Pi Agent. How can I help you today?</p>
                    </div>
                </div>
                <div class="chat-input-wrap">
                    <input type="text" class="chat-input" id="chat-input" placeholder="Type a message..." />
                    <button class="send-btn" id="send-btn" onclick="sendMessage()">
                        <i class="fas fa-paper-plane"></i>
                        Send
                    </button>
                </div>
            </div>
            
            <!-- Briefing Panel -->
            <div id="briefing-panel" class="panel">
                <div class="panel-header">
                    <h2>Daily Briefing</h2>
                    <button class="btn btn-primary" onclick="loadBriefing()">
                        <i class="fas fa-sync"></i> Refresh
                    </button>
                </div>
                <div id="briefing-content" class="card">
                    <div class="loading"><div class="spinner"></div></div>
                </div>
            </div>
            
            <!-- Email Panel -->
            <div id="email-panel" class="panel">
                <div class="panel-header">
                    <h2>Email Triage</h2>
                    <button class="btn btn-primary" onclick="loadEmailTriage()">
                        <i class="fas fa-sync"></i> Refresh
                    </button>
                </div>
                <div id="email-content">
                    <div class="loading"><div class="spinner"></div></div>
                </div>
            </div>
            
            <!-- Tasks Panel -->
            <div id="tasks-panel" class="panel">
                <div class="panel-header">
                    <h2>Tasks</h2>
                    <button class="btn btn-primary" onclick="showAddTaskModal()">
                        <i class="fas fa-plus"></i> Add Task
                    </button>
                </div>
                <div id="tasks-list">
                    <div class="loading"><div class="spinner"></div></div>
                </div>
            </div>
            
            <!-- Memory Panel -->
            <div id="memory-panel" class="panel">
                <div class="panel-header">
                    <h2>Memory</h2>
                    <button class="btn btn-primary" onclick="showAddMemoryModal()">
                        <i class="fas fa-plus"></i> Add Memory
                    </button>
                </div>
                <div id="memory-list">
                    <div class="loading"><div class="spinner"></div></div>
                </div>
            </div>
            
            <!-- Skills Panel -->
            <div id="skills-panel" class="panel">
                <div class="panel-header">
                    <h2>Skills</h2>
                </div>
                <div id="skills-list">
                    <div class="loading"><div class="spinner"></div></div>
                </div>
            </div>
            
            <!-- Nodes Panel -->
            <div id="nodes-panel" class="panel">
                <div class="panel-header">
                    <h2>Mesh Network</h2>
                </div>
                <div id="nodes-content">
                    <div class="loading"><div class="spinner"></div></div>
                </div>
            </div>
            
            <!-- Settings Panel -->
            <div id="settings-panel" class="panel">
                <div class="panel-header">
                    <h2>Settings</h2>
                </div>
                
                <div class="card">
                    <h3>LLM Provider</h3>
                    <select id="provider-select" onchange="changeProvider(this.value)">
                        <option value="anthropic">Claude (Anthropic)</option>
                        <option value="openai">GPT (OpenAI)</option>
                        <option value="ollama">Ollama (Local)</option>
                    </select>
                </div>
                
                <div class="card">
                    <h3>Agent</h3>
                    <div class="stat-row">
                        <span>Name</span>
                        <span id="setting-name" class="stat-value">Pi Agent</span>
                    </div>
                    <div class="stat-row">
                        <span>Memory</span>
                        <div class="toggle on" id="toggle-memory"></div>
                    </div>
                    <div class="stat-row">
                        <span>Skills</span>
                        <div class="toggle on" id="toggle-skills"></div>
                    </div>
                </div>
                
                <div class="card">
                    <h3>Mesh Gateway</h3>
                    <div class="stat-row">
                        <span>Status</span>
                        <span id="gateway-status" class="stat-value">Running</span>
                    </div>
                    <div class="stat-row">
                        <span>Port</span>
                        <span class="stat-value">18789</span>
                    </div>
                    <div style="margin-top: 12px;">
                        <button class="btn btn-secondary" onclick="showMeshKey()">
                            <i class="fas fa-key"></i> Show Secret Key
                        </button>
                    </div>
                </div>
            </div>
        </main>
        
        <!-- Right Panel -->
        <aside class="right-panel">
            <div class="card">
                <h3>System Status</h3>
                <div class="stat-row">
                    <span>Provider</span>
                    <span class="stat-value" id="stat-provider">Loading...</span>
                </div>
                <div class="stat-row">
                    <span>Memory</span>
                    <span class="stat-value" id="stat-memory">0 entries</span>
                </div>
                <div class="stat-row">
                    <span>Skills</span>
                    <span class="stat-value" id="stat-skills">0</span>
                </div>
                <div class="stat-row">
                    <span>Tools</span>
                    <span class="stat-value" id="stat-tools">0</span>
                </div>
            </div>
            
            <div class="card">
                <h3>Connected Nodes</h3>
                <div id="nodes-sidebar">
                    <div class="node-item">
                        <div class="node-dot"></div>
                        <div>
                            <div style="font-weight: 500;">Gateway</div>
                            <div style="font-size: 0.75rem; color: var(--text-dim);">This device</div>
                        </div>
                    </div>
                </div>
            </div>
            
            <div class="card">
                <h3>Quick Actions</h3>
                <button class="btn btn-secondary" style="width: 100%; margin-bottom: 8px;" onclick="quickCommand('daily_briefing')">
                    <i class="fas fa-sun"></i> Morning Briefing
                </button>
                <button class="btn btn-secondary" style="width: 100%; margin-bottom: 8px;" onclick="quickCommand('triage_inbox')">
                    <i class="fas fa-envelope"></i> Sort Inbox
                </button>
                <button class="btn btn-secondary" style="width: 100%;" onclick="quickCommand('check_deadlines')">
                    <i class="fas fa-clock"></i> Check Deadlines
                </button>
            </div>
        </aside>
    </div>
    
    <!-- Add Task Modal -->
    <div class="modal-overlay" id="task-modal">
        <div class="modal">
            <h3>Add Task</h3>
            <div class="form-group">
                <label>Title</label>
                <input type="text" id="task-title" placeholder="What needs to be done?" />
            </div>
            <div class="form-group">
                <label>Priority</label>
                <select id="task-priority">
                    <option value="normal">Normal</option>
                    <option value="high">High</option>
                    <option value="urgent">Urgent</option>
                    <option value="low">Low</option>
                </select>
            </div>
            <div class="form-group">
                <label>Due Date</label>
                <input type="text" id="task-due" placeholder="tomorrow, next week, 2024-03-15" />
            </div>
            <div class="form-group">
                <label>Category</label>
                <select id="task-category">
                    <option value="general">General</option>
                    <option value="grants">Grants</option>
                    <option value="donors">Donors</option>
                    <option value="board">Board</option>
                    <option value="events">Events</option>
                    <option value="compliance">Compliance</option>
                </select>
            </div>
            <div class="actions">
                <button class="btn btn-secondary" onclick="hideModal('task-modal')">Cancel</button>
                <button class="btn btn-primary" onclick="addTask()">Add Task</button>
            </div>
        </div>
    </div>
    
    <!-- Add Memory Modal -->
    <div class="modal-overlay" id="memory-modal">
        <div class="modal">
            <h3>Add Memory</h3>
            <div class="form-group">
                <label>Key</label>
                <input type="text" id="memory-key" placeholder="e.g., user_name, favorite_color" />
            </div>
            <div class="form-group">
                <label>Value</label>
                <textarea id="memory-value" rows="3" placeholder="What should I remember?"></textarea>
            </div>
            <div class="form-group">
                <label>Category</label>
                <select id="memory-category">
                    <option value="fact">Fact</option>
                    <option value="preference">Preference</option>
                    <option value="user_info">User Info</option>
                    <option value="task">Task</option>
                </select>
            </div>
            <div class="actions">
                <button class="btn btn-secondary" onclick="hideModal('memory-modal')">Cancel</button>
                <button class="btn btn-primary" onclick="addMemory()">Save</button>
            </div>
        </div>
    </div>
    
    <script>
        // API base
        const API = '';
        
        // ── Auth layer ──
        // Read key from URL (?api_key=xxx), sessionStorage, or prompt user
        let _apiKey = new URLSearchParams(window.location.search).get('api_key')
                    || sessionStorage.getItem('familiar_api_key')
                    || '';
        
        // Clean the URL so the key isn't visible in the address bar
        if (window.location.search.includes('api_key')) {
            const url = new URL(window.location);
            url.searchParams.delete('api_key');
            window.history.replaceState({}, '', url);
        }
        
        if (_apiKey) sessionStorage.setItem('familiar_api_key', _apiKey);
        
        // Authenticated fetch wrapper
        function apiFetch(url, opts = {}) {
            opts.headers = opts.headers || {};
            if (_apiKey) opts.headers['X-API-Key'] = _apiKey;
            return fetch(url, opts).then(res => {
                if (res.status === 401) { showLoginOverlay(); throw new Error('Unauthorized'); }
                return res;
            });
        }
        
        function showLoginOverlay() {
            let overlay = document.getElementById('auth-overlay');
            if (overlay) { overlay.style.display = 'flex'; return; }
            overlay = document.createElement('div');
            overlay.id = 'auth-overlay';
            overlay.style.cssText = 'position:fixed;inset:0;background:rgba(15,15,26,0.95);display:flex;align-items:center;justify-content:center;z-index:9999;';
            overlay.innerHTML = `
                <div style="background:#1a1a2e;padding:40px;border-radius:12px;max-width:440px;width:90%;text-align:center;">
                    <h2 style="margin-bottom:8px;color:#eaeaea;">🦔 Familiar Dashboard</h2>
                    <p style="color:#888;margin-bottom:24px;font-size:14px;">Paste the API key from your terminal</p>
                    <input id="auth-key-input" type="text" placeholder="API key"
                        style="width:100%;padding:12px;background:#252540;border:1px solid #333;border-radius:6px;color:#eaeaea;font-family:monospace;font-size:14px;margin-bottom:16px;">
                    <button id="auth-submit-btn"
                        style="width:100%;padding:12px;background:#e94560;color:white;border:none;border-radius:6px;cursor:pointer;font-size:14px;font-weight:600;">
                        Connect
                    </button>
                    <p id="auth-error" style="color:#f87171;margin-top:12px;font-size:13px;display:none;">Invalid key — check your terminal output</p>
                </div>`;
            document.body.appendChild(overlay);
            const inp = document.getElementById('auth-key-input');
            inp.focus();
            inp.addEventListener('keypress', e => { if (e.key === 'Enter') tryAuth(); });
            document.getElementById('auth-submit-btn').addEventListener('click', tryAuth);
        }
        
        async function tryAuth() {
            const inp = document.getElementById('auth-key-input');
            const key = inp.value.trim();
            if (!key) return;
            try {
                const res = await apiFetch(API + '/api/status', { headers: { 'X-API-Key': key } });
                if (res.ok) {
                    _apiKey = key;
                    sessionStorage.setItem('familiar_api_key', key);
                    document.getElementById('auth-overlay').style.display = 'none';
                    loadStatus();
                } else {
                    document.getElementById('auth-error').style.display = 'block';
                }
            } catch(e) {
                document.getElementById('auth-error').style.display = 'block';
            }
        }
        
        // Verify auth on load
        if (!_apiKey) { showLoginOverlay(); }
        else { fetch(API + '/api/status', { headers: { 'X-API-Key': _apiKey } })
            .then(r => { if (r.status === 401) showLoginOverlay(); })
            .catch(() => {}); }
        
        
        // Navigation
        document.querySelectorAll('.nav-item').forEach(item => {
            item.addEventListener('click', () => {
                const panel = item.dataset.panel;
                
                document.querySelectorAll('.nav-item').forEach(n => n.classList.remove('active'));
                item.classList.add('active');
                
                document.querySelectorAll('.panel').forEach(p => p.classList.remove('active'));
                document.getElementById(panel + '-panel').classList.add('active');
                
                // Load data for panel
                switch(panel) {
                    case 'briefing': loadBriefing(); break;
                    case 'email': loadEmailTriage(); break;
                    case 'tasks': loadTasks(); break;
                    case 'memory': loadMemory(); break;
                    case 'skills': loadSkills(); break;
                    case 'nodes': loadNodes(); break;
                }
            });
        });
        
        // Chat
        const chatInput = document.getElementById('chat-input');
        const sendBtn = document.getElementById('send-btn');
        const messagesDiv = document.getElementById('messages');
        
        chatInput.addEventListener('keypress', e => {
            if (e.key === 'Enter') sendMessage();
        });
        
        async function sendMessage() {
            const text = chatInput.value.trim();
            if (!text) return;
            
            // Add user message
            addMessage(text, 'user');
            chatInput.value = '';
            sendBtn.disabled = true;
            
            try {
                const res = await apiFetch(API + '/api/chat', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({message: text})
                });
                const data = await res.json();
                addMessage(data.response, 'assistant');
            } catch (e) {
                addMessage('Error: Could not reach agent', 'assistant');
            }
            
            sendBtn.disabled = false;
        }
        
        function addMessage(text, role) {
            const msg = document.createElement('div');
            msg.className = 'message ' + role;
            
            // Format text
            text = text.replace(/```(\w*)\n([\s\S]*?)```/g, '<pre><code>$2</code></pre>');
            text = text.replace(/`([^`]+)`/g, '<code style="background:var(--bg-input);padding:2px 6px;border-radius:4px;">$1</code>');
            text = text.replace(/\n/g, '<br>');
            
            msg.innerHTML = '<p>' + text + '</p>';
            messagesDiv.appendChild(msg);
            messagesDiv.scrollTop = messagesDiv.scrollHeight;
        }
        
        function quickCommand(cmd) {
            chatInput.value = cmd.replace(/_/g, ' ');
            sendMessage();
            
            // Switch to chat
            document.querySelector('[data-panel="chat"]').click();
        }
        
        // Load functions
        async function loadStatus() {
            try {
                const res = await apiFetch(API + '/api/status');
                const data = await res.json();
                
                document.getElementById('status-text').textContent = 'Online';
                document.getElementById('status-dot').style.background = 'var(--success)';
                
                document.getElementById('stat-provider').textContent = data.provider || 'Unknown';
                document.getElementById('stat-memory').textContent = (data.memory_entries || 0) + ' entries';
                document.getElementById('stat-skills').textContent = data.skills_loaded || 0;
                document.getElementById('stat-tools').textContent = data.tools_available || 0;
            } catch (e) {
                document.getElementById('status-text').textContent = 'Offline';
                document.getElementById('status-dot').style.background = 'var(--error)';
            }
        }
        
        async function loadBriefing() {
            const container = document.getElementById('briefing-content');
            container.innerHTML = '<div class="loading"><div class="spinner"></div></div>';
            
            try {
                const res = await apiFetch(API + '/api/briefing');
                const data = await res.json();
                
                let html = data.briefing || 'No briefing available';
                html = html.replace(/\n/g, '<br>');
                container.innerHTML = html;
            } catch (e) {
                container.innerHTML = '<p>Error loading briefing</p>';
            }
        }
        
        async function loadEmailTriage() {
            const container = document.getElementById('email-content');
            container.innerHTML = '<div class="loading"><div class="spinner"></div></div>';
            
            try {
                const res = await apiFetch(API + '/api/email/triage');
                const data = await res.json();
                
                let html = data.triage || 'No email data';
                html = html.replace(/\n/g, '<br>');
                container.innerHTML = '<div class="card">' + html + '</div>';
            } catch (e) {
                container.innerHTML = '<div class="card"><p>Error loading email triage. Make sure email is configured.</p></div>';
            }
        }
        
        async function loadTasks() {
            const container = document.getElementById('tasks-list');
            
            try {
                const res = await apiFetch(API + '/api/tasks');
                const data = await res.json();
                
                if (!data.tasks || data.tasks.length === 0) {
                    container.innerHTML = '<p style="color:var(--text-dim)">No tasks yet</p>';
                    return;
                }
                
                container.innerHTML = data.tasks.filter(t => !t.completed).map(t => `
                    <div class="list-item">
                        <div class="task-checkbox ${t.completed ? 'done' : ''}" onclick="completeTask('${t.id}')">
                            ${t.completed ? '<i class="fas fa-check"></i>' : ''}
                        </div>
                        <div class="content">
                            <div class="title">${t.title}</div>
                            <div class="meta">
                                <span class="priority-${t.priority}">${t.priority}</span>
                                ${t.due_date ? ' • Due: ' + t.due_date : ''}
                                ${t.category ? ' • ' + t.category : ''}
                            </div>
                        </div>
                    </div>
                `).join('');
            } catch (e) {
                container.innerHTML = '<p>Error loading tasks</p>';
            }
        }
        
        async function completeTask(id) {
            await apiFetch(API + '/api/tasks/' + id + '/complete', {method: 'POST'});
            loadTasks();
        }
        
        async function loadMemory() {
            const container = document.getElementById('memory-list');
            
            try {
                const res = await apiFetch(API + '/api/memory');
                const data = await res.json();
                
                if (!data.memories || data.memories.length === 0) {
                    container.innerHTML = '<p style="color:var(--text-dim)">No memories yet</p>';
                    return;
                }
                
                container.innerHTML = data.memories.map(m => `
                    <div class="list-item">
                        <div class="icon"><i class="fas fa-lightbulb"></i></div>
                        <div class="content">
                            <div class="title">${m.key}</div>
                            <div class="meta">${m.value}</div>
                            <div class="meta">${m.category} • ${m.updated_at?.slice(0,10) || ''}</div>
                        </div>
                    </div>
                `).join('');
            } catch (e) {
                container.innerHTML = '<p>Error loading memory</p>';
            }
        }
        
        async function loadSkills() {
            const container = document.getElementById('skills-list');
            
            try {
                const res = await apiFetch(API + '/api/skills');
                const data = await res.json();
                
                if (!data.skills || data.skills.length === 0) {
                    container.innerHTML = '<p style="color:var(--text-dim)">No skills loaded</p>';
                    return;
                }
                
                container.innerHTML = data.skills.map(s => `
                    <div class="list-item">
                        <div class="icon"><i class="fas fa-puzzle-piece"></i></div>
                        <div class="content">
                            <div class="title">${s.name}</div>
                            <div class="meta">${s.tools?.length || 0} tools</div>
                        </div>
                        <div class="toggle ${s.enabled ? 'on' : ''}" onclick="toggleSkill('${s.name}')"></div>
                    </div>
                `).join('');
            } catch (e) {
                container.innerHTML = '<p>Error loading skills</p>';
            }
        }
        
        async function toggleSkill(name) {
            await apiFetch(API + '/api/skills/' + name + '/toggle', {method: 'POST'});
            loadSkills();
        }
        
        async function loadNodes() {
            const container = document.getElementById('nodes-content');
            const sidebar = document.getElementById('nodes-sidebar');
            
            try {
                const res = await apiFetch(API + '/api/nodes');
                const data = await res.json();
                
                const gatewayHtml = `
                    <div class="node-item">
                        <div class="node-dot"></div>
                        <div>
                            <div style="font-weight: 500;">Gateway</div>
                            <div style="font-size: 0.75rem; color: var(--text-dim);">This device</div>
                        </div>
                    </div>
                `;
                
                if (!data.nodes || data.nodes.length === 0) {
                    container.innerHTML = `
                        <div class="card">
                            <p>No nodes connected</p>
                            <p style="margin-top: 10px; color: var(--text-dim);">
                                Connect a node with:<br>
                                <code style="display: block; margin-top: 8px; padding: 12px; background: var(--bg-input); border-radius: 6px; font-size: 0.85rem;">
                                    python -m pi_agent.node --gateway ws://YOUR_IP:18789 --key YOUR_KEY
                                </code>
                            </p>
                        </div>
                    `;
                    sidebar.innerHTML = gatewayHtml;
                    return;
                }
                
                const nodesHtml = data.nodes.map(n => `
                    <div class="list-item">
                        <div class="icon"><i class="fas fa-laptop"></i></div>
                        <div class="content">
                            <div class="title">${n.name}</div>
                            <div class="meta">${n.type} • ${n.tools?.length || 0} tools</div>
                        </div>
                        <div class="node-dot"></div>
                    </div>
                `).join('');
                
                container.innerHTML = nodesHtml;
                sidebar.innerHTML = gatewayHtml + data.nodes.map(n => `
                    <div class="node-item">
                        <div class="node-dot"></div>
                        <div>
                            <div style="font-weight: 500;">${n.name}</div>
                            <div style="font-size: 0.75rem; color: var(--text-dim);">${n.type}</div>
                        </div>
                    </div>
                `).join('');
            } catch (e) {
                container.innerHTML = '<p>Error loading nodes</p>';
            }
        }
        
        // Modals
        function showModal(id) {
            document.getElementById(id).classList.add('show');
        }
        
        function hideModal(id) {
            document.getElementById(id).classList.remove('show');
        }
        
        function showAddTaskModal() { showModal('task-modal'); }
        function showAddMemoryModal() { showModal('memory-modal'); }
        
        async function addTask() {
            const data = {
                title: document.getElementById('task-title').value,
                priority: document.getElementById('task-priority').value,
                due_date: document.getElementById('task-due').value,
                category: document.getElementById('task-category').value
            };
            
            if (!data.title) {
                alert('Please enter a task title');
                return;
            }
            
            await apiFetch(API + '/api/tasks', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify(data)
            });
            
            hideModal('task-modal');
            document.getElementById('task-title').value = '';
            document.getElementById('task-due').value = '';
            loadTasks();
        }
        
        async function addMemory() {
            const data = {
                key: document.getElementById('memory-key').value,
                value: document.getElementById('memory-value').value,
                category: document.getElementById('memory-category').value
            };
            
            if (!data.key || !data.value) {
                alert('Please enter key and value');
                return;
            }
            
            await apiFetch(API + '/api/memory', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify(data)
            });
            
            hideModal('memory-modal');
            document.getElementById('memory-key').value = '';
            document.getElementById('memory-value').value = '';
            loadMemory();
        }
        
        async function changeProvider(provider) {
            await apiFetch(API + '/api/config', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify({provider: provider})
            });
            loadStatus();
        }
        
        function showMeshKey() {
            apiFetch(API + '/api/config')
                .then(r => r.json())
                .then(d => alert('Mesh key functionality coming soon'));
        }
        
        // Init
        loadStatus();
        setInterval(loadStatus, 30000);
        setInterval(loadNodes, 15000);
    </script>
</body>
</html>
