// memory.js — Knowledge tab, notes tab, topic detail viewer/editor
// Extracted from dashboard.html

// ── Knowledge tab (general markdown topics) ──

async function mtLoadKnowledge() {
    const container = document.getElementById('mt-knowledge-list');
    const query = (document.getElementById('mt-knowledge-search').value || '').trim();
    container.innerHTML = '<div class="loading"><div class="spinner"></div></div>';

    try {
        let url;
        if (query) {
            url = API + '/api/memories/markdown/search?q=' + encodeURIComponent(query);
            const res = await apiFetch(url);
            const data = await res.json();
            const results = data.results || [];
            if (!results.length) {
                container.innerHTML = '<p style="color:var(--text-dim);text-align:center;padding:20px">No matching topics found.</p>';
                return;
            }
            container.innerHTML = results.map(r => `
                <div class="list-item" style="cursor:pointer" onclick="mtShowTopic('${escapeHtml(r.slug)}', '')">
                    <div class="icon"><i class="fas fa-book"></i></div>
                    <div class="content">
                        <div class="title">${escapeHtml(r.slug)}</div>
                        <div class="meta">${escapeHtml(r.preview || '')}</div>
                    </div>
                    <button onclick="event.stopPropagation();mtDeleteTopic('${escapeHtml(r.slug)}','')" style="background:none;border:none;color:var(--text-dim);cursor:pointer;padding:4px" title="Delete" onmouseover="this.style.color='var(--error-strong)'" onmouseout="this.style.color='var(--text-dim)'"><i class="fas fa-trash"></i></button>
                </div>
            `).join('');
        } else {
            url = API + '/api/memories/markdown';
            const res = await apiFetch(url);
            const data = await res.json();
            const topics = data.topics || [];
            if (!topics.length) {
                container.innerHTML = '<p style="color:var(--text-dim);text-align:center;padding:20px">No knowledge topics yet. Add one to get started.</p>';
                return;
            }
            container.innerHTML = topics.map(t => {
                const slug = t.topic || t;
                const tags = (t.tags || []).map(tg => '<span style="background:var(--bg-dark);padding:1px 6px;border-radius:4px;font-size:0.75em">' + escapeHtml(tg) + '</span>').join(' ');
                const updated = (t.updated || '').slice(0, 10);
                const rev = t.revision || 1;
                return `
                <div class="list-item" style="cursor:pointer" onclick="mtShowTopic('${escapeHtml(slug)}', '')">
                    <div class="icon"><i class="fas fa-book"></i></div>
                    <div class="content">
                        <div class="title">${escapeHtml(slug)}</div>
                        <div class="meta">${tags} rev ${rev}${updated ? ' · ' + updated : ''}</div>
                    </div>
                    <button onclick="event.stopPropagation();mtDeleteTopic('${escapeHtml(slug)}','')" style="background:none;border:none;color:var(--text-dim);cursor:pointer;padding:4px" title="Delete" onmouseover="this.style.color='var(--error-strong)'" onmouseout="this.style.color='var(--text-dim)'"><i class="fas fa-trash"></i></button>
                </div>`;
            }).join('');
        }
    } catch (e) {
        container.innerHTML = '<p style="color:var(--error-strong)">Failed to load knowledge topics.</p>';
    }
}

// ── Notes tab (job-class markdown notes) ──

