<?php
declare(strict_types=1);
require_once __DIR__ . '/../includes/bootstrap.php';
$dashboardPage  = 'chat';
$dashboardTitle = dbnToolsT('dash_title_chat', dbnToolsCurrentLanguage());
$dashboardLead  = dbnToolsT('dash_lead_chat',  dbnToolsCurrentLanguage());
require_once __DIR__ . '/../includes/layout_dashboard.php';
?>
<div class="disclaimer" role="note" style="margin-bottom:1rem;">
    <?= htmlspecialchars(dbnToolsT('dash_chat_disclaimer', $uiLang)) ?>
</div>

<section class="dash-card" style="display:flex; flex-direction:column; min-height:60vh;">
    <div id="chatLog" class="chat-log" aria-live="polite">
        <div class="chat-empty" id="chatEmptyMsg"></div>
    </div>

    <form id="chatForm" class="chat-form" autocomplete="off">
        <textarea id="chatInput" rows="2" required placeholder="<?= htmlspecialchars(dbnToolsT('dash_chat_placeholder', $uiLang)) ?>"></textarea>
        <button type="submit" class="dash-btn dash-btn--primary" id="chatSendBtn">Send</button>
    </form>
</section>

<style>
.chat-log { flex: 1; overflow-y: auto; padding: 0.25rem 0.25rem 1rem; display: flex; flex-direction: column; gap: 1rem; min-height: 40vh; max-height: 65vh; }
.chat-empty { text-align: center; padding: 3rem 1rem; color: rgba(22, 19, 15, 0.5); font-style: italic; }
.chat-msg { display: flex; flex-direction: column; gap: 0.4rem; max-width: 88%; }
.chat-msg--user { align-self: flex-end; }
.chat-msg--ai   { align-self: flex-start; }
.chat-bubble {
    padding: 0.85rem 1.05rem; border-radius: var(--dash-radius); line-height: 1.55; font-size: 0.95rem;
    white-space: pre-wrap; word-wrap: break-word;
}
.chat-msg--user .chat-bubble { background: var(--dbn-blue); color: #fff; }
.chat-msg--ai   .chat-bubble { background: #fff; border: 1px solid var(--dbn-line); }
.chat-sources { display: flex; flex-wrap: wrap; gap: 0.35rem; }
.chat-source-chip {
    font-size: 0.78rem; padding: 0.2rem 0.55rem; border-radius: 999px;
    background: rgba(0, 32, 91, 0.07); color: var(--dbn-blue); text-decoration: none;
    border: 1px solid rgba(0, 32, 91, 0.15);
}
.chat-source-chip:hover { background: rgba(0, 32, 91, 0.13); }
.chat-actions { display: flex; gap: 0.5rem; }
.chat-actions button { font-size: 0.8rem; padding: 0.25rem 0.55rem; }
.chat-form { display: grid; grid-template-columns: 1fr auto; gap: 0.6rem; padding-top: 0.75rem; border-top: 1px solid var(--dbn-line); }
.chat-form textarea {
    padding: 0.7rem 0.85rem; border: 1px solid var(--dbn-line); border-radius: var(--dash-radius-sm);
    font: inherit; resize: vertical; min-height: 3rem; max-height: 8rem; background: #fff;
}
.chat-meta { font-size: 0.72rem; color: rgba(22, 19, 15, 0.5); margin-top: 0.2rem; }
.chat-thinking { font-style: italic; color: rgba(22, 19, 15, 0.5); }
</style>

<script>
(function () {
    'use strict';
    const I18N  = window.DBN_I18N || {};
    const api   = window.DBN_DASHBOARD.apiBase;
    const $log  = document.getElementById('chatLog');
    const $form = document.getElementById('chatForm');
    const $input = document.getElementById('chatInput');
    const $send  = document.getElementById('chatSendBtn');
    const $empty = document.getElementById('chatEmptyMsg');

    if ($empty) $empty.textContent = I18N.ask_btn
        ? I18N.ask_btn.replace(/^💬\s*/, '')
        : 'Ask your first question. It can be about child welfare, family law, ECHR — anything in your corpus.';

    const history = [];

    function safe(s) { return String(s ?? '').replace(/[&<>"]/g, c => ({ '&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;' }[c])); }

    function clearEmpty() {
        const empty = $log.querySelector('.chat-empty');
        if (empty) empty.remove();
    }
    function appendUser(text) {
        clearEmpty();
        const wrap = document.createElement('div');
        wrap.className = 'chat-msg chat-msg--user';
        wrap.innerHTML = '<div class="chat-bubble">' + safe(text) + '</div>';
        $log.appendChild(wrap);
        $log.scrollTop = $log.scrollHeight;
    }
    function appendAi() {
        const wrap = document.createElement('div');
        wrap.className = 'chat-msg chat-msg--ai';
        wrap.innerHTML =
            '<div class="chat-bubble"><span class="chat-stream"></span><span class="chat-thinking">' + (I18N.chat_thinking || 'thinking…') + '</span></div>'
            + '<div class="chat-sources" hidden></div>'
            + '<div class="chat-actions" hidden>'
            +   '<button class="dash-btn chat-save" type="button">' + (I18N.chat_save || '💾 Save to corpus') + '</button>'
            +   '<button class="dash-btn chat-copy" type="button">' + (I18N.chat_copy || '📋 Copy') + '</button>'
            + '</div>'
            + '<div class="chat-meta" hidden></div>';
        $log.appendChild(wrap);
        $log.scrollTop = $log.scrollHeight;
        return wrap;
    }

    async function ask(question) {
        appendUser(question);
        history.push({ role: 'user', content: question });
        const aiNode  = appendAi();
        const stream   = aiNode.querySelector('.chat-stream');
        const thinking = aiNode.querySelector('.chat-thinking');
        const sources  = aiNode.querySelector('.chat-sources');
        const actions  = aiNode.querySelector('.chat-actions');
        const meta     = aiNode.querySelector('.chat-meta');

        $send.disabled = true;
        $input.disabled = true;

        let answer = '';
        try {
            const resp = await fetch(api + '/chat-stream.php', {
                method: 'POST', credentials: 'same-origin',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ question, history: history.slice(0, -1) }),
            });
            if (!resp.ok || !resp.body) throw new Error('HTTP ' + resp.status);

            const reader = resp.body.getReader();
            const dec = new TextDecoder('utf-8');
            let buffer = '';
            let firstToken = true;

            while (true) {
                const { value, done } = await reader.read();
                if (done) break;
                buffer += dec.decode(value, { stream: true });

                let idx;
                while ((idx = buffer.indexOf('\n\n')) !== -1) {
                    const frame = buffer.slice(0, idx);
                    buffer = buffer.slice(idx + 2);
                    let evName = 'message';
                    let data   = '';
                    frame.split('\n').forEach(line => {
                        if (line.startsWith('event:')) evName = line.slice(6).trim();
                        else if (line.startsWith('data:')) data += line.slice(5).trim();
                    });
                    if (!data) continue;
                    let payload;
                    try { payload = JSON.parse(data); } catch (_) { continue; }

                    if (evName === 'token') {
                        if (firstToken) { thinking.remove(); firstToken = false; }
                        answer += payload.t || '';
                        stream.textContent = answer;
                        $log.scrollTop = $log.scrollHeight;
                    } else if (evName === 'done') {
                        history.push({ role: 'assistant', content: answer });
                        renderSources(sources, payload.sources || []);
                        const chunksTmpl = (I18N.chat_passages_meta || '{n} passages').replace('{n}', payload.chunks_used || 0);
                        meta.hidden = false;
                        meta.textContent = chunksTmpl + ' · ' + (payload.model || 'auto') + ' · ' + (payload.response_time_ms || 0) + ' ms';
                        actions.hidden = false;
                        wireActions(aiNode, question, answer);
                    } else if (evName === 'fail') {
                        thinking.textContent = '❌ ' + (payload.message || 'Error');
                        thinking.style.color = 'var(--dbn-red)';
                    }
                }
            }
        } catch (err) {
            thinking.textContent = '❌ ' + err.message;
            thinking.style.color = 'var(--dbn-red)';
        } finally {
            $send.disabled = false;
            $input.disabled = false;
            $input.focus();
        }
    }

    function renderSources(container, sources) {
        if (!sources.length) return;
        container.hidden = false;
        container.innerHTML = sources.map(s => {
            const label = s.title + (s.section ? ' (§ ' + s.section + ')' : '');
            if (s.document_id > 0) {
                return '<a class="chat-source-chip" href="/dashboard/document.php?id=' + s.document_id + '">'
                    + safe(label) + '</a>';
            }
            if (s.source_url) {
                return '<a class="chat-source-chip" href="' + safe(s.source_url) + '" target="_blank" rel="noopener">'
                    + safe(label) + ' ↗</a>';
            }
            return '<span class="chat-source-chip">' + safe(label) + '</span>';
        }).join('');
    }

    function wireActions(node, question, answer) {
        node.querySelector('.chat-copy').addEventListener('click', () => {
            navigator.clipboard.writeText(answer).then(() => {
                const btn = node.querySelector('.chat-copy');
                const orig = btn.textContent;
                btn.textContent = I18N.chat_copied || '✓ Copied';
                setTimeout(() => btn.textContent = orig, 1400);
            });
        });
        node.querySelector('.chat-save').addEventListener('click', () => {
            const dialog = document.getElementById('save-corpus-dialog');
            const titleField = document.getElementById('save-corpus-title');
            const tagsField  = document.getElementById('save-corpus-tags');
            if (!dialog || !titleField) {
                alert(I18N.chat_save_unavail || 'Save dialog unavailable.');
                return;
            }
            titleField.value = question.slice(0, 80);
            tagsField.value  = 'chat,answer';
            dialog.dataset.pendingContent = 'Q: ' + question + '\n\nA: ' + answer;
            dialog.dataset.pendingTool    = 'dashboard-chat';
            dialog.showModal();
        });
    }

    $form.addEventListener('submit', (e) => {
        e.preventDefault();
        const q = $input.value.trim();
        if (!q) return;
        $input.value = '';
        ask(q);
    });

    $input.addEventListener('keydown', (e) => {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            $form.dispatchEvent(new Event('submit', { cancelable: true }));
        }
    });
})();
</script>

<?php require_once __DIR__ . '/../includes/layout_dashboard_footer.php'; ?>
