import { cn } from "@/lib/utils";
import { ChatAttachmentList } from "@/components/chat/chat-attachment-list";
import { getMessageAttachments, type Message } from "@/lib/api";
import { MarkdownContent } from "@/components/markdown/markdown-content";
import { Globe2, Link2, Wrench } from "lucide-preact";

type Props = {
  messages: Message[];
  isLoading: boolean;
  isSending: boolean;
};

type ToolLogMetadata = {
  kind: "tool_call";
  toolName?: string;
  status?: "completed" | "failed";
  summary?: string;
};

function asToolLogMetadata(value: unknown): ToolLogMetadata | null {
  if (!value || typeof value !== "object" || Array.isArray(value)) return null;
  const record = value as Record<string, unknown>;
  if (record.kind !== "tool_call") return null;
  return record as ToolLogMetadata;
}

function getToolSummary(message: Message, metadata: ToolLogMetadata) {
  if (typeof metadata.summary === "string" && metadata.summary.trim()) return metadata.summary.trim();
  const toolName = metadata.toolName?.trim() || message.name?.trim() || "unknown_tool";
  return `Ran tool '${toolName}'.`;
}

function getToolIconName(toolName: string | null | undefined) {
  const lowered = toolName?.toLowerCase() ?? "";
  if (lowered.includes("search")) return "search";
  if (lowered.includes("url") || lowered.includes("fetch") || lowered.includes("http")) return "fetch";
  return "generic";
}

export function ChatMessagesPanel({ messages, isLoading, isSending }: Props) {
  const hasPendingAssistant = messages.some((message) => message.id.startsWith("temp-assistant-") && message.content.trim().length === 0);

  return (
    <>
      {isLoading && messages.length === 0 ? <p className="text-sm text-muted-foreground">Loading messages...</p> : null}
      <div className="mx-auto max-w-4xl space-y-6">
        {messages.map((message) => {
          const toolLogMetadata = asToolLogMetadata(message.metadata);
          if (message.role === "tool" && toolLogMetadata) {
            const iconKind = getToolIconName(toolLogMetadata.toolName ?? message.name);
            const Icon = iconKind === "search" ? Globe2 : iconKind === "fetch" ? Link2 : Wrench;
            const isFailed = toolLogMetadata.status === "failed";
            const toolSummary = getToolSummary(message, toolLogMetadata);
            return (
              <div key={message.id} className="flex justify-start">
                <div
                  className={cn(
                    "inline-flex max-w-[85%] min-w-0 items-center gap-3 overflow-hidden rounded-lg border px-3.5 py-2 text-sm leading-5 shadow-[inset_0_1px_0_hsl(180_100%_88%_/_0.06)]",
                    isFailed
                      ? "border-rose-500/40 bg-rose-950/18 text-rose-200"
                      : "border-cyan-400/34 bg-cyan-950/18 text-cyan-100"
                  )}
                  title={toolSummary}
                >
                  <Icon className="h-4 w-4 shrink-0 text-cyan-300" />
                  <span className="min-w-0 flex-1 truncate">{toolSummary}</span>
                </div>
              </div>
            );
          }

          const isUser = message.role === "user";
          const isPendingAssistant = message.id.startsWith("temp-assistant-") && isSending && message.content.trim().length === 0;
          const attachments = getMessageAttachments(message.metadata);
          return (
            <div key={message.id} className={cn("flex", isUser ? "justify-end" : "justify-start")}>
              <div
                className={cn(
                  "max-w-[85%] space-y-3",
                  isUser
                    ? "rounded-xl border border-violet-300/24 bg-[linear-gradient(135deg,hsl(258_86%_48%_/_0.86),hsl(278_72%_29%_/_0.86))] px-4 py-3 text-sm leading-6 text-fuchsia-50 shadow-sm"
                    : "text-base leading-7 text-violet-50"
                )}
              >
                {attachments.length ? <ChatAttachmentList attachments={attachments} tone={isUser ? "user" : "assistant"} /> : null}
                {isPendingAssistant ? (
                  <span className="inline-flex items-center gap-1" aria-label="Assistant is typing" role="status">
                    <span className="inline-block h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:0ms]" />
                    <span className="inline-block h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:140ms]" />
                    <span className="inline-block h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:280ms]" />
                  </span>
                ) : message.content.trim() ? (
                  <MarkdownContent
                    markdown={message.content}
                    className={cn("[&_a]:text-inherit [&_a]:underline", isUser ? "leading-[1.78] text-fuchsia-50" : "leading-[1.82] text-violet-50")}
                  />
                ) : null}
              </div>
            </div>
          );
        })}
        {isSending && !hasPendingAssistant ? (
          <div className="flex justify-start">
            <div className="max-w-[85%] text-base leading-7 text-violet-50">
              <span className="inline-flex items-center gap-1" aria-label="Assistant is typing" role="status">
                <span className="inline-block h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:0ms]" />
                <span className="inline-block h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:140ms]" />
                <span className="inline-block h-1.5 w-1.5 animate-bounce rounded-full bg-muted-foreground [animation-delay:280ms]" />
              </span>
            </div>
          </div>
        ) : null}
      </div>
    </>
  );
}
