"use client"

import ReactMarkdown from "react-markdown"
import remarkGfm from "remark-gfm"
import rehypeHighlight from "rehype-highlight"
import "highlight.js/styles/github-dark.css"
import { DiffTool } from "./diff-tool"
import { useState, isValidElement, type ReactNode } from "react"
import { cn } from "@/lib/utils"
import { Copy } from "lucide-react"

interface MarkdownRendererProps {
  content: string
  className?: string
  tone?: "default" | "bubble"
}

// Parse diff tool calls from markdown content
function parseDiffTools(content: string) {
  const diffToolRegex = /```diff-tool\n([\s\S]*?)\n```/g
  const tools: Array<{ match: string; props: any }> = []
  let match

  while ((match = diffToolRegex.exec(content)) !== null) {
    try {
      const props = JSON.parse(match[1])
      tools.push({ match: match[0], props })
    } catch (e) {
      console.error('Failed to parse diff tool:', e)
    }
  }

  return tools
}

export function MarkdownRenderer({ content, className = "", tone = "default" }: MarkdownRendererProps) {
  // Parse diff tools from content
  const diffTools = parseDiffTools(content)
  let processedContent = content

  // Replace diff tool calls with placeholders
  diffTools.forEach((tool, index) => {
    processedContent = processedContent.replace(tool.match, `__DIFF_TOOL_${index}__`)
  })

  const baseTone = tone === "bubble"
    ? "text-charcoal dark:text-white"
    : "text-charcoal dark:text-foreground"

  const mutedTone = tone === "bubble"
    ? "text-charcoal/80 dark:text-white/80"
    : "text-charcoal/80 dark:text-foreground/75"

  return (
    <div className={cn("markdown-glass space-y-3 text-sm leading-relaxed", baseTone, className)}>
      <ReactMarkdown
        remarkPlugins={[remarkGfm]}
        rehypePlugins={[rehypeHighlight]}
        components={{
          // Custom component for diff tool placeholders
          p: ({ children }) => {
            const text = typeof children === 'string' ? children : children?.toString() || ''
            const diffToolMatch = text.match(/^__DIFF_TOOL_(\d+)__$/)
            
            if (diffToolMatch) {
              const index = parseInt(diffToolMatch[1])
              const tool = diffTools[index]
              if (tool) {
                return (
                  <DiffTool
                    oldCode={tool.props.oldCode}
                    newCode={tool.props.newCode}
                    title={tool.props.title}
                    language={tool.props.language}
                  />
                )
              }
            }
            
            return (
              <p className={cn("mb-2 text-sm leading-relaxed last:mb-0", baseTone)}>
                {children}
              </p>
            )
          },
          // Custom styling for different elements
          h1: ({ children }) => (
            <h1 className={cn("text-[2rem] font-semibold tracking-tight", baseTone)}>
              {children}
            </h1>
          ),
          h2: ({ children }) => (
            <h2 className={cn("text-[1.75rem] font-semibold tracking-tight", baseTone)}>
              {children}
            </h2>
          ),
          h3: ({ children }) => (
            <h3 className={cn("text-[1.5rem] font-semibold", baseTone)}>
              {children}
            </h3>
          ),
          ul: ({ children }) => (
            <ul className={cn("mb-2 list-disc space-y-1 pl-4 text-sm", mutedTone)}>
              {children}
            </ul>
          ),
          ol: ({ children }) => (
            <ol className={cn("mb-2 list-decimal space-y-1 pl-4 text-sm", mutedTone)}>
              {children}
            </ol>
          ),
          li: ({ children }) => (
            <li className={cn("text-sm", mutedTone)}>
              {children}
            </li>
          ),
          code: ({ children, className }) => {
            // Check if this is inline code (no language class) or block code
            const isInline = !className
            if (isInline) {
              return (
                <code className="rounded bg-white/60 px-1.5 py-0.5 font-mono text-xs text-charcoal dark:bg-white/10 dark:text-foreground">
                  {children}
                </code>
              )
            }
            return (
              <code className={className}>
                {children}
              </code>
            )
          },
          pre: ({ children, className }) => (
            <PreWithCopy className={className}>{children}</PreWithCopy>
          ),
          blockquote: ({ children }) => (
            <blockquote className="border-l-2 border-burnt/70 pl-4 text-sm italic text-muted-foreground dark:text-foreground/80">
              {children}
            </blockquote>
          ),
          a: ({ children, href }) => (
            <a 
              href={href} 
              target="_blank" 
              rel="noopener noreferrer"
              className="underline decoration-burnt/40 decoration-2 underline-offset-4 text-burnt hover:text-terracotta dark:text-white dark:hover:text-burnt"
            >
              {children}
            </a>
          ),
          strong: ({ children }) => (
            <strong className="font-semibold text-charcoal dark:text-white">
              {children}
            </strong>
          ),
          em: ({ children }) => (
            <em className={cn("italic", mutedTone)}>
              {children}
            </em>
          ),
          table: ({ children }) => (
            <div className="overflow-x-auto mb-3">
              <table className="min-w-full rounded-lg border border-border/50">
                {children}
              </table>
            </div>
          ),
          thead: ({ children }) => (
            <thead className="bg-white/70 text-charcoal dark:bg-white/10 dark:text-foreground">
              {children}
            </thead>
          ),
          tbody: ({ children }) => (
            <tbody className="bg-white/40 text-charcoal dark:bg-white/5 dark:text-foreground">
              {children}
            </tbody>
          ),
          tr: ({ children }) => (
            <tr className="border-b border-border/40">
              {children}
            </tr>
          ),
          th: ({ children }) => (
            <th className="px-4 py-2 text-left text-sm font-semibold text-charcoal dark:text-foreground">
              {children}
            </th>
          ),
          td: ({ children }) => (
            <td className="px-4 py-2 text-sm text-charcoal dark:text-foreground">
              {children}
            </td>
          ),
        }}
      >
        {content}
      </ReactMarkdown>
    </div>
  )
}

function PreWithCopy({ children, className }: { children?: ReactNode; className?: string }) {
  const [copied, setCopied] = useState(false)
  const text = extractCodeText(children)

  const handleCopy = async () => {
    try {
      await navigator.clipboard.writeText(text.trimEnd())
      setCopied(true)
      setTimeout(() => setCopied(false), 1200)
    } catch (error) {
      console.error("[markdown] Code copy failed", error)
    }
  }

  return (
    <div className="relative mb-3">
      <pre className={cn("overflow-x-auto rounded-xl border border-border/50 p-4 text-sm text-charcoal shadow-sm dark:border-white/10 dark:text-foreground", className)}>
        {children}
      </pre>
      <button
        type="button"
        onClick={handleCopy}
        className={cn(
          "absolute right-3 top-3 inline-flex h-5 w-5 items-center justify-center rounded border border-white/25 bg-white/8 text-white/70 shadow-[0_2px_4px_rgba(0,0,0,0.06)] backdrop-blur transition-transform duration-150 hover:bg-white/18",
          copied && "scale-90 bg-white/30 text-white"
        )}
        aria-label="Copy code"
      >
        <Copy className="h-2.5 w-2.5" />
      </button>
    </div>
  )
}

function extractCodeText(node: ReactNode): string {
  if (typeof node === "string") {
    return node
  }
  if (Array.isArray(node)) {
    return node.map(extractCodeText).join("")
  }
  if (isValidElement(node)) {
    return extractCodeText(node.props.children)
  }
  return ""
}
