/**
 * CodeBlock Component
 *
 * 代码块组件，支持语法高亮和一键复制
 */

import { useState, useEffect, useRef } from 'react';
import { Copy, Check } from 'lucide-react';
import { codeToHtml } from 'shiki';
import { cn } from '../utils/cn';

interface CodeBlockProps {
  code: string;
  language?: string;
  className?: string;
}

export function CodeBlock({ code, language = 'text', className }: CodeBlockProps) {
  const [copied, setCopied] = useState(false);
  const [highlightedHtml, setHighlightedHtml] = useState<string>('');
  // 使用 ref 跟踪上一次高亮的代码，避免不必要的重新高亮
  const lastHighlightedCode = useRef<string>('');
  const highlightTimer = useRef<ReturnType<typeof setTimeout> | null>(null);

  // 语法高亮 - 使用防抖避免频繁高亮导致闪烁
  useEffect(() => {
    // 清除之前的定时器
    if (highlightTimer.current) {
      clearTimeout(highlightTimer.current);
    }

    // 如果代码没变，不需要重新高亮
    if (code === lastHighlightedCode.current && highlightedHtml) {
      return;
    }

    // 使用防抖：等待 150ms 后再进行高亮（流式输出时减少高亮次数）
    highlightTimer.current = setTimeout(async () => {
      try {
        const html = await codeToHtml(code, {
          lang: language,
          theme: 'github-dark',
        });
        lastHighlightedCode.current = code;
        setHighlightedHtml(html);
      } catch {
        // 如果语言不支持，回退到纯文本
        lastHighlightedCode.current = code;
        setHighlightedHtml(`<pre><code>${escapeHtml(code)}</code></pre>`);
      }
    }, 150);

    return () => {
      if (highlightTimer.current) {
        clearTimeout(highlightTimer.current);
      }
    };
  }, [code, language]);

  const handleCopy = async () => {
    await navigator.clipboard.writeText(code);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  return (
    <div className={cn('relative group rounded-lg overflow-hidden', className)}>
      {/* 语言标签和复制按钮 */}
      <div className="flex items-center justify-between px-4 py-2 bg-code border-b border-line">
        <span className="text-xs text-fg-muted font-mono">{language}</span>
        <button
          onClick={handleCopy}
          className="flex items-center gap-1 px-2 py-1 text-xs text-fg-muted hover:text-fg-secondary hover:bg-surface-muted rounded transition-colors"
          title="Copy code"
        >
          {copied ? (
            <>
              <Check size={14} className="text-green-500" />
              <span className="text-green-500">Copied!</span>
            </>
          ) : (
            <>
              <Copy size={14} />
              <span>Copy</span>
            </>
          )}
        </button>
      </div>

      {/* 代码内容 - 始终显示高亮后的内容，未高亮时显示纯文本 */}
      <div className="overflow-x-auto">
        {highlightedHtml ? (
          <div
            className="shiki-wrapper text-sm [&>pre]:p-4 [&>pre]:m-0 [&>pre]:bg-code"
            dangerouslySetInnerHTML={{ __html: highlightedHtml }}
          />
        ) : (
          <pre className="p-4 bg-code text-fg-secondary text-sm font-mono">
            <code>{code}</code>
          </pre>
        )}
      </div>
    </div>
  );
}

// 简单的内联代码组件
interface InlineCodeProps {
  children: React.ReactNode;
  className?: string;
}

export function InlineCode({ children, className }: InlineCodeProps) {
  return (
    <code
      className={cn(
        'px-1.5 py-0.5 rounded bg-surface-muted text-fg-secondary text-sm font-mono',
        className
      )}
    >
      {children}
    </code>
  );
}

// HTML 转义
function escapeHtml(str: string): string {
  return str
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#039;');
}