async function mtLoadNotes() {
    const container = document.getElementById('mt-notes-list');
    const namespace = document.getElementById('mt-notes-namespace').value;
    const query = (document.getElementById('mt-notes-search').value || '').trim();
    container.innerHTML = '<div class="loading"><div class="spinner"></div></div>';

    try {
        let url;
        if (query) {
            url = API + '/api/memories/markdown/search?namespace=' + encodeURIComponent(namespace) + '&q=' + encodeURIComponent(query);
            const res = await apiFetch(url);
            const data = await res.json();
            const results = data.results || [];
            if (!results.length) {
                container.innerHTML = '<p style="color:var(--text-dim);text-align:center;padding:20px">No matching notes in ' + escapeHtml(namespace) + '.</p>';
                return;
            }
            container.innerHTML = results.map(r => `
                <div class="list-item" style="cursor:pointer" onclick="mtShowTopic('${escapeHtml(r.slug)}', '${escapeHtml(namespace)}')">
                    <div class="icon"><i class="fas fa-sticky-note"></i></div>
                    <div class="content">
                        <div class="title">${escapeHtml(r.slug)}</div>
                        <div class="meta">${escapeHtml(r.preview || '')}</div>
                    </div>
                    <button onclick="event.stopPropagation();mtDeleteTopic('${escapeHtml(r.slug)}','${escapeHtml(namespace)}')" style="background:none;border:none;color:var(--text-dim);cursor:pointer;padding:4px" title="Delete" onmouseover="this.style.color='var(--error-strong)'" onmouseout="this.style.color='var(--text-dim)'"><i class="fas fa-trash"></i></button>
                </div>
            `).join('');
        } else {
            url = API + '/api/memories/markdown?namespace=' + encodeURIComponent(namespace);
            const res = await apiFetch(url);
            const data = await res.json();
            const topics = data.topics || [];
            if (!topics.length) {
                container.innerHTML = '<p style="color:var(--text-dim);text-align:center;padding:20px">No notes in ' + escapeHtml(namespace) + ' yet.</p>';
                return;
            }
            container.innerHTML = topics.map(t => {
                const slug = t.topic || t;
                const tags = (t.tags || []).map(tg => '<span style="background:var(--bg-dark);padding:1px 6px;border-radius:4px;font-size:0.75em">' + escapeHtml(tg) + '</span>').join(' ');
                const updated = (t.updated || '').slice(0, 10);
                const rev = t.revision || 1;
                return `
                <div class="list-item" style="cursor:pointer" onclick="mtShowTopic('${escapeHtml(slug)}', '${escapeHtml(namespace)}')">
                    <div class="icon"><i class="fas fa-sticky-note"></i></div>
                    <div class="content">
                        <div class="title">${escapeHtml(slug)}</div>
                        <div class="meta">${tags} rev ${rev}${updated ? ' · ' + updated : ''}</div>
                    </div>
                    <button onclick="event.stopPropagation();mtDeleteTopic('${escapeHtml(slug)}','${escapeHtml(namespace)}')" style="background:none;border:none;color:var(--text-dim);cursor:pointer;padding:4px" title="Delete" onmouseover="this.style.color='var(--error-strong)'" onmouseout="this.style.color='var(--text-dim)'"><i class="fas fa-trash"></i></button>
                </div>`;
            }).join('');
        }
    } catch (e) {
        container.innerHTML = '<p style="color:var(--error-strong)">Failed to load notes.</p>';
    }
}

// ── Topic detail viewer/editor ──

async function mtShowTopic(slug, namespace) {
    try {
        let url = API + '/api/memories/markdown/' + encodeURIComponent(slug);
        if (namespace) url += '?namespace=' + encodeURIComponent(namespace);
        const res = await apiFetch(url);
        const data = await res.json();
        if (data.error) { showToast(data.error, 'error'); return; }

        const isNotes = !!namespace;
        const title = data.topic || slug;
        const tags = (data.tags || []).join(', ');
        const updated = (data.updated || '').slice(0, 10);

        // Render in a modal
        const modal = document.getElementById('mt-topic-modal');
        document.getElementById('mt-topic-title').textContent = title;
        document.getElementById('mt-topic-meta').textContent = (tags ? 'Tags: ' + tags + ' · ' : '') + 'Rev ' + (data.revision || 1) + (updated ? ' · ' + updated : '');
        document.getElementById('mt-topic-body').value = data.body || '';
        document.getElementById('mt-topic-slug').value = slug;
        document.getElementById('mt-topic-ns').value = namespace || '';
        document.getElementById('mt-topic-new-slug-wrap').style.display = 'none';
        modal.style.display = 'flex';
    } catch (e) {
        showToast('Failed to load topic', 'error');
    }
}

