/**
 * summarize.js — Custom handler for the Summarize Document tool.
 *
 * Handles file upload (via api/extract.php), corpus slice toggles,
 * engine selection, JSON submission, and NDJSON streaming response.
 */
(function () {
    'use strict';

    // ── Element refs ──────────────────────────────────────────────────────────
    var form       = document.getElementById('sumForm');
    var runBtn     = document.getElementById('sumRunButton');
    var statusEl   = document.getElementById('sumStatus');
    var resultsEl  = document.getElementById('sumResults');
    var traceList  = document.getElementById('traceList');
    var textarea   = document.getElementById('sumInput');

    var uploadZone     = document.getElementById('sumUploadZone');
    var uploadInput    = document.getElementById('sumUploadInput');
    var uploadPrompt   = document.getElementById('sumUploadPrompt');
    var uploadFileInfo = document.getElementById('sumUploadFileInfo');
    var uploadFileList = document.getElementById('sumUploadFileList');
    var uploadClear    = document.getElementById('sumUploadClear');

    // ── State ─────────────────────────────────────────────────────────────────
    var _extractedFiles = []; // [{ name, text, chars }]
    var _currentLang    = 'en';
    var _lastPayload    = null;

    // ── Lang switcher ─────────────────────────────────────────────────────────
    document.querySelectorAll('.sum-lang-btn').forEach(function (btn) {
        btn.addEventListener('click', function () {
            document.querySelectorAll('.sum-lang-btn').forEach(function (b) {
                b.classList.toggle('is-active', b === btn);
            });
            _currentLang = btn.dataset.lang || 'en';
        });
    });

    // ── Corpus slice toggles ──────────────────────────────────────────────────
    document.querySelectorAll('.sum-slice').forEach(function (btn) {
        btn.addEventListener('click', function () {
            var on = btn.classList.toggle('is-on');
            btn.setAttribute('aria-pressed', String(on));
            var badge = btn.querySelector('.dr-slice__badge');
            if (badge) badge.textContent = on ? 'on' : 'off';
        });
    });

    function activeSlices() {
        var out = [];
        document.querySelectorAll('.sum-slice.is-on').forEach(function (btn) {
            if (btn.dataset.slice) out.push(btn.dataset.slice);
        });
        return out;
    }

    // ── File upload ───────────────────────────────────────────────────────────
    if (uploadZone) {
        uploadZone.addEventListener('dragover', function (e) {
            e.preventDefault();
            uploadZone.classList.add('is-drag-over');
        });
        uploadZone.addEventListener('dragleave', function (e) {
            if (!uploadZone.contains(e.relatedTarget)) {
                uploadZone.classList.remove('is-drag-over');
            }
        });
        uploadZone.addEventListener('drop', function (e) {
            e.preventDefault();
            uploadZone.classList.remove('is-drag-over');
            if (e.dataTransfer && e.dataTransfer.files.length) {
                handleFiles(e.dataTransfer.files);
            }
        });
        // Stop label-for and the input itself from bubbling into the zone click
        // handler — otherwise the picker opens twice (native + programmatic).
        var browseLabel = uploadZone.querySelector('label[for="' + (uploadInput && uploadInput.id) + '"]');
        if (browseLabel) {
            browseLabel.addEventListener('click', function (e) { e.stopPropagation(); });
        }
        if (uploadInput) {
            uploadInput.addEventListener('click', function (e) { e.stopPropagation(); });
        }
        uploadZone.addEventListener('click', function (e) {
            if (e.target === uploadClear || (uploadClear && uploadClear.contains(e.target))) return;
            if (e.target === uploadInput) return;
            var lbl = e.target.closest && e.target.closest('label');
            if (lbl && lbl.getAttribute('for') === uploadInput.id) return;
            if (uploadInput) uploadInput.click();
        });
    }

    if (uploadInput) {
        uploadInput.addEventListener('change', function () {
            if (uploadInput.files && uploadInput.files.length) {
                handleFiles(uploadInput.files);
            }
        });
    }

    if (uploadClear) {
        uploadClear.addEventListener('click', function (e) {
            e.stopPropagation();
            resetUpload();
        });
    }

    function resetUpload() {
        _extractedFiles = [];
        if (uploadInput) uploadInput.value = '';
        if (uploadPrompt) uploadPrompt.classList.remove('is-hidden');
        if (uploadFileInfo) uploadFileInfo.classList.add('is-hidden');
        if (uploadFileList) uploadFileList.innerHTML = '';
    }

    function handleFiles(fileList) {
        var files = Array.from(fileList).slice(0, 5);
        if (!files.length) return;

        setStatus('Extracting text from ' + files.length + ' file(s)…');
        setBusy(true);

        var promises = files.map(function (file) {
            var fd = new FormData();
            fd.append('file', file);
            return fetch('api/extract.php', { method: 'POST', credentials: 'same-origin', body: fd })
                .then(function (r) { return r.json(); })
                .then(function (data) {
                    if (!data.ok) throw new Error(data.error || 'Extraction failed for ' + file.name);
                    return { name: file.name, text: data.text || '', chars: data.chars || 0 };
                });
        });

        Promise.all(promises)
            .then(function (results) {
                _extractedFiles = results;
                renderFileList(results);
                setStatus('');
                setBusy(false);
            })
            .catch(function (err) {
                setStatus('Error: ' + err.message);
                setBusy(false);
            });
    }

    function renderFileList(files) {
        if (!uploadFileList) return;
        uploadFileList.innerHTML = files.map(function (f) {
            return '<li><span class="upload-filename">' + esc(f.name) + '</span>'
                + ' <span class="upload-chars">' + f.chars.toLocaleString() + ' chars</span></li>';
        }).join('');
        if (uploadPrompt) uploadPrompt.classList.add('is-hidden');
        if (uploadFileInfo) uploadFileInfo.classList.remove('is-hidden');
    }

    // ── Form submission ───────────────────────────────────────────────────────
    if (form) {
        form.addEventListener('submit', function (e) {
            e.preventDefault();
            runSummarize();
        });
    }

    async function runSummarize() {
        // Build text: extracted files + textarea
        var pastedText = textarea ? textarea.value.trim() : '';
        var fileText   = _extractedFiles.map(function (f) { return f.text; }).join('\n\n---\n\n');
        var combined   = [fileText, pastedText].filter(Boolean).join('\n\n---\n\n');

        // Doc picker ids
        var docIdsEl  = document.getElementById('docPickerIds');
        var rawDocIds = docIdsEl ? docIdsEl.value.trim() : '';
        var docIds    = rawDocIds ? rawDocIds.split(',').map(Number).filter(Boolean) : [];

        if (!combined && !docIds.length) {
            setStatus('Paste text, upload a file, or select a document before running.');
            return;
        }

        var engine = (document.querySelector('input[name="sumEngine"]:checked') || {}).value || 'azure_mini';
        var slices = activeSlices();

        var payload = {
            text:     combined,
            language: _currentLang,
            engine:   engine,
            slices:   slices,
        };
        if (docIds.length) payload.doc_ids = docIds;
        _lastPayload = payload;

        setBusy(true);
        setStatus('Running…');
        showProgress([]);

        try {
            var resp = await fetch('api/summarize.php', {
                method:      'POST',
                credentials: 'same-origin',
                headers:     { 'Content-Type': 'application/json' },
                body:        JSON.stringify(payload),
            });

            if (!resp.ok || !resp.body) {
                throw new Error('Server returned ' + resp.status);
            }

            var reader  = resp.body.getReader();
            var decoder = new TextDecoder();
            var buffer  = '';
            var steps   = [];

            while (true) {
                var _ref   = await reader.read();
                var done   = _ref.done;
                var value  = _ref.value;
                if (done) break;
                buffer += decoder.decode(value, { stream: true });
                var lines  = buffer.split('\n');
                buffer = lines.pop(); // keep incomplete line
                for (var i = 0; i < lines.length; i++) {
                    var line = lines[i].trim();
                    if (!line) continue;
                    var data;
                    try { data = JSON.parse(line); } catch (_) { continue; }
                    if (data.event === 'progress') {
                        steps.push(data);
                        showProgress(steps);
                        setStatus(data.detail || '');
                    } else if (data.event === 'final') {
                        renderFinal(data);
                        if (typeof window.dbnShowSaveResultButton === 'function') {
                            window.dbnShowSaveResultButton(
                                'summarize',
                                _lastPayload || {},
                                data,
                                { model: data.engine || null, latency_ms: data.latency_ms || 0 },
                                resultsEl
                            );
                        }
                        // Offer deep legal analysis on the summarised text
                        if (typeof window.dbnInjectLegalAnalysisButton === 'function') {
                            var sourceText = combined || (_lastPayload && _lastPayload.text) || '';
                            if (sourceText && sourceText.length >= 80) {
                                window.dbnInjectLegalAnalysisButton(sourceText, _currentLang, 'summarize', resultsEl);
                            }
                        }
                        if (data.balance != null) {
                            var credEl = document.getElementById('creditsRemaining');
                            if (credEl) credEl.textContent = data.balance;
                        }
                    } else if (data.event === 'error') {
                        showError(data.error || 'An error occurred.');
                    }
                }
            }
        } catch (err) {
            showError(err.message || 'Request failed.');
        } finally {
            setBusy(false);
            setStatus('');
        }
    }

    // ── Result rendering ──────────────────────────────────────────────────────
    function showProgress(steps) {
        if (!resultsEl) return;
        var items = steps.map(function (s) {
            return '<li><span class="trace-status running"></span>'
                + '<div><strong>' + esc(stepLabel(s.step)) + '</strong>'
                + '<p>' + esc(s.detail || '') + '</p></div></li>';
        }).join('');
        resultsEl.innerHTML = '<ol class="trace-list">' + items
            + '<li><span class="trace-status running"></span><div><strong>Working…</strong></div></li></ol>';
    }

    function stepLabel(step) {
        var labels = {
            text_ready:    'Document prepared',
            corpus_search: 'Searching legal corpus',
            corpus_done:   'Corpus search done',
            generating:    'Generating summary',
        };
        return labels[step] || step;
    }

    function renderFinal(data) {
        if (!resultsEl) return;

        var sections = [];

        if (data.what_we_found) {
            sections.push(
                '<section class="result-section">'
                + '<h3>Summary</h3>'
                + '<p>' + esc(data.what_we_found) + '</p>'
                + '</section>'
            );
        }

        if (Array.isArray(data.key_facts) && data.key_facts.length) {
            sections.push(detailBlock('Key Facts', data.key_facts));
        }
        if (Array.isArray(data.dates) && data.dates.length) {
            sections.push(detailBlock('Dates', data.dates));
        }
        if (Array.isArray(data.parties) && data.parties.length) {
            sections.push(detailBlock('Parties', data.parties));
        }
        if (Array.isArray(data.legal_references_detected) && data.legal_references_detected.length) {
            sections.push(detailBlock('Legal References Detected', data.legal_references_detected));
        }
        if (Array.isArray(data.what_remains_uncertain) && data.what_remains_uncertain.length) {
            sections.push(detailBlock('What Remains Uncertain', data.what_remains_uncertain));
        }

        if (data.next_practical_step) {
            sections.push(
                '<section class="result-section">'
                + '<h3>Next Practical Step</h3>'
                + '<p>' + esc(data.next_practical_step) + '</p>'
                + '</section>'
            );
        }

        if (data.corpus_used) {
            sections.push(
                '<p class="upload-hint" style="margin-top:.5rem">'
                + 'Summary enriched with relevant passages from the Do Better Norge legal corpus.'
                + '</p>'
            );
        }

        if (data.disclaimer) {
            sections.push('<p class="disclaimer-note">' + esc(data.disclaimer) + '</p>');
        }

        resultsEl.innerHTML = sections.join('');

        // Update reasoning panel trace
        if (traceList && Array.isArray(data.trace) && data.trace.length) {
            traceList.innerHTML = data.trace.map(function (item) {
                return '<li>'
                    + '<span class="trace-status ' + esc(item.status || 'complete') + '"></span>'
                    + '<div><strong>' + esc(item.label || '') + '</strong>'
                    + '<p>' + esc(item.detail || '') + '</p></div>'
                    + '</li>';
            }).join('');
        }
    }

    function showError(msg) {
        if (resultsEl) {
            resultsEl.innerHTML = '<div class="empty-state"><h3>Error</h3><p>' + esc(msg) + '</p></div>';
        }
        setStatus('');
    }

    function detailBlock(title, items) {
        return '<div class="detail-block"><h4>' + esc(title) + '</h4>'
            + '<ul>' + items.map(function (v) { return '<li>' + esc(String(v)) + '</li>'; }).join('') + '</ul>'
            + '</div>';
    }

    // ── Helpers ───────────────────────────────────────────────────────────────
    function setBusy(on) {
        if (runBtn) runBtn.disabled = on;
        if (runBtn) runBtn.textContent = on ? 'Running…' : 'Summarize';
    }

    function setStatus(msg) {
        if (statusEl) statusEl.textContent = msg;
    }

    function esc(s) {
        return String(s == null ? '' : s)
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#039;');
    }

}());
