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 (
        <ChatSpecCard
          content={content}
          messageId={id}
          conversationId={conversationId}
          onHandoff={onHandoff}
        />
      );
    }
    if (messageType === "handoff") {
      return <ChatHandoffIndicator content={content} />;
    }
    if (messageType === "task_created") {
      try {
        const data = JSON.parse(content) as { taskId?: string; taskTitle?: string; taskUrl?: string };
        return <ChatTaskCreatedBadge taskId={data.taskId} taskTitle={data.taskTitle} taskUrl={data.taskUrl} />;
      } catch {
        return <ChatTaskCreatedBadge />;
      }
    }
    if (messageType === "status_update") {
      try {
        const data = JSON.parse(content) as { agentName: string; taskId: string; taskTitle?: string; taskUrl?: string };
        return <ChatStatusUpdateBadge agentName={data.agentName} taskId={data.taskId} taskTitle={data.taskTitle} taskUrl={data.taskUrl} />;
      } catch {
        return null;
      }
    }
    if (messageType === "voice_input" || messageType === "voice_full") {
      const autoPlay = typeof window !== "undefined"
        ? localStorage.getItem("nexus:voice:autoplay") === "true"
        : false;
      return (
        <div className="max-w-full group relative">
          {agentName && (
            <ChatMessageIdentityBar
              agentName={agentName}
              agentIcon={agentIcon}
              agentRole={agentRole}
              timestamp={timestamp}
              isStreaming={isStreaming}
            />
          )}
          <ChatVoiceBadge
            content={content}
            messageType={messageType}
            autoPlayVoice={autoPlay}
          />
          {isStreaming && <ChatStreamingCursor />}
          <ChatMessageActions
            role="assistant"
            isStreaming={isAnyStreaming}
            onRetry={id && onRetry ? () => onRetry(id) : undefined}
            onBookmark={id && onBookmark ? () => onBookmark(id) : undefined}
            isBookmarked={isBookmarked}
          />
        </div>
      );
    }
    // Fall through to default system message rendering (plain markdown)
  }

  if (role === "user") {
    if (isEditing) {
      return (
        <div className="flex justify-end">
          <div className="max-w-[85%] w-full">
            <textarea
              value={editValue}
              onChange={(e) => setEditValue(e.target.value)}
              className="w-full rounded-md border border-input bg-transparent px-3 py-2 text-sm resize-none min-h-[40px] focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring"
              aria-label="Edit your message"
              rows={3}
            />
            <div className="flex justify-end gap-2 mt-1">
              <Button
                variant="ghost"
                size="sm"
                onClick={() => {
                  setIsEditing(false);
                  setEditValue(content);
                }}
              >
                Discard edit
              </Button>
              <Button
                variant="default"
                size="sm"
                disabled={!editValue.trim()}
                onClick={() => {
                  if (id && onEdit && editValue.trim()) {
                    onEdit(id, editValue.trim());
                    setIsEditing(false);
                  }
                }}
              >
                Save edit
              </Button>
            </div>
          </div>
        </div>
      );
    }

    return (
      <div className="flex justify-end">
        <div
          className={cn(
            "relative group max-w-[85%] rounded-lg bg-secondary px-3 py-2 text-secondary-foreground text-sm",
          )}
        >
          {content}
          {files && files.length > 0 && (
            <div className="mt-2 flex flex-col gap-2">
              {files.map((f) => (
                <ChatFilePreview
                  key={f.id}
                  file={f}
                  contentPath={`/api/files/${f.id}/content`}
                />
              ))}
            </div>
          )}
          <ChatMessageActions
            role="user"
            isStreaming={isAnyStreaming}
            onEdit={() => setIsEditing(true)}
            onBookmark={id && onBookmark ? () => onBookmark(id) : undefined}
            isBookmarked={isBookmarked}
          />
        </div>
      </div>
    );
  }

  // assistant or system
  return (
    <div className="max-w-full group relative">
      {agentName && (
        <ChatMessageIdentityBar
          agentName={agentName}
          agentIcon={agentIcon}
          agentRole={agentRole}
          timestamp={timestamp}
          isStreaming={isStreaming}
        />
      )}
      <ChatMarkdownMessage content={content} />
      {files && files.length > 0 && (
        <div className="mt-2 flex flex-col gap-2">
          {files.map((f) => (
            <ChatFilePreview
              key={f.id}
              file={f}
              contentPath={`/api/files/${f.id}/content`}
            />
          ))}
        </div>
      )}
      {isStreaming && <ChatStreamingCursor />}
      <ChatMessageActions
        role="assistant"
        isStreaming={isAnyStreaming}
        onRetry={id && onRetry ? () => onRetry(id) : undefined}
        onBookmark={id && onBookmark ? () => onBookmark(id) : undefined}
        isBookmarked={isBookmarked}
      />
    </div>
  );
}