async function mtSaveTopic() {
    const slug = document.getElementById('mt-topic-slug').value;
    const namespace = document.getElementById('mt-topic-ns').value;
    const body = document.getElementById('mt-topic-body').value.trim();
    if (!body) { showToast('Content is required', 'error'); return; }

    try {
        const payload = { topic: slug, content: body };
        if (namespace) payload.namespace = namespace;
        const res = await apiFetch(API + '/api/memories/markdown', {
            method: 'POST',
            headers: {'Content-Type': 'application/json'},
            body: JSON.stringify(payload),
        });
        const data = await res.json();
        if (data.error) { showToast(data.error, 'error'); return; }
        showToast('Saved', 'success');
        document.getElementById('mt-topic-modal').style.display = 'none';
        if (namespace) mtLoadNotes();
        else mtLoadKnowledge();
    } catch (e) {
        showToast('Save failed', 'error');
    }
}

async function mtDeleteTopic(slug, namespace) {
    if (!confirm('Delete "' + slug + '"? This cannot be undone.')) return;
    try {
        let url = API + '/api/memories/markdown/' + encodeURIComponent(slug);
        if (namespace) url += '?namespace=' + encodeURIComponent(namespace);
        await apiFetch(url, {method: 'DELETE'});
        showToast('Deleted', 'success');
        if (namespace) mtLoadNotes();
        else mtLoadKnowledge();
    } catch (e) {
        showToast('Delete failed', 'error');
    }
}

function mtShowTopicModal(type) {
    const namespace = type === 'notes' ? (document.getElementById('mt-notes-namespace').value || 'helper') : '';
    document.getElementById('mt-topic-title').textContent = type === 'notes' ? 'New Note' : 'New Knowledge Topic';
    document.getElementById('mt-topic-meta').textContent = '';
    document.getElementById('mt-topic-body').value = '';
    document.getElementById('mt-topic-slug').value = '';
    document.getElementById('mt-topic-ns').value = namespace;
    // Show slug input for new topics
    document.getElementById('mt-topic-new-slug-wrap').style.display = '';
    document.getElementById('mt-topic-new-slug').value = '';
    document.getElementById('mt-topic-modal').style.display = 'flex';
}

async function mtSaveNewTopic() {
    const slugInput = document.getElementById('mt-topic-new-slug');
    const slugWrap = document.getElementById('mt-topic-new-slug-wrap');
    const existingSlug = document.getElementById('mt-topic-slug').value;
    const topic = existingSlug || slugInput.value.trim();
    if (!topic) { showToast('Topic name is required', 'error'); return; }

    // Set the slug and hide new-slug input, then save
    document.getElementById('mt-topic-slug').value = topic;
    slugWrap.style.display = 'none';
    await mtSaveTopic();
}

