import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
import React__default, { useMemo, useRef } from 'react';
import ReactMarkdown from 'react-markdown';
import { Prism } from 'react-syntax-highlighter';
import { oneDark, oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
import remarkGfm from 'remark-gfm';
import { useReducedMotion, motion } from 'motion/react';
import { blockTransition, blockSlideIn } from './StreamingResponse.animations.js';
import { WordAnimationProvider, useWordAnimation } from './WordAnimationContext.js';

/**
 * Wrapper that optionally animates block-level elements during streaming.
 * Once an element has animated in, it stays static (no re-animation on re-render).
 * Used for structural elements like code blocks and tables.
 */
const AnimatedBlock = ({ children, animate, className, as = 'div' }) => {
    const hasAnimatedRef = useRef(false);
    const shouldAnimate = animate && !hasAnimatedRef.current;
    // Mark as animated after first render
    if (animate) {
        hasAnimatedRef.current = true;
    }
    if (!shouldAnimate) {
        const Tag = as;
        return jsx(Tag, { className: className, children: children });
    }
    const MotionTag = as === 'p' ? motion.p : motion.div;
    return (jsx(MotionTag, { variants: blockSlideIn, initial: "hidden", animate: "visible", transition: blockTransition, className: className, children: children }));
};
/**
 * Prose wrapper — uses word-level animation from context for text elements.
 * Falls back to plain rendering when animation is disabled.
 */
const AnimatedProse = ({ children, className, as: tag = 'p', }) => {
    const wordAnim = useWordAnimation();
    const content = wordAnim ? wordAnim.processChildren(children) : children;
    return React__default.createElement(tag, { className }, content);
};
/**
 * Skip counter — counts words in non-prose children to keep counter in sync.
 */
const SkipWords = ({ children }) => {
    const wordAnim = useWordAnimation();
    if (wordAnim) {
        wordAnim.skipChildren(children);
    }
    return null;
};
/**
 * MarkdownRenderer component for rendering markdown with syntax highlighting
 * Supports GitHub Flavored Markdown (tables, task lists, strikethrough, etc.)
 * Animates individual words during streaming with a fade-in + blur effect
 */
const MarkdownRenderer = ({ content, options = {}, isStreaming = false, animated = true, showCursor = true, animateLastN = 12, }) => {
    const { allowHtml = false, syntaxTheme = 'light', renderCodeBlock } = options;
    const shouldReduceMotion = useReducedMotion();
    const shouldAnimate = animated && isStreaming && !shouldReduceMotion;
    // Append cursor character to content so it renders inline within the last element
    const displayContent = isStreaming && showCursor
        ? content + ' ▏'
        : content;
    const markdownComponents = useMemo(() => ({
        // Code blocks with syntax highlighting
        code({ inline, className, children, ...props }) {
            const match = /language-(\w+)/.exec(className || '');
            const language = match ? match[1] : '';
            // Use custom code block renderer if provided
            if (!inline && renderCodeBlock && language) {
                return (jsxs(AnimatedBlock, { animate: shouldAnimate, children: [jsx(SkipWords, { children: children }), renderCodeBlock(String(children).replace(/\n$/, ''), language)] }));
            }
            // Render syntax-highlighted code block
            if (!inline && language) {
                return (jsxs(AnimatedBlock, { animate: shouldAnimate, children: [jsx(SkipWords, { children: children }), jsx(Prism, { style: syntaxTheme === 'dark' ? oneDark : oneLight, language: language, PreTag: "div", className: "rounded-lg my-3", ...props, children: String(children).replace(/\n$/, '') })] }));
            }
            // Inline code — skip word animation for code tokens
            return (jsxs(Fragment, { children: [jsx(SkipWords, { children: children }), jsx("code", { className: "bg-(--color-background-tertiary) text-(--color-primary) px-1.5 py-0.5 rounded text-base font-mono", ...props, children: children })] }));
        },
        // Paragraphs — word-level animation
        p({ children }) {
            return (jsx(AnimatedProse, { as: "p", className: "mb-3 last:mb-0 text-(--color-text-primary) leading-relaxed", children: children }));
        },
        // Headings — word-level animation
        h1({ children }) {
            return (jsx(AnimatedProse, { as: "h1", className: "text-2xl font-bold mb-4 text-(--color-text-primary) border-b border-(--color-border) pb-2", children: children }));
        },
        h2({ children }) {
            return (jsx(AnimatedProse, { as: "h2", className: "text-2xl font-bold mb-3 text-(--color-text-primary) border-b border-(--color-border) pb-2", children: children }));
        },
        h3({ children }) {
            return (jsx(AnimatedProse, { as: "h3", className: "text-xl font-semibold mb-2 text-(--color-text-primary)", children: children }));
        },
        h4({ children }) {
            return (jsx(AnimatedProse, { as: "h4", className: "text-lg font-semibold mb-2 text-(--color-text-primary)", children: children }));
        },
        h5({ children }) {
            return (jsx(AnimatedProse, { as: "h5", className: "text-base font-semibold mb-2 text-(--color-text-primary)", children: children }));
        },
        h6({ children }) {
            return (jsx(AnimatedProse, { as: "h6", className: "text-base font-semibold mb-2 text-(--color-text-secondary)", children: children }));
        },
        // Lists — word-level animation on li
        ul({ children }) {
            return (jsx("ul", { className: "list-disc list-inside mb-3 space-y-1 text-(--color-text-primary)", children: children }));
        },
        ol({ children }) {
            return (jsx("ol", { className: "list-decimal list-inside mb-3 space-y-1 text-(--color-text-primary)", children: children }));
        },
        li({ children }) {
            return (jsx(AnimatedProse, { as: "li", className: "ml-4", children: children }));
        },
        // Blockquotes — word-level animation
        blockquote({ children }) {
            return (jsx("blockquote", { className: "border-l-4 border-(--color-primary) pl-4 py-2 my-3 bg-(--color-background-secondary) italic text-(--color-text-secondary)", children: children }));
        },
        // Links
        a({ href, children }) {
            return (jsx("a", { href: href, className: "text-(--color-primary) hover:text-(--color-primary-700) underline transition-colors", target: "_blank", rel: "noopener noreferrer", children: children }));
        },
        // Tables — block-level slide-in, skip word animation
        table({ children }) {
            return (jsxs(AnimatedBlock, { animate: shouldAnimate, children: [jsx(SkipWords, { children: children }), jsx("div", { className: "overflow-x-auto my-3", children: jsx("table", { className: "min-w-full border-collapse border border-(--color-border)", children: children }) })] }));
        },
        thead({ children }) {
            return jsx("thead", { className: "bg-(--color-background-secondary)", children: children });
        },
        tbody({ children }) {
            return jsx("tbody", { children: children });
        },
        tr({ children }) {
            return jsx("tr", { className: "border-b border-(--color-border)", children: children });
        },
        th({ children }) {
            return (jsx("th", { className: "px-4 py-2 text-left font-semibold text-(--color-text-primary) border border-(--color-border)", children: children }));
        },
        td({ children }) {
            return (jsx("td", { className: "px-4 py-2 text-(--color-text-primary) border border-(--color-border)", children: children }));
        },
        // Horizontal rule
        hr() {
            return jsx("hr", { className: "my-4 border-t border-(--color-border)" });
        },
        // Strong/Bold — pass through (word animation handles inline elements)
        strong({ children }) {
            return jsx("strong", { className: "font-semibold text-(--color-text-primary)", children: children });
        },
        // Emphasis/Italic
        em({ children }) {
            return jsx("em", { className: "italic", children: children });
        },
        // Strikethrough (from remarkGfm)
        del({ children }) {
            return jsx("del", { className: "line-through text-(--color-text-secondary)", children: children });
        },
    }), [shouldAnimate, syntaxTheme, renderCodeBlock]);
    return (jsx(WordAnimationProvider, { content: displayContent, enabled: shouldAnimate, animateLastN: animateLastN, hasCursor: isStreaming && showCursor, children: jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], skipHtml: !allowHtml, components: markdownComponents, children: displayContent }) }));
};
MarkdownRenderer.displayName = 'MarkdownRenderer';

export { MarkdownRenderer };
