import { useState } from "react";
import { ChatMarkdownMessage } from "./ChatMarkdownMessage";
import { ChatMessageIdentityBar } from "./ChatMessageIdentityBar";
import { ChatStreamingCursor } from "./ChatStreamingCursor";
import { ChatMessageActions } from "./ChatMessageActions";
import { ChatSpecCard } from "./ChatSpecCard";
import { ChatHandoffIndicator } from "./ChatHandoffIndicator";
import { ChatTaskCreatedBadge } from "./ChatTaskCreatedBadge";
import { ChatStatusUpdateBadge } from "./ChatStatusUpdateBadge";
import { ChatFilePreview } from "./ChatFilePreview";
import { ChatVoiceBadge } from "./ChatVoiceBadge";
import { Button } from "@/components/ui/button";
import { cn } from "../lib/utils";
import type { AgentRole, ChatFile } from "@paperclipai/shared";
interface ChatMessageProps {
id?: string;
role: "user" | "assistant" | "system";
content: string;
messageType?: string | null;
conversationId?: string;
agentName?: string | null;
agentIcon?: string | null;
agentRole?: AgentRole | null;
timestamp?: string;
isStreaming?: boolean;
isAnyStreaming?: boolean;
onEdit?: (messageId: string, newContent: string) => void;
onRetry?: (messageId: string) => void;
onHandoff?: (spec: { what: string; why: string; constraints: string; success: string }) => void;
onBookmark?: (messageId: string) => void;
isBookmarked?: boolean;
files?: ChatFile[];
}
export function ChatMessage({
id,
role,
content,
messageType,
conversationId,
agentName,
agentIcon,
agentRole,
timestamp,
isStreaming,
isAnyStreaming,
onEdit,
onRetry,
onHandoff,
onBookmark,
isBookmarked,
files,
}: ChatMessageProps) {
const [isEditing, setIsEditing] = useState(false);
const [editValue, setEditValue] = useState(content);
// Dispatch to specialized system message components (Phase 23)
if (role === "system" || messageType) {
if (messageType === "spec_card") {
return (