/**
 * Matrix Cycling Blog - Markdown Parser Engine
 * Lightweight, zero-dependency Markdown parser with custom extensions for Matrix/FreeBSD alerts and code blocks.
 */

window.MatrixMarkdown = (function () {
    function escapeHtml(text) {
        return text
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }

    function render(md) {
        if (!md) return "";

        let html = md;

        // 1. Code blocks with headers ```lang:title ... ```
        html = html.replace(/```([a-zA-Z0-9_-]*)(?::([^\n]+))?\n([\s\S]*?)```/g, function (match, lang, title, code) {
            const headerTitle = title ? title.trim() : (lang ? lang.toUpperCase() : "CODE");
            const escapedCode = escapeHtml(code.trim());
            return `
<div class="code-block">
    <div class="code-header">
        <span>${escapeHtml(headerTitle)}</span>
        <span>${escapeHtml((lang || "SHELL").toUpperCase())}</span>
    </div>
    <pre><code>${escapedCode}</code></pre>
</div>`;
        });

        // 2. Custom Alerts: > [!TIP], > [!WARN], > [!DANGER], > [!NOTE]
        html = html.replace(/^>\s*\[!(TIP|WARN|WARNING|DANGER|NOTE|INFO)\](?:\s*([^\n]+))?\n((?:>.*\n?)*)/gim, function (match, type, title, body) {
            const alertType = type.toLowerCase() === "warning" ? "warn" : (type.toLowerCase() === "info" ? "tip" : type.toLowerCase());
            const alertTitle = title ? title.trim() : (
                alertType === "tip" ? "💡 Совет из практики:" :
                alertType === "warn" ? "⚠️ Внимание / Грабли:" :
                alertType === "danger" ? "🚨 Ошибка / Критично:" : "📌 Примечание:"
            );
            const cleanBody = body.replace(/^>\s?/gm, "").trim();
            const renderedBody = renderInline(cleanBody);
            return `
<div class="alert-box ${alertType}">
    <span class="alert-title">${escapeHtml(alertTitle)}</span>
    <div>${renderedBody}</div>
</div>`;
        });

        // 3. Blockquotes: > quote text
        html = html.replace(/^>\s+(.+)$/gm, function (match, text) {
            return `<blockquote>${renderInline(text)}</blockquote>`;
        });

        // 4. Headers: #, ##, ###, ####
        html = html.replace(/^#### (.*?)$/gm, '<h4 style="color: var(--accent-cyan); margin: 12px 0 6px 0;">$1</h4>');
        html = html.replace(/^### (.*?)$/gm, '<h3 style="color: var(--accent-cyan); margin: 14px 0 8px 0;">$1</h3>');
        html = html.replace(/^## (.*?)$/gm, '<h2 style="color: var(--accent-green); margin: 16px 0 10px 0;">$1</h2>');
        html = html.replace(/^# (.*?)$/gm, '<h1 style="color: var(--accent-green); margin: 20px 0 12px 0;">$1</h1>');

        // 5. Images: ![alt](url)
        html = html.replace(/!\[(.*?)\]\((.*?)\)/g, function (match, alt, url) {
            return `<div style="margin: 14px 0; border-radius: 4px; overflow: hidden;"><img src="${escapeHtml(url)}" alt="${escapeHtml(alt)}" style="width: 100%; height: auto; border-radius: 4px; border: 1px solid var(--border-color);" loading="lazy"></div>`;
        });

        // 6. Links: [text](url)
        html = html.replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>');

        // 7. Unordered lists: - item or * item
        html = html.replace(/^(?:-|\*)\s+(.+)$/gm, '<li class="md-li">$1</li>');
        html = html.replace(/((?:<li class="md-li">.*?<\/li>\s*)+)/gs, '<ul style="margin: 10px 0 14px 22px; line-height: 1.7;">$1</ul>');

        // 8. Ordered lists: 1. item
        html = html.replace(/^\d+\.\s+(.+)$/gm, '<li class="md-oli">$1</li>');
        html = html.replace(/((?:<li class="md-oli">.*?<\/li>\s*)+)/gs, '<ol style="margin: 10px 0 14px 22px; line-height: 1.7;">$1</ol>');

        // 9. Horizontal rules: --- or ***
        html = html.replace(/^---|\*\*\*$/gm, '<hr style="border: 0; border-top: 1px dashed var(--border-color); margin: 16px 0;">');

        // 10. Split by double newlines for paragraphs (if not already inside custom elements)
        const parts = html.split(/\n\n+/);
        const processedParts = parts.map(part => {
            part = part.trim();
            if (!part) return "";
            if (part.startsWith("<div") || part.startsWith("<ul") || part.startsWith("<ol") || 
                part.startsWith("<h") || part.startsWith("<blockquote") || part.startsWith("<hr")) {
                return part;
            }
            return `<p>${renderInline(part.replace(/\n/g, "<br>"))}</p>`;
        });

        return processedParts.filter(Boolean).join("\n\n");
    }

    function renderInline(text) {
        if (!text) return "";
        let inline = text;

        // Bold + Italic: ***text*** or ___text___
        inline = inline.replace(/\*\*\*(.*?)\*\*\*/g, '<strong><em>$1</em></strong>');
        // Bold: **text**
        inline = inline.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
        // Italic: *text* or _text_
        inline = inline.replace(/\*([^\*]+)\*/g, '<em>$1</em>');
        inline = inline.replace(/_([^_]+)_/g, '<em>$1</em>');
        // Strikethrough: ~~text~~
        inline = inline.replace(/~~(.*?)~~/g, '<del>$1</del>');
        // Inline code: `code`
        inline = inline.replace(/`([^`]+)`/g, '<code style="background: var(--bg-code); color: var(--accent-green); padding: 2px 6px; border-radius: 3px; border: 1px solid var(--border-color); font-size: 0.9em;">$1</code>');

        return inline;
    }

    return {
        render: render,
        renderInline: renderInline
    };
})();