async function loadMemory() {
    const container = document.getElementById('memory-list');
    let html = '';

    // Load MemoryTree working-tier entries
    try {
        const treeRes = await apiFetch(API + '/api/memory/tree?tier=working');
        const treeData = await treeRes.json();
        if (treeData.entries && treeData.entries.length > 0) {
            html += '<div style="font-size:0.75rem;color:var(--text-dim);text-transform:uppercase;letter-spacing:0.5px;margin:8px 0 4px 4px">Memory Tree (Working Tier)</div>';
            html += treeData.entries.map(e => `
                <div class="list-item" style="cursor:pointer" onclick="mtShowTreeEntry('${e.memory_id}')">
                    <div class="icon"><i class="fas fa-brain"></i></div>
                    <div class="content">
                        <div class="title">${_esc(e.title)}</div>
                        <div class="meta">${_esc((e.body || '').slice(0,120))}</div>
                        <div class="meta">${(e.tags||[]).map(t=>'#'+t).join(' ')} • imp: ${(e.importance||0).toFixed(1)}</div>
                    </div>
                    <button class="btn-icon" title="Delete" onclick="event.stopPropagation(); mtDeleteTreeEntry('${e.memory_id}')"><i class="fas fa-trash"></i></button>
                </div>
            `).join('');
            const st = treeData.stats || {};
            html += `<div style="font-size:0.75rem;color:var(--text-dim);margin:4px 0 8px 4px">${st.active || 0} active memories across ${Object.keys(st.by_tier||{}).length} tiers</div>`;
        }
    } catch(e) {}

    // Load legacy brain memories
    try {
        const res = await apiFetch(API + '/api/memory');
        const data = await res.json();
        if (data.memories && data.memories.length > 0) {
            html += '<div style="font-size:0.75rem;color:var(--text-dim);text-transform:uppercase;letter-spacing:0.5px;margin:8px 0 4px 4px">Brain (Legacy)</div>';
            html += data.memories.map(m => `
                <div class="list-item">
                    <div class="icon"><i class="fas fa-lightbulb"></i></div>
                    <div class="content">
                        <div class="title">${_esc(m.key)}</div>
                        <div class="meta">${_esc(m.value)}</div>
                        <div class="meta">${m.category} • ${m.updated_at?.slice(0,10) || ''}</div>
                    </div>
                </div>
            `).join('');
        }
    } catch (e) {}

    container.innerHTML = html || '<p style="color:var(--text-dim)">No memories yet. Chat with your Familiar to build working memory.</p>';
}

async function mtShowTreeEntry(memId) {
    try {
        const res = await apiFetch(API + '/api/memory/tree/' + memId);
        const data = await res.json();
        if (data.error) return;
        const e = data.entry;
        const histRes = await apiFetch(API + '/api/memory/tree/' + memId + '/history');
        const histData = await histRes.json();
        const graphRes = await apiFetch(API + '/api/memory/tree/' + memId + '/graph?depth=1');
        const graphData = await graphRes.json();

        let body = `<h3>${_esc(e.title)}</h3>`;
        body += `<div style="margin:8px 0"><strong>Tier:</strong> ${e.tier} &nbsp; <strong>Importance:</strong> ${(e.importance||0).toFixed(2)} &nbsp; <strong>Status:</strong> ${e.status}</div>`;
        if (e.tags && e.tags.length) body += `<div style="margin:4px 0">${e.tags.map(t=>'<span style="background:var(--bg-tertiary);padding:2px 6px;border-radius:4px;font-size:0.8rem;margin-right:4px">#'+_esc(t)+'</span>').join('')}</div>`;
        body += `<pre style="white-space:pre-wrap;margin:8px 0;max-height:200px;overflow:auto">${_esc(e.body)}</pre>`;
        if (e.source) body += `<div style="font-size:0.8rem;color:var(--text-dim)">Source: ${_esc(e.source)}</div>`;
        body += `<div style="font-size:0.8rem;color:var(--text-dim)">Updated: ${e.updated_at?.slice(0,19)||''}</div>`;

        // History section
        if (histData.history && histData.history.length > 1) {
            body += '<div style="margin-top:12px"><strong>Version History</strong> (' + histData.history.length + ' versions)</div>';
            body += histData.history.map(h => `<div style="font-size:0.85rem;padding:4px 0;border-bottom:1px solid var(--border)"><span style="color:${h.status==='active'?'var(--accent)':'var(--text-dim)'}">${h.status}</span> — ${_esc(h.title)} <span style="color:var(--text-dim)">${h.created_at?.slice(0,19)||''}</span></div>`).join('');
        }

        // Graph section
        if (graphData.edges && graphData.edges.length > 0) {
            body += '<div style="margin-top:12px"><strong>Connections</strong></div>';
            body += graphData.edges.map(edge => {
                const other = graphData.nodes.find(n => n.memory_id === (edge.from_id === memId ? edge.to_id : edge.from_id));
                return `<div style="font-size:0.85rem;padding:2px 0"><span style="color:var(--accent)">${edge.relation_type}</span> → ${_esc(other?.title || edge.to_id.slice(0,8))}</div>`;
            }).join('');
        }

        document.getElementById('mt-detail-body').innerHTML = body;
        showModal('mt-detail-modal');
    } catch(e) {}
}

