// Renders an assistant message: markdown for prose, plus pills for any
// command-bus action blocks or native tool calls attached to the message.
// Tool-role messages (results from a function call) render as a JSON card.

import { useMemo } from "react"
import ReactMarkdown from "react-markdown"
import { Sparkles, Wrench } from "lucide-react"

import { extractActionBlocks } from "@crema/action-bus"
import { stripToolCallTags, type ToolCall } from "@crema/llm-ui"

const ACTION_BLOCK_RE = /```action\s*\n[\s\S]*?```/g

export type MessageBodyProps = {
  content: string
  /** When set, render as a tool-result card. */
  isToolResult?: boolean
  /** Native tool calls attached to this assistant message, if any. */
  toolCalls?: ToolCall[]
}

export function MessageBody({ content, isToolResult, toolCalls }: MessageBodyProps) {
  const { prose, actionCount } = useMemo(() => {
    const blocks = extractActionBlocks(content)
    const cleaned = stripToolCallTags(content).replace(ACTION_BLOCK_RE, "").trim()
    return {
      prose: cleaned,
      actionCount: blocks.length,
    }
  }, [content])

  if (isToolResult) {
    return (
      <div className="rounded-md border border-border/60 bg-muted/40 px-3 py-2 text-xs">
        <div className="mb-1 flex items-center gap-1.5 font-medium text-muted-foreground">
          <Wrench className="size-3" />
          Tool result
        </div>
        <pre className="overflow-x-auto whitespace-pre-wrap font-mono text-[11px] leading-snug text-foreground/80">
          {content}
        </pre>
      </div>
    )
  }

  return (
    <div className="prose prose-sm max-w-none dark:prose-invert">
      {prose && (
        <ReactMarkdown
          components={{
            p: ({ children }) => <p className="my-1.5 leading-relaxed">{children}</p>,
            code: ({ children, className }) => {
              const isBlock = className?.startsWith("language-")
              if (isBlock) {
                return (
                  <pre className="my-2 overflow-x-auto rounded-md bg-muted p-3 text-xs">
                    <code className="font-mono">{children}</code>
                  </pre>
                )
              }
              return (
                <code className="rounded bg-muted px-1 py-0.5 font-mono text-[0.85em]">
                  {children}
                </code>
              )
            },
            ul: ({ children }) => <ul className="my-1.5 list-disc pl-5">{children}</ul>,
            ol: ({ children }) => <ol className="my-1.5 list-decimal pl-5">{children}</ol>,
            li: ({ children }) => <li className="my-0.5">{children}</li>,
            a: ({ children, href }) => (
              <a href={href} className="text-primary underline underline-offset-2" target="_blank" rel="noreferrer">
                {children}
              </a>
            ),
          }}
        >
          {prose}
        </ReactMarkdown>
      )}
      {actionCount > 0 && (
        <span
          className="mt-1 inline-flex items-center gap-1.5 rounded-full border border-primary/40 bg-primary/10 px-2.5 py-0.5 text-xs font-medium text-primary dark:border-sky-400/60 dark:bg-sky-400/15 dark:text-sky-200"
          title="Action block executed by the command bus"
        >
          <Sparkles className="size-3" />
          Ran {actionCount} action{actionCount > 1 ? "s" : ""}
        </span>
      )}
      {toolCalls && toolCalls.length > 0 && (
        <span
          className="mt-1 ml-1 inline-flex items-center gap-1.5 rounded-full border border-amber-400/40 bg-amber-400/10 px-2.5 py-0.5 text-xs font-medium text-amber-700 dark:border-amber-300/60 dark:bg-amber-300/10 dark:text-amber-200"
          title="Tool call dispatched"
        >
          <Wrench className="size-3" />
          Called {toolCalls.map((c) => c.name).join(", ")}
        </span>
      )}
    </div>
  )
}
