(function () {
    'use strict';

    if (document.body.dataset.activeTool !== 'citations') return;

    const form       = document.getElementById('citationsForm');
    const titleInput = document.getElementById('titleInput');
    const docIdInput = document.getElementById('docIdHidden');
    const acList     = document.getElementById('citAutocomplete');
    const depthRow   = document.getElementById('depthRow');
    const depthRange = document.getElementById('depthRange');
    const depthValue = document.getElementById('depthValue');
    const runBtn     = document.getElementById('citeRunBtn');
    const statusEl   = document.getElementById('citStatus');
    const resultsDiv = document.getElementById('citationResults');
    const sourceCard = document.getElementById('citSourceCard');
    const resultsArea = document.getElementById('citResultsArea');
    const trailList  = document.getElementById('trailList');

    const trail = [];

    // ── Utilities ─────────────────────────────────────────────────────────────

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

    function setStatus(msg, kind) {
        statusEl.textContent = msg;
        statusEl.style.color = kind === 'error' ? '#b41e1e' : kind === 'ok' ? 'var(--teal-dark)' : 'var(--muted)';
    }

    function debounce(fn, ms) {
        let t;
        return (...args) => { clearTimeout(t); t = setTimeout(() => fn(...args), ms); };
    }

    function authorityLabel(atype) {
        const map = {
            case_law: 'Case law', guidance: 'Guidance', report: 'Report',
            law: 'Statute', treaty: 'Treaty', ombudsman: 'Ombudsman',
            tribunal: 'Tribunal', regulatory: 'Regulatory',
        };
        return map[atype] || atype || '';
    }

    function relChipClass(action, relType) {
        if (action === 'chain') return 'rel-chip--reachable';
        if (action === 'cited_by') return 'rel-chip--cited-by';
        if (action === 'cites') return 'rel-chip--cites';
        const rt = (relType || '').toUpperCase();
        if (rt === 'REPEALS') return 'rel-chip--repeals';
        return 'rel-chip--implements';
    }

    function relChipLabel(action, relType) {
        if (action === 'chain') return 'Reachable';
        if (action === 'cited_by') return 'Cited by';
        if (action === 'cites') return 'Cites';
        if (relType) return relType.replace(/_/g, ' ');
        return 'Implements';
    }

    function yearFrom(dateStr) {
        if (!dateStr) return '';
        return String(dateStr).slice(0, 4);
    }

    // ── Autocomplete ──────────────────────────────────────────────────────────

    function hideAc() { acList.hidden = true; }

    function renderAc(docs) {
        if (!docs.length) { hideAc(); return; }
        acList.innerHTML = docs.map(d => {
            const al = authorityLabel(d.authority_type);
            return `<li role="option" data-id="${esc(String(d.id))}" data-title="${esc(d.title || '')}">`
                + esc(d.title || '(Untitled)')
                + (al ? `<span class="cit-ac-atype">${esc(al)}</span>` : '')
                + `</li>`;
        }).join('');
        acList.hidden = false;
    }

    const fetchAc = debounce(async (q) => {
        if (!q || q.length < 2) { hideAc(); return; }
        try {
            const res = await fetch('api/corpus-documents.php?' + new URLSearchParams({ title: q, limit: 15 }), { credentials: 'same-origin' });
            if (!res.ok) { hideAc(); return; }
            const data = await res.json();
            renderAc(data.documents || []);
        } catch { hideAc(); }
    }, 300);

    titleInput.addEventListener('input', (e) => {
        const val = e.target.value.trim();
        if (/^\d+$/.test(val)) {
            docIdInput.value = val;
            hideAc();
        } else {
            docIdInput.value = '';
            fetchAc(val);
        }
    });

    acList.addEventListener('mousedown', (e) => {
        const li = e.target.closest('li[data-id]');
        if (!li) return;
        e.preventDefault();
        titleInput.value = li.dataset.title;
        docIdInput.value = li.dataset.id;
        hideAc();
    });

    titleInput.addEventListener('blur', () => setTimeout(hideAc, 150));
    document.addEventListener('keydown', (e) => { if (e.key === 'Escape') hideAc(); });

    // ── Action radios + depth slider ──────────────────────────────────────────

    document.querySelectorAll('input[name="citAction"]').forEach(r => {
        r.addEventListener('change', () => { depthRow.hidden = r.value !== 'chain'; });
    });

    depthRange.addEventListener('input', () => { depthValue.textContent = depthRange.value; });

    // ── Form submit ───────────────────────────────────────────────────────────

    form.addEventListener('submit', async (e) => {
        e.preventDefault();

        let docId = parseInt(docIdInput.value, 10) || parseInt(titleInput.value.trim(), 10);
        if (!docId || docId <= 0) {
            setStatus('Enter a document title or numeric ID.', 'error');
            titleInput.focus();
            return;
        }

        const action = document.querySelector('input[name="citAction"]:checked').value;
        const params = { action, doc_id: docId, limit: 50 };
        if (action === 'chain') params.depth = parseInt(depthRange.value, 10);

        setStatus('Querying citation graph…', 'busy');
        runBtn.disabled = true;

        try {
            const url = 'https://ai.bluenotelogic.com/api/graph-search.php?' + new URLSearchParams(params);
            const res = await fetch(url, { credentials: 'omit' });

            if (res.status === 404) {
                setStatus('', '');
                renderNotFound(docId);
                return;
            }
            if (!res.ok) {
                setStatus('Graph error (' + res.status + ').', 'error');
                return;
            }

            const data = await res.json();
            if (data.error) { setStatus(data.error, 'error'); return; }

            setStatus('', '');
            renderResults(data, action);
            addToTrail(data.source);

        } catch (err) {
            setStatus('Network error: ' + err.message, 'error');
        } finally {
            runBtn.disabled = false;
        }
    });

    // ── Render ────────────────────────────────────────────────────────────────

    function renderNotFound(docId) {
        resultsDiv.hidden = false;
        sourceCard.innerHTML = '';
        resultsArea.innerHTML = '<p class="cit-no-results">Document '
            + esc(String(docId))
            + ' is not in the citation graph yet. The graph grows as new documents are scraped and resolved.</p>';
    }

    function renderResults(data, action) {
        const src = data.source;
        const atLabel = authorityLabel(src.atype);
        const year    = yearFrom(src.valid_from);

        sourceCard.innerHTML =
            '<p class="cit-source-card__title">' + esc(src.title || '(Untitled)') + '</p>'
            + '<div class="cit-source-card__meta">'
            + (atLabel ? '<span class="source-badge badge--teal">' + esc(atLabel) + '</span>' : '')
            + (year ? '<span>' + esc(year) + '</span>' : '')
            + (src.jurisdiction ? '<span>' + esc(src.jurisdiction) + '</span>' : '')
            + '<span style="color:var(--muted)">ID ' + esc(String(src.doc_id)) + '</span>'
            + (src.source_url ? '<a href="' + esc(src.source_url) + '" target="_blank" rel="noopener" style="color:var(--teal)">Source ↗</a>' : '')
            + '</div>';

        const results = data.results || [];
        const count   = data.count ?? results.length;

        const actionLabels = {
            cites: 'Documents cited',
            cited_by: 'Documents citing this',
            implements: 'Documents implementing / amending',
            chain: 'Reachable documents (citation chain)',
        };

        let html = '<div class="cit-results-header">'
            + '<p class="eyebrow">' + esc(actionLabels[action] || action) + '</p>'
            + '<span class="cit-results-count">' + esc(String(count)) + ' document' + (count !== 1 ? 's' : '') + '</span>'
            + '</div>';

        if (results.length === 0) {
            html += '<p class="cit-no-results">No connected documents found for this action.</p>';
        } else {
            html += '<div class="cit-grid">';
            for (const r of results) {
                const chipCls  = relChipClass(action, r.rel_type);
                const chipLbl  = relChipLabel(action, r.rel_type);
                const unresolved = r.doc_id === null || r.doc_id === undefined;
                const cardTitle  = r.title || '';
                const atl        = authorityLabel(r.atype);
                const yr         = yearFrom(r.valid_from);

                html += '<div class="cit-card' + (unresolved ? ' cit-card--unresolved' : '') + '">'
                    + '<span class="rel-chip ' + esc(chipCls) + '">' + esc(chipLbl) + '</span>'
                    + (cardTitle ? '<span class="cit-card__title">' + esc(cardTitle) + '</span>' : '')
                    + (!cardTitle && r.ref ? '<span class="cit-card__ref">' + esc(r.ref) + '</span>' : '')
                    + '<div class="cit-card__meta">'
                    + (atl ? '<span class="source-badge badge--muted">' + esc(atl) + '</span>' : '')
                    + (yr  ? '<span>' + esc(yr) + '</span>' : '')
                    + '</div>'
                    + (!unresolved ? '<button class="cit-explore-btn" type="button" data-explore-id="' + esc(String(r.doc_id)) + '" data-explore-title="' + esc(cardTitle) + '">Explore →</button>' : '')
                    + '</div>';
            }
            html += '</div>';
        }

        resultsArea.innerHTML = html;
        resultsDiv.hidden = false;

        resultsArea.querySelectorAll('.cit-explore-btn').forEach(btn => {
            btn.addEventListener('click', () => exploreDoc(parseInt(btn.dataset.exploreId, 10), btn.dataset.exploreTitle));
        });
    }

    // ── Trail ─────────────────────────────────────────────────────────────────

    function addToTrail(source) {
        if (trail.length && trail[trail.length - 1].doc_id === source.doc_id) return;
        trail.push({ doc_id: source.doc_id, title: source.title || '(Untitled)', atype: source.atype });
        renderTrail();
    }

    function renderTrail() {
        const placeholder = document.getElementById('trailPlaceholder');
        if (placeholder) placeholder.remove();

        trailList.innerHTML = '';
        for (let i = trail.length - 1; i >= 0; i--) {
            const entry     = trail[i];
            const isCurrent = i === trail.length - 1;
            const li        = document.createElement('li');
            li.className    = 'cit-trail-item' + (isCurrent ? ' is-active' : '');
            li.innerHTML    =
                '<span class="trace-status ' + (isCurrent ? 'running' : 'complete') + '"></span>'
                + '<div>'
                + '<strong>' + esc(entry.title) + '</strong>'
                + '<p>' + esc(authorityLabel(entry.atype) || 'Document') + ' · ID ' + esc(String(entry.doc_id)) + '</p>'
                + '</div>';
            if (!isCurrent) {
                li.addEventListener('click', () => exploreDoc(entry.doc_id, entry.title));
            }
            trailList.appendChild(li);
        }
    }

    // ── Navigation ────────────────────────────────────────────────────────────

    function exploreDoc(docId, title) {
        titleInput.value = title || String(docId);
        docIdInput.value = String(docId);
        hideAc();
        form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true }));
    }

})();
