import { memo } from "react";
import { User, Sparkles, AlertTriangle } from "lucide-react";
import { cn } from "@/lib/utils";
import {
  Reasoning,
  ReasoningTrigger,
  ReasoningContent,
} from "@/components/ai-elements/reasoning";
import { MarkdownRenderer } from "@/components/MarkdownRenderer";
import { MentionRenderer } from "@/lib/ir/mention-renderer";
import { getProviderIcon } from "./provider-icon";
import { isVisibleToolCall } from "./tool-utils";
import { ToolCallList } from "./tool-call-list";
import { useCodePreview } from "./code-preview-context";
import type { Message } from "./types";

interface MessageBubbleProps {
  msg: Message;
  modelProvider?: string;
}

export const MessageBubble = memo(function MessageBubble({
  msg,
  modelProvider,
}: MessageBubbleProps) {
  const isUser = msg.role === "user";
  const { openCodePreview } = useCodePreview();
  const hasToolCalls =
    !isUser &&
    msg.tool_calls &&
    msg.tool_calls.some((tc) => isVisibleToolCall(tc.name));
  const isError = !isUser && /^Error:|I encountered an error/i.test(msg.content);

  return (
    <div
      className={cn("flex gap-3", isUser ? "justify-end" : "justify-start")}
      role="article"
      aria-label={isUser ? "Your message" : "Assistant message"}
    >
      {!isUser && <AIAvatar providerName={modelProvider} />}

      <div className="min-w-0 max-w-[85%] space-y-2">
        {/* Reasoning content */}
        {msg.reasoning_content && (
          <Reasoning defaultOpen={false}>
            <ReasoningTrigger />
            <ReasoningContent>{msg.reasoning_content}</ReasoningContent>
          </Reasoning>
        )}

        {/* Tool calls */}
        {hasToolCalls && <ToolCallList toolCalls={msg.tool_calls!} />}

        {/* Message content */}
        <div
          className={cn(
            "relative overflow-hidden text-sm leading-relaxed shadow-sm",
            isUser
              ? "rounded-2xl rounded-tr-sm bg-primary text-primary-foreground px-4 py-2.5"
              : isError
                ? "rounded-2xl rounded-tl-sm bg-destructive/[0.06] text-foreground border border-destructive/20 px-4 py-2.5"
                : "rounded-2xl rounded-tl-sm bg-muted/70 text-foreground border border-border/40 px-4 py-2.5",
          )}
        >
          {isUser ? (
            <div className="whitespace-pre-wrap break-words">
              <MentionRenderer content={msg.content} />
            </div>
          ) : isError ? (
            <div className="flex items-start gap-2.5">
              <AlertTriangle className="mt-0.5 size-4 shrink-0 text-destructive/60" />
              <div className="min-w-0 flex-1">
                <p className="text-[13px] font-medium text-destructive/80">Something went wrong</p>
                <div className="mt-1 text-destructive/60">
                  <MarkdownRenderer
                    content={msg.content.replace(/^(Error:\s*|I encountered an error while processing your request:\s*)/i, "")}
                    onOpenCodePanel={(payload) =>
                      openCodePreview({ ...payload, id: crypto.randomUUID() })
                    }
                  />
                </div>
              </div>
            </div>
          ) : (
            <MarkdownRenderer
              content={msg.content}
              onOpenCodePanel={(payload) =>
                openCodePreview({ ...payload, id: crypto.randomUUID() })
              }
            />
          )}
        </div>
      </div>

      {isUser && <UserAvatar />}
    </div>
  );
});

function AIAvatar({ providerName }: { providerName?: string }) {
  const Icon = providerName ? getProviderIcon(providerName) : null;

  if (Icon) {
    return (
      <span
        className="mt-0.5 grid size-8 shrink-0 place-items-center rounded-full bg-gradient-to-br from-primary/15 to-primary/5 ring-1 ring-primary/10 shadow-sm"
        aria-hidden="true"
      >
        <Icon className="size-4 text-primary/70" />
      </span>
    );
  }

  return (
    <span
      className="mt-0.5 grid size-8 shrink-0 place-items-center rounded-full bg-gradient-to-br from-primary/20 to-primary/5 ring-1 ring-primary/10 shadow-sm"
      aria-hidden="true"
    >
      <Sparkles className="size-3.5 text-primary/60" />
    </span>
  );
}

function UserAvatar() {
  return (
    <span
      className="mt-0.5 grid size-8 shrink-0 place-items-center rounded-full bg-gradient-to-br from-muted to-muted/50 ring-1 ring-border/40 shadow-sm"
      aria-hidden="true"
    >
      <User className="size-3.5 text-muted-foreground/70" />
    </span>
  );
}
