import { memo, useState } from "react";
import { motion, AnimatePresence } from "motion/react";

import {
  ChevronDown,
  Bot,
  CheckCircle2,
  XCircle,
  Loader2,
} from "lucide-react";
import {
  Tool,
  ToolHeader,
  ToolContent,
  ToolInput,
  ToolOutput,
} from "@/components/ai-elements/tool";
import type { ToolCallRecord } from "./types";

/**
 * Collapsible tool call list — uses ai-elements Tool components
 * for regular tools and SubAgentCard for subagent calls.
 */
export const ToolCallList = memo(function ToolCallList({
  toolCalls,
  isStreaming = false,
}: {
  toolCalls: ToolCallRecord[];
  isStreaming?: boolean;
}) {
  if (toolCalls.length === 0) return null;

  return (
    <div className="space-y-2">
      {toolCalls.map((tc) => {
        const isSubAgent = tc.name === "call_sub_agent";
        if (isSubAgent) {
          return (
            <SubAgentCard key={tc.id} toolCall={tc} isStreaming={isStreaming} />
          );
        }
        return (
          <RegularToolCard key={tc.id} toolCall={tc} isStreaming={isStreaming} />
        );
      })}
    </div>
  );
});

/** SubAgent — compact card with role, task, output preview. */
const SubAgentCard = memo(function SubAgentCard({
  toolCall,
  isStreaming,
}: {
  toolCall: ToolCallRecord;
  isStreaming: boolean;
}) {
  const [expanded, setExpanded] = useState(false);
  const role = (toolCall.arguments as Record<string, unknown>)?.role as
    | string
    | undefined;
  const task = (toolCall.arguments as Record<string, unknown>)?.task as
    | string
    | undefined;
  const hasOutput =
    typeof toolCall.output === "object" && toolCall.output !== null;
  const outputText = hasOutput
    ? JSON.stringify(toolCall.output, null, 2)
    : typeof toolCall.output === "string"
      ? toolCall.output
      : "";
  const lineCount = outputText ? outputText.split("\n").length : 0;
  const isPending = !toolCall.output && !toolCall.error && isStreaming;
  const isOk = !!toolCall.output && !toolCall.error;
  const isError = !!toolCall.error;

  return (
    <motion.div
      initial={{ opacity: 0, y: 4 }}
      animate={{ opacity: 1, y: 0 }}
      transition={{ duration: 0.2 }}
      className="overflow-hidden rounded-xl border border-border/50 bg-card/80 shadow-sm"
    >
      {/* Header */}
      <button
        className="flex w-full items-center gap-2.5 px-3 py-2.5 text-left transition-colors hover:bg-muted/20"
        onClick={() => setExpanded(!expanded)}
        type="button"
      >
        {/* Status icon */}
        <span className="shrink-0">
          {isPending ? (
            <Loader2 className="size-3.5 animate-spin text-info" />
          ) : isOk ? (
            <CheckCircle2 className="size-3.5 text-emerald-500" />
          ) : isError ? (
            <XCircle className="size-3.5 text-destructive" />
          ) : (
            <Bot className="size-3.5 text-muted-foreground/40" />
          )}
        </span>

        <div className="min-w-0 flex-1">
          <div className="flex items-center gap-2">
            <span className="text-[13px] font-medium text-foreground">
              {role || "Sub-agent"}
            </span>
            <span className="rounded-md bg-muted/70 px-1.5 py-[2px] text-[10px] font-medium text-muted-foreground/70">
              sub-agent
            </span>
          </div>
          {task && (
            <p className="mt-0.5 line-clamp-1 text-[11px] text-muted-foreground/60">
              {task}
            </p>
          )}
        </div>

        {/* Expand chevron */}
        <motion.span
          animate={{ rotate: expanded ? 180 : 0 }}
          transition={{ duration: 0.2 }}
          className="shrink-0 text-muted-foreground/40"
        >
          <ChevronDown className="size-3.5" />
        </motion.span>
      </button>

      {/* Output preview (collapsed) */}
      <AnimatePresence>
        {!expanded && outputText && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: "auto", opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            transition={{ duration: 0.2 }}
            className="overflow-hidden border-t border-border/30"
          >
            <div className="px-3 pb-3 pt-2.5">
              <pre className="max-h-24 overflow-hidden rounded-lg border border-border/30 bg-muted/25 px-3 py-2 text-[11px] leading-relaxed text-muted-foreground/70">
                <code>{outputText.slice(0, 500)}</code>
                {outputText.length > 500 && (
                  <span className="text-muted-foreground/30"> …</span>
                )}
              </pre>
              {lineCount > 0 && (
                <div className="mt-1.5 flex items-center gap-1 text-[10px] text-muted-foreground/35">
                  <span>{lineCount} lines</span>
                  <span>·</span>
                  <span>click to expand</span>
                </div>
              )}
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Expanded content */}
      <AnimatePresence>
        {expanded && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: "auto", opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            transition={{ duration: 0.25 }}
            className="overflow-hidden border-t border-border/30"
          >
            <div className="space-y-3 px-3 pb-3 pt-2.5">
              {task && (
                <div>
                  <div className="mb-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/50">
                    Task
                  </div>
                  <div className="rounded-lg bg-muted/25 px-3 py-2 text-[12px] text-foreground/80">
                    {task}
                  </div>
                </div>
              )}
              {outputText && (
                <div>
                  <div className="mb-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/50">
                    Output
                  </div>
                  <pre className="max-h-72 overflow-auto rounded-lg border border-border/30 bg-muted/25 px-3 py-2 text-[11px] leading-relaxed text-muted-foreground/80">
                    <code>{outputText}</code>
                  </pre>
                </div>
              )}
              {toolCall.error && (
                <div>
                  <div className="mb-1 text-[10px] font-semibold uppercase tracking-wider text-destructive/60">
                    Error
                  </div>
                  <div className="rounded-lg bg-destructive/[0.06] px-3 py-2 text-[12px] text-destructive/80">
                    {toolCall.error}
                  </div>
                </div>
              )}
            </div>
          </motion.div>
        )}
      </AnimatePresence>
    </motion.div>
  );
});

/** Regular tool — uses ai-elements Tool compound component. */
const RegularToolCard = memo(function RegularToolCard({
  toolCall,
}: {
  toolCall: ToolCallRecord;
  isStreaming: boolean;
}) {
  return (
    <Tool>
      <ToolHeader
        type="dynamic-tool"
        state={
          toolCall.error
            ? "output-error"
            : toolCall.output != null
              ? "output-available"
              : "input-streaming"
        }
        title={toolCall.name}
        toolName={toolCall.name}
      />
      <ToolContent>
        {toolCall.arguments && Object.keys(toolCall.arguments).length > 0 && (
          <ToolInput input={toolCall.arguments} />
        )}
        {(toolCall.output || toolCall.error) && (
          <ToolOutput
            output={toolCall.output ?? undefined}
            errorText={toolCall.error ?? undefined}
          />
        )}
      </ToolContent>
    </Tool>
  );
});
