// ==================================================================================
// MARKDOWN TEXT COMPONENT
// Renders markdown text with proper formatting
// ==================================================================================
const MarkdownText = ({ text, isUserMessage }) => {
    const renderMarkdown = (text) => {
        if (!text) {
            return '';
        }

        // Collapse 3+ newlines to 2 so AI over-spacing doesn't create huge gaps
        text = text.replace(/\n{3,}/g, '\n\n');

        // Fix common "numbered list got squished into one line" cases (tickets)
        if (text.includes('Ticket ID:')) {
            text = text.replace(/(?<!^)(?<!\n)(\d+\.\s*Ticket ID:)/g, '\n$1');
        }

        // IMPORTANT: Protect links/URLs BEFORE italic/bold parsing
        const linkTokens = [];
        const urlTokens = [];

        // 1) Tokenize markdown links: [label](url)
        text = text.replace(/\[([^\]]+?)\]\(([^)]+?)\)/g, (match, label, url) => {
            const token = `MDLINKTOKEN${linkTokens.length}`;
            linkTokens.push({ label, url });
            return token;
        });

        // 2) Tokenize HTML anchors if the model ever outputs them
        text = text.replace(/<a\b[^>]*href=["']([^"']+)["'][^>]*>(.*?)<\/a>/gi, (match, url, label) => {
            const token = `MDLINKTOKEN${linkTokens.length}`;
            linkTokens.push({ label, url });
            return token;
        });

        // 3) Tokenize bare URLs so underscores don't get parsed as italics
        text = text.replace(/(https?:\/\/[^\s<>"']+)/g, (match, url) => {
            const token = `MDURLTOKEN${urlTokens.length}`;
            urlTokens.push({ url });
            return token;
        });

        // 4) Escape any raw HTML
        const escapeHtml = (s) => s
            .replace(/&/g, '&amp;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');

        let safe = escapeHtml(text);

        // Convert markdown to HTML (order matters! match #### before ###)
        let html = safe
            // Headers — mark them so we don't insert extra <br/> around them later
            .replace(/^#### (.+)$/gm, '<h4 class="markdown-h4">$1</h4><!--NL_OFF-->')
            .replace(/^### (.+)$/gm, '<h3 class="markdown-h3">$1</h3><!--NL_OFF-->')
            .replace(/^## (.+)$/gm, '<h2 class="markdown-h2">$1</h2><!--NL_OFF-->')
            .replace(/^# (.+)$/gm, '<h1 class="markdown-h1">$1</h1><!--NL_OFF-->')
            // Bold
            .replace(/\*\*([^\*]+?)\*\*/g, '<strong class="font-bold">$1</strong>')
            .replace(/__([^_]+?)__/g, '<strong class="font-bold">$1</strong>')
            // Italic
            .replace(/(?<!\*)\*([^*]+?)\*(?!\*)/g, '<em class="italic">$1</em>')
            .replace(/(?<!_)_([^_]+?)_(?!_)/g, '<em class="italic">$1</em>')
            // Code
            .replace(/`([^`]+?)`/g, '<code class="bg-gray-100 px-1 py-0.5 rounded text-sm font-mono">$1</code>');

        // Restore markdown link tokens
        html = html.replace(/(?:__)?MDLINKTOKEN(\d+)(?:__)?/g, (match, idx) => {
            const i = parseInt(idx, 10);
            const item = linkTokens[i];
            if (!item) return match;
            return `<a href="${item.url}" target="_blank" rel="noopener noreferrer" class="underline">${item.label}</a>`;
        });

        // Restore bare URL tokens
        html = html.replace(/(?:__)?MDURLTOKEN(\d+)(?:__)?/g, (match, idx) => {
            const i = parseInt(idx, 10);
            const item = urlTokens[i];
            if (!item) return match;
            return `<a href="${item.url}" target="_blank" rel="noopener noreferrer" class="underline">${item.url}</a>`;
        });

        // Process lists
        const lines = html.split('\n');
        let inUl = false;
        let inOl = false;
        let processedLines = [];

        const closeLists = () => {
            // Close any open lists. We deliberately do NOT tag these with <!--NL_OFF-->
            // so that a real line break between a bullet block and the next vendor header
            // becomes a small visual gap between groups.
            if (inUl) { processedLines.push('</ul>'); inUl = false; }
            if (inOl) { processedLines.push('</ol>'); inOl = false; }
        };

        for (let i = 0; i < lines.length; i++) {
            const line = lines[i];
            // Allow a bit of leading whitespace before bullets so lines like "   - Phone: ..."
            // are still treated as list items.
            const ulMatch = line.match(/^\s*[\*\-]\s+(.+)$/);
            const olMatch = line.match(/^\s*(\d+)\.\s+(.+)$/);

            if (ulMatch) {
                if (inOl) { processedLines.push('</ol>'); inOl = false; }
                if (!inUl) {
                    // Start a new bullet list with minimal extra spacing.
                    // Tag with <!--NL_OFF--> so we can strip the automatic <br/> after block tags later.
                    processedLines.push('<ul class="markdown-list"><!--NL_OFF-->');
                    inUl = true;
                }
                processedLines.push(`<li class="markdown-list-item">${ulMatch[1]}</li><!--NL_OFF-->`);
                continue;
            }

            if (olMatch) {
                if (inUl) { processedLines.push('</ul>'); inUl = false; }
                if (!inOl) {
                    // Start a new ordered list with minimal extra spacing
                    processedLines.push('<ol class="markdown-olist"><!--NL_OFF-->');
                    inOl = true;
                }
                processedLines.push(`<li class="markdown-olist-item">${olMatch[2]}</li><!--NL_OFF-->`);
                continue;
            }

            closeLists();

            if (line.trim()) {
                processedLines.push(line);
            }
        }

        closeLists();

        // Join lines and convert line breaks.
        // 1) Join using newlines so we can reason about where <br/> should appear.
        // 2) Strip newlines that immediately follow special <!--NL_OFF--> markers attached
        //    to block elements like headings and list tags, so we don't get stray <br/>
        //    between <ol>, <ul>, <li>, and headings.
        // 3) Collapse any remaining multiple newlines, then convert to <br/>.
        html = processedLines.join('\n');
        html = html.replace(/<!--NL_OFF-->\n/g, '<!--NL_OFF-->'); // remove newline right after marker
        html = html.replace(/\n{2,}/g, '\n');
        html = html.replace(/\n/g, '<br/>');
        html = html.replace(/<!--NL_OFF-->/g, ''); // finally drop the markers

        // Final cleanup: remove any stray <br/> between vendor headers (in <ol>)
        // and the bullet list that follows, so the bullets "hug" the header.
        html = html.replace(/<\/ol><br\/?>\s*<ul/g, '</ol><ul');

        return html;
    };

    const htmlContent = renderMarkdown(text);

    return (
        <div
            className={`markdown-content ${isUserMessage ? 'user-message-content' : ''}`}
            dangerouslySetInnerHTML={{ __html: htmlContent }}
        />
    );
};

if (typeof window !== 'undefined') window.MarkdownText = MarkdownText;
