'use client';

/**
 * Markdown 渲染（assistant 消息内容）—— GFM 表格 / 链接 / 列表 / 代码块
 *
 * React.memo：流式 turn 期间消息列表每个 text_delta 都重渲染，已完成消息的
 * MarkdownContent（含每个代码块的 hljs.highlight / highlightAuto）就会被反复重算。
 * 同 content prop 时跳过 re-render。
 */

import { memo } from 'react';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import hljs from 'highlight.js/lib/common';
import 'highlight.js/styles/github.css';

function escapeHtml(s: string): string {
  return s
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#x27;');
}

export const MarkdownContent = memo(function MarkdownContent({ content }: { content: string }) {
  return (
    // 紧凑容器：
    // - first/last child 去掉外 margin（贴边）
    // - 嵌套：<li> 内的 <p>/<ul>/<ol> 不再叠 margin
    // - 列表 item 间用 li 自身 mt 控制，不靠 children 撑高
    <div className="[&>*:first-child]:!mt-0 [&>*:last-child]:!mb-0 [&_li>p]:!my-0 [&_li>ul]:!my-1 [&_li>ol]:!my-1 [&_li>p+ul]:!mt-0.5 [&_li>p+ol]:!mt-0.5">
      <ReactMarkdown
        remarkPlugins={[remarkGfm]}
        components={{
          a: ({ node: _node, ...props }) => (
            <a
              {...props}
              target="_blank"
              rel="noopener noreferrer"
              className="text-blue-600 underline-offset-2 hover:underline dark:text-blue-400"
            />
          ),
          code: ({ node: _node, className, children, ...props }) => {
            const isBlock = /\bcode-block\b/.test(className ?? '') || className?.startsWith('language-');
            if (isBlock) {
              // highlight.js/lib/common ~35 常见语言（ts/js/py/bash/sql/json/yaml/html/css 等）
              const lang = className?.replace(/^language-/, '') ?? '';
              const raw = String(children).replace(/\n$/, '');
              let html: string;
              try {
                if (lang && hljs.getLanguage(lang)) {
                  html = hljs.highlight(raw, { language: lang, ignoreIllegals: true }).value;
                } else {
                  html = hljs.highlightAuto(raw).value;
                }
              } catch {
                html = escapeHtml(raw);
              }
              return (
                <pre className="my-2 overflow-x-auto rounded-lg bg-stone-100 p-3 text-[13px] leading-6 dark:bg-neutral-800">
                  <code
                    className="hljs"
                    {...props}
                    dangerouslySetInnerHTML={{ __html: html }}
                  />
                </pre>
              );
            }
            return (
              <code
                className="rounded bg-stone-100 px-1 py-0.5 font-mono text-[0.9em] dark:bg-neutral-800"
                {...props}
              >
                {children}
              </code>
            );
          },
          h1: ({ node: _node, ...props }) => <h1 className="mt-3 mb-1.5 text-lg font-semibold" {...props} />,
          h2: ({ node: _node, ...props }) => <h2 className="mt-2.5 mb-1 text-base font-semibold" {...props} />,
          h3: ({ node: _node, ...props }) => <h3 className="mt-2 mb-0.5 text-sm font-semibold" {...props} />,
          ul: ({ node: _node, ...props }) => <ul className="my-1 list-disc pl-5" {...props} />,
          ol: ({ node: _node, ...props }) => <ol className="my-1 list-decimal pl-5" {...props} />,
          li: ({ node: _node, ...props }) => <li className="my-0.5 leading-6" {...props} />,
          p: ({ node: _node, ...props }) => <p className="my-1 leading-7" {...props} />,
          blockquote: ({ node: _node, ...props }) => (
            <blockquote
              className="my-2 border-l-2 border-stone-300 pl-3 text-neutral-600 dark:border-neutral-700 dark:text-neutral-400"
              {...props}
            />
          ),
          table: ({ node: _node, ...props }) => (
            <div className="my-2 overflow-x-auto">
              <table className="w-full border-collapse text-[13px]" {...props} />
            </div>
          ),
          th: ({ node: _node, ...props }) => (
            <th className="border-b border-stone-200 px-2 py-1.5 text-left font-medium dark:border-neutral-700" {...props} />
          ),
          td: ({ node: _node, ...props }) => (
            <td className="border-b border-stone-100 px-2 py-1.5 align-top dark:border-neutral-800" {...props} />
          ),
          hr: ({ node: _node, ...props }) => <hr className="my-3 border-stone-200 dark:border-neutral-800" {...props} />,
        }}
      >
        {content}
      </ReactMarkdown>
    </div>
  );
});
