const API_BASE = '/api'; let currentPage = null; let chatHistory = []; document.addEventListener('DOMContentLoaded', () => { initTabs(); loadWikiList(); loadRawList(); }); function initTabs() { document.querySelectorAll('.tab-btn').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.tab-btn').forEach(b => b.classList.remove('tab-active')); btn.classList.add('tab-active'); document.querySelectorAll('.tab-panel').forEach(p => p.classList.add('hidden')); document.getElementById(`tab-${btn.dataset.tab}`).classList.remove('hidden'); }); }); } async function loadWikiList() { try { const res = await fetch(`${API_BASE}/wiki/list`); const data = await res.json(); const list = document.getElementById('page-list'); list.innerHTML = ''; const categories = ['entities', 'concepts', 'sources', 'topics', 'comparisons']; categories.forEach(cat => { if (data[cat] && data[cat].length > 0) { const catDiv = document.createElement('div'); catDiv.innerHTML = `
${cat}
`; data[cat].forEach(page => { const a = document.createElement('a'); a.href = '#'; a.textContent = page.name; a.className = 'block px-2 py-1 rounded hover:bg-gray-700 text-blue-400'; a.onclick = () => loadPage(page.file); catDiv.appendChild(a); }); list.appendChild(catDiv); } }); } catch (e) { console.error('Error loading wiki list:', e); } } async function loadPage(file) { try { const res = await fetch(`${API_BASE}/wiki/page/${file}`); const data = await res.json(); currentPage = data; const container = document.getElementById('page-content'); let html = `

${data.file.split('/').pop().replace('.md', '')}

`; if (data.metadata && Object.keys(data.metadata).length > 0) { html += `
Tags: ${Object.values(data.metadata).join(', ')}
`; } let content = data.content || ''; content = content.replace(/\[\[([^\]]+)\]\]/g, '[[$1]]'); html += `
${marked.parse(content)}
`; container.innerHTML = html; } catch (e) { document.getElementById('page-content').innerHTML = `

Errore: ${e.message}

`; } } function navigateTo(name) { const normalized = name.toLowerCase().replace(/\s+/g, '-'); loadPage(normalized); } async function loadRawList() { try { const res = await fetch(`${API_BASE}/raw/list`); const data = await res.json(); const list = document.getElementById('raw-list'); list.innerHTML = ''; Object.entries(data).forEach(([cat, files]) => { if (files.length > 0) { const div = document.createElement('div'); div.innerHTML = `
${cat}
`; files.forEach(f => { const label = document.createElement('label'); label.className = 'flex items-center gap-2 px-2 py-1 hover:bg-gray-700 rounded cursor-pointer'; label.innerHTML = ` ${f}`; div.appendChild(label); }); list.appendChild(div); } }); } catch (e) { console.error('Error loading raw list:', e); } } async function runIngest() { const selected = document.querySelector('input[name="source"]:checked'); if (!selected) { alert('Seleziona un file da ingestire'); return; } const log = document.getElementById('ingest-log'); log.innerHTML = 'Avvio ingest...\n'; try { const eventSource = new EventSource(`${API_BASE}/ingest/stream/${selected.value}`); eventSource.onmessage = (e) => { log.innerHTML += e.data + '\n'; log.scrollTop = log.scrollHeight; }; eventSource.onerror = () => { eventSource.close(); log.innerHTML += 'Completato!\n'; loadWikiList(); }; } catch (e) { log.innerHTML += `Errore: ${e.message}\n`; } } async function doSearch() { const query = document.getElementById('search-input').value.trim(); if (!query) return; const results = document.getElementById('search-results'); results.innerHTML = 'Ricerca in corso...'; try { const res = await fetch(`${API_BASE}/search?q=${encodeURIComponent(query)}`); const data = await res.json(); results.innerHTML = ''; if (data.by_name && data.by_name.length > 0) { const section = document.createElement('div'); section.innerHTML = `

Per nome

`; data.by_name.forEach(r => { section.innerHTML += `
${r.name} (${r.category})
`; }); results.appendChild(section); } if (data.by_content && data.by_content.length > 0) { const section = document.createElement('div'); section.innerHTML = `

Nel contenuto

`; data.by_content.forEach(r => { const matchesHtml = r.matches.map(m => `
Linea ${m.line}: ${m.text}
`).join(''); section.innerHTML += `
${r.name}${matchesHtml}
`; }); results.appendChild(section); } if ((!data.by_name || data.by_name.length === 0) && (!data.by_content || data.by_content.length === 0)) { results.innerHTML = 'Nessun risultato'; } } catch (e) { results.innerHTML = `Errore: ${e.message}`; } } async function sendChat() { const input = document.getElementById('chat-input'); const message = input.value.trim(); if (!message) return; const messages = document.getElementById('chat-messages'); messages.innerHTML += `
Tu: ${escapeHtml(message)}
`; input.value = ''; const responseDiv = document.createElement('div'); responseDiv.className = 'mb-2 p-2 bg-gray-800 rounded'; responseDiv.innerHTML = 'Wiki: '; messages.appendChild(responseDiv); messages.scrollTop = messages.scrollHeight; try { const res = await fetch(`${API_BASE}/chat`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ message, history: chatHistory }) }); const reader = res.body.getReader(); const decoder = new TextDecoder(); let response = ''; while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value); response += chunk; responseDiv.innerHTML = `Wiki: ${formatResponse(response)}`; } chatHistory.push({ role: 'user', content: message }); chatHistory.push({ role: 'assistant', content: response }); } catch (e) { responseDiv.innerHTML = `Errore: ${e.message}`; } } function formatResponse(text) { text = escapeHtml(text); text = text.replace(/\[\[([^\]]+)\]\]/g, '[[$1]]'); return text + ''; } function escapeHtml(text) { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; } const marked = { parse: function(text) { text = text.replace(/^### (.+)$/gm, '

$1

'); text = text.replace(/^## (.+)$/gm, '

$1

'); text = text.replace(/^# (.+)$/gm, '

$1

'); text = text.replace(/\*\*(.+?)\*\*/g, '$1'); text = text.replace(/\*(.+?)\*/g, '$1'); text = text.replace(/`(.+?)`/g, '$1'); text = text.replace(/\n/g, '
'); return text; } };