async function mtDeleteTreeEntry(memId) {
    if (!confirm('Invalidate this memory?')) return;
    try {
        await apiFetch(API + '/api/memory/tree/' + memId, {method:'DELETE', headers:{'Content-Type':'application/json'}, body:JSON.stringify({reason:'user deleted from dashboard'})});
        loadMemory();
    } catch(e) {}
}

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;
        }

        // Sort: setup_required first, then connected, then optional
        const order = {setup_required: 0, connected: 1, optional: 2};
        data.skills.sort((a, b) => (order[a.status] || 2) - (order[b.status] || 2));

        container.innerHTML = data.skills.map(s => {
            const badge = s.status === 'connected'
                ? '<span class="skill-badge skill-connected" title="Connected">&#x2705;</span>'
                : s.status === 'setup_required'
                ? '<span class="skill-badge skill-setup" title="Setup required">&#x1F527;</span>'
                : '<span class="skill-badge skill-optional" title="Optional">&#x2B1C;</span>';
            return `
            <div class="list-item" style="cursor:pointer" onclick="showSkillDetail('${s.name}')">
                <div class="icon">${badge}</div>
                <div class="content">
                    <div class="title">${s.name}</div>
                    <div class="meta">${s.tools_count || 0} tools</div>
                </div>
                <div class="toggle ${s.enabled ? 'on' : ''}" onclick="event.stopPropagation(); 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 showSkillDetail(name) {
    try {
        const res = await apiFetch(API + '/api/skills/' + name + '/detail');
        const s = await res.json();
        if (s.error) { alert(s.error); return; }

        const setupBanner = !s.configured
            ? `<div style="background:var(--warning-bg, #4a3700);padding:8px 12px;border-radius:6px;margin-bottom:12px">
                 <strong>&#x1F527; Setup Required</strong>
                 ${s.prerequisites.map(p => '<div style="font-size:0.85rem;color:var(--text-dim)">&#x2022; ' + p + '</div>').join('')}
                 <div style="margin-top:6px"><code>${s.setup_command}</code></div>
               </div>`
            : '';
        const toolsList = s.tools.length
            ? '<div style="margin-top:8px"><strong>Tools:</strong> ' + s.tools.join(', ') + '</div>'
            : '';
        const desc = (s.description || '').replace(/</g, '&lt;').replace(/>/g, '&gt;')
            .replace(/^# (.+)$/gm, '<h3>$1</h3>')
            .replace(/^## (.+)$/gm, '<h4>$1</h4>')
            .replace(/\n/g, '<br>');

        const modal = document.createElement('div');
        modal.className = 'skill-modal-overlay';
        modal.innerHTML = `
            <div class="skill-modal">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:12px">
                    <h3 style="margin:0">${s.name}</h3>
                    <button onclick="this.closest('.skill-modal-overlay').remove()" style="background:none;border:none;color:var(--text);font-size:1.3rem;cursor:pointer">&times;</button>
                </div>
                ${setupBanner}
                ${toolsList}
                <div style="margin-top:12px;font-size:0.9rem;line-height:1.5;max-height:60vh;overflow-y:auto">${desc}</div>
            </div>`;
        modal.addEventListener('click', e => { if (e.target === modal) modal.remove(); });
        document.body.appendChild(modal);
    } catch (e) {
        console.error('Failed to load skill detail:', e);
    }
}

async function testServiceConnection(service) {
    const btn = event.target;
    const origText = btn.textContent;
    btn.textContent = 'Testing...';
    btn.disabled = true;
    try {
        const res = await apiFetch(API + '/api/connect/test/' + service, {method: 'POST'});
        const data = await res.json();
        btn.textContent = data.success ? '\u2705 ' + data.message : '\u274c ' + data.message;
        setTimeout(() => { btn.textContent = origText; btn.disabled = false; }, 3000);
    } catch (e) {
        btn.textContent = '\u274c Error';
        setTimeout(() => { btn.textContent = origText; btn.disabled = false; }, 3000);
    }
}


