// ==========================================
// ChatPane Kit — Markdown Renderer
// ==========================================
// Wraps window.marked + window.DOMPurify with fallback.
// Independently importable utility.
//
// Note: This module uses innerHTML via DOMPurify (sanitized) and imperative
// DOM patterns intentionally for rendering performance. This is a documented
// exception from the "no raw DOM" convention (Critical Review P3-4).
//
// v0.37.10: Task list rendering, code block language extraction.
//
// Usage:
//   import { renderMarkdown } from './markdown.js';
//   const html = renderMarkdown('**bold** text');

let _lastInput = '';
let _lastOutput = '';

const _escMap = { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' };

function _escapeHtml(text) {
    return text.replace(/[&<>"']/g, c => _escMap[c]);
}

/**
 * Configure marked with task list support if available.
 */
let _configured = false;
function _ensureConfigured() {
    if (_configured) return;
    _configured = true;
    if (typeof marked === 'undefined') return;

    marked.setOptions({
        breaks: true,
        gfm: true,
    });

    // Custom renderer for task list items (marked v16 token-based API)
    marked.use({
        renderer: {
            listitem(token) {
                const body = this.parser.parse(token.tokens);
                if (token.task) {
                    const checkbox = token.checked
                        ? '<input type="checkbox" checked disabled class="sw-task-checkbox" />'
                        : '<input type="checkbox" disabled class="sw-task-checkbox" />';
                    return '<li class="sw-task-item">' + checkbox + ' ' + body + '</li>\n';
                }
                return '<li>' + body + '</li>\n';
            },
        },
    });
}

/**
 * Render markdown text to sanitized HTML.
 * Falls back to escaped plaintext when marked/DOMPurify unavailable.
 *
 * @param {string} text — raw markdown
 * @returns {string} sanitized HTML
 */
export function renderMarkdown(text) {
    if (!text) return '';
    if (text === _lastInput) return _lastOutput;

    let result;
    if (typeof marked !== 'undefined' && typeof DOMPurify !== 'undefined') {
        _ensureConfigured();
        result = DOMPurify.sanitize(marked.parse(text));
    } else {
        result = _escapeHtml(text);
    }

    // Highlight @mentions as styled spans (runs after sanitization — safe)
    result = result.replace(/(^|[\s>])@([\w-]+)/g, '$1<span class="sw-mention">@$2</span>');

    // Run pipe render filters (extensions can transform final HTML)
    if (window.sw?.pipe?._runRender) {
        const pipeCtx = window.sw.pipe._runRender({ html: result, raw: text });
        if (pipeCtx !== null && pipeCtx !== undefined) {
            result = pipeCtx.html;
        }
    }

    _lastInput = text;
    _lastOutput = result;
    return result;
}
