"use client"

import { memo, useState, useCallback } from "react"
import ReactMarkdown from "react-markdown"
import remarkGfm from "remark-gfm"
import { Copy, Check } from "lucide-react"
import { useTranslations } from "next-intl"
import { toast } from "sonner"

import { Button } from "@/shared/components/ui/button"
import { cn } from "@/shared/lib/utils"
import { AiChartRenderer, type AiChartType } from "./ai-chart-renderer"

type AiMarkdownRendererProps = {
  content: string
  /** 是否显示复制按钮 */
  showCopyButton?: boolean
  /** 自定义类名 */
  className?: string
}

/** 支持的图表类型映射：language → chart type */
const CHART_LANG_PREFIX = "chart:"
const CHART_TYPES: Record<string, AiChartType> = {
  "chart:bar": "bar",
  "chart:line": "line",
  "chart:pie": "pie",
  "chart:radar": "radar",
}

/**
 * 类型守卫：判断字符串是否为合法的 AiChartType
 */
function isAiChartType(value: string): value is AiChartType {
  return value === "bar" || value === "line" || value === "pie" || value === "radar"
}

/**
 * 从 language 标识中解析图表类型
 */
function resolveChartType(lang: string): AiChartType | undefined {
  // 优先查表（兼容 "chart:bar" 形式）
  const fromTable = CHART_TYPES[`${CHART_LANG_PREFIX}${lang}`]
  if (fromTable) return fromTable
  // 兼容 "chart:bar" 前缀形式
  if (lang.startsWith(CHART_LANG_PREFIX)) {
    const suffix = lang.slice(CHART_LANG_PREFIX.length)
    return isAiChartType(suffix) ? suffix : undefined
  }
  return undefined
}

/**
 * AI Markdown 渲染器
 *
 * 将 AI 回复渲染为富文本 Markdown，支持：
 * - GFM（表格、删除线、任务列表）
 * - 代码块语法高亮
 * - 图表渲染（```chart:bar|line|pie|radar + JSON）
 * - 复制按钮
 *
 * 安全：react-markdown 默认不执行 HTML，防止 XSS。
 */
function AiMarkdownRendererImpl({
  content,
  showCopyButton = true,
  className,
}: AiMarkdownRendererProps): React.ReactNode {
  const t = useTranslations("ai")
  const [copied, setCopied] = useState(false)

  const handleCopy = useCallback(async (): Promise<void> => {
    try {
      await navigator.clipboard.writeText(content)
      setCopied(true)
      toast.success(t("chat.copied"))
      setTimeout(() => setCopied(false), 2000)
    } catch {
      toast.error(t("error.chatFailed"))
    }
  }, [content, t])

  return (
    <div className="group relative">
      <div
        className={cn(
          "prose prose-sm dark:prose-invert max-w-none",
          "prose-p:my-1 prose-ul:my-1 prose-ol:my-1 prose-li:my-0",
          "prose-code:before:content-none prose-code:after:content-none",
          "prose-pre:bg-muted prose-pre:p-3 prose-pre:rounded-md",
          className
        )}
      >
        <ReactMarkdown
          remarkPlugins={[remarkGfm]}
          components={{
            code({ className: codeClass, children, ...props }) {
              const isInline = !codeClass?.includes("language-")
              if (isInline) {
                return (
                  <code
                    className="rounded bg-muted px-1 py-0.5 text-xs font-mono"
                    {...props}
                  >
                    {children}
                  </code>
                )
              }

              // 检测图表代码块：language-chart:bar / chart:line / chart:pie / chart:radar
              const lang = codeClass?.replace("language-", "").trim() ?? ""
              const chartType = resolveChartType(lang)

              if (chartType) {
                const raw = String(children).replace(/\n$/, "")
                return <AiChartRenderer type={chartType} spec={raw} />
              }

              return (
                <code className={codeClass} {...props}>
                  {children}
                </code>
              )
            },
            a({ children, ...props }) {
              return (
                <a
                  {...props}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="text-primary underline underline-offset-2"
                >
                  {children}
                </a>
              )
            },
          }}
        >
          {content}
        </ReactMarkdown>
      </div>
      {showCopyButton ? (
        <Button
          type="button"
          variant="ghost"
          size="sm"
          className="absolute top-0 right-0 opacity-0 group-hover:opacity-100 transition-opacity h-7 px-2"
          onClick={() => void handleCopy()}
          aria-label={t("chat.copy")}
        >
          {copied ? (
            <Check className="h-3.5 w-3.5 text-green-500" />
          ) : (
            <Copy className="h-3.5 w-3.5" />
          )}
        </Button>
      ) : null}
    </div>
  )
}

export const AiMarkdownRenderer = memo(AiMarkdownRendererImpl)
