import { useState, useMemo } from "react";
import { cn } from "@/lib/utils";
import {
  Terminal,
  FileText,
  FileEdit,
  Search,
  FolderSearch,
  Globe,
  Link,
  ListTodo,
  Bot,
  ChevronDown,
  ChevronRight,
  Loader2,
  Check,
  X,
  Clock,
  Copy,
  GitBranch,
  MessageCircle,
  Wrench,
  Settings,
  Send,
  Server,
  KeyRound,
  Timer,
  Zap,
  Code2,
  BookOpen,
  MonitorPlay,
  Moon,
  Play,
  Braces,
  ListChecks,
  CalendarClock,
  Trash2,
  List,
  Eye,
  StopCircle,
  RefreshCw,
  Languages,
  Map,
  MapPin,
  Users,
  UserMinus,
  Webhook,
  FlaskConical,
  GitFork,
} from "lucide-react";
import type { ToolCallInfo } from "@/hooks/useChat";

/**
 * Tool icon map — EXACT parity with original claw-code tool names.
 * Supports both original names and legacy aliases.
 */
const TOOL_ICONS: Record<string, React.ElementType> = {
  // ── Core 19 tools (original names) ──
  bash: Terminal,
  PowerShell: MonitorPlay,
  read_file: FileText,
  write_file: FileEdit,
  edit_file: FileEdit,
  glob_search: FolderSearch,
  grep_search: Search,
  NotebookEdit: BookOpen,
  WebSearch: Globe,
  WebFetch: Link,
  TodoWrite: ListTodo,
  Agent: Bot,
  SendUserMessage: MessageCircle,
  Brief: MessageCircle,
  TestingPermission: FlaskConical,
  ToolSearch: Wrench,
  Config: Settings,
  Skill: Zap,
  Sleep: Moon,
  REPL: Play,
  StructuredOutput: Braces,
  // ── Extended tools (full parity) ──
  TaskCreate: ListChecks,
  TaskGet: Eye,
  TaskList: List,
  TaskOutput: Terminal,
  TaskStop: StopCircle,
  TaskUpdate: RefreshCw,
  CronCreate: CalendarClock,
  CronDelete: Trash2,
  CronList: CalendarClock,
  LSP: Languages,
  EnterPlanMode: Map,
  ExitPlanMode: MapPin,
  EnterWorktree: GitFork,
  ExitWorktree: GitBranch,
  TeamCreate: Users,
  TeamDelete: UserMinus,
  RemoteTrigger: Webhook,
  SyntheticOutput: FlaskConical,
  // ── MCP ──
  mcp_tool: Server,
  list_mcp_resources: Server,
  read_mcp_resource: Server,
  mcp_auth: KeyRound,
  // ── Legacy aliases ──
  powershell: MonitorPlay,
  grep: Search,
  glob: FolderSearch,
  web_search: Globe,
  web_fetch: Link,
  todo_read: ListTodo,
  todo_write: ListTodo,
  sub_agent: Bot,
  send_message: Send,
  ask_user: MessageCircle,
  tool_search: Wrench,
  config_read: Settings,
  config_write: Settings,
  notebook_edit: BookOpen,
  skill: Zap,
};

/**
 * Tool color map — EXACT parity with original claw-code tool names.
 */
const TOOL_COLORS: Record<string, string> = {
  // ── Core 19 tools ──
  bash: "text-green-400",
  PowerShell: "text-blue-500",
  read_file: "text-blue-400",
  write_file: "text-yellow-400",
  edit_file: "text-orange-400",
  glob_search: "text-cyan-400",
  grep_search: "text-purple-400",
  NotebookEdit: "text-emerald-400",
  WebSearch: "text-pink-400",
  WebFetch: "text-indigo-400",
  TodoWrite: "text-teal-400",
  Agent: "text-amber-400",
  SendUserMessage: "text-sky-400",
  Brief: "text-sky-400",
  TestingPermission: "text-gray-400",
  ToolSearch: "text-violet-400",
  Config: "text-slate-400",
  Skill: "text-yellow-300",
  Sleep: "text-indigo-300",
  REPL: "text-lime-400",
  StructuredOutput: "text-cyan-300",
  // ── Extended tools (full parity) ──
  TaskCreate: "text-emerald-500",
  TaskGet: "text-emerald-400",
  TaskList: "text-emerald-300",
  TaskOutput: "text-emerald-400",
  TaskStop: "text-red-400",
  TaskUpdate: "text-emerald-300",
  CronCreate: "text-amber-500",
  CronDelete: "text-red-400",
  CronList: "text-amber-400",
  LSP: "text-blue-500",
  EnterPlanMode: "text-violet-500",
  ExitPlanMode: "text-violet-400",
  EnterWorktree: "text-orange-500",
  ExitWorktree: "text-orange-400",
  TeamCreate: "text-cyan-500",
  TeamDelete: "text-red-400",
  RemoteTrigger: "text-pink-500",
  SyntheticOutput: "text-lime-500",
  // ── MCP ──
  mcp_tool: "text-rose-400",
  list_mcp_resources: "text-rose-300",
  read_mcp_resource: "text-rose-300",
  mcp_auth: "text-rose-500",
  // ── Legacy aliases ──
  powershell: "text-blue-500",
  grep: "text-purple-400",
  glob: "text-cyan-400",
  web_search: "text-pink-400",
  web_fetch: "text-indigo-400",
  todo_read: "text-teal-400",
  todo_write: "text-teal-400",
  sub_agent: "text-amber-400",
  send_message: "text-sky-400",
  ask_user: "text-sky-400",
  tool_search: "text-violet-400",
  config_read: "text-slate-400",
  config_write: "text-slate-400",
  notebook_edit: "text-emerald-400",
  skill: "text-yellow-300",
};

/** Simple diff line renderer for edit_file results */
function DiffView({ content }: { content: string }) {
  const lines = content.split("\n");
  return (
    <div className="text-xs font-mono">
      {lines.map((line, i) => {
        let cls = "text-foreground/70";
        if (line.startsWith("+ ") || line.startsWith("+\t") || line === "+") {
          cls = "text-green-400 bg-green-400/10";
        } else if (
          line.startsWith("- ") ||
          line.startsWith("-\t") ||
          line === "-"
        ) {
          cls = "text-red-400 bg-red-400/10";
        } else if (line.startsWith("@@ ")) {
          cls = "text-cyan-400/60";
        } else if (line.startsWith("--- ") || line.startsWith("+++ ")) {
          cls = "text-muted-foreground";
        }
        return (
          <div key={i} className={cn("px-2 py-px whitespace-pre-wrap", cls)}>
            {line}
          </div>
        );
      })}
    </div>
  );
}

/** Detect if output looks like a diff */
function isDiffLike(content: string): boolean {
  if (!content) return false;
  const lines = content.split("\n").slice(0, 20);
  let diffIndicators = 0;
  for (const l of lines) {
    if (
      l.startsWith("+ ") ||
      l.startsWith("- ") ||
      l.startsWith("@@ ") ||
      l.startsWith("--- ") ||
      l.startsWith("+++ ")
    )
      diffIndicators++;
  }
  return diffIndicators >= 2;
}

export function ToolCallCard({ tool }: { tool: ToolCallInfo }) {
  const [expanded, setExpanded] = useState(false);
  const [copied, setCopied] = useState(false);

  const Icon = TOOL_ICONS[tool.name] || Terminal;
  const colorClass = TOOL_COLORS[tool.name] || "text-muted-foreground";

  let parsedArgs: Record<string, unknown> = {};
  try {
    parsedArgs = JSON.parse(tool.arguments || "{}");
  } catch {
    parsedArgs = { raw: tool.arguments };
  }

  const showDiff = useMemo(
    () =>
      (tool.name === "edit_file" || tool.name === "bash") &&
      tool.result &&
      isDiffLike(tool.result),
    [tool.name, tool.result]
  );

  // Format the tool call summary — supports both original and legacy names
  const getSummary = () => {
    switch (tool.name) {
      case "bash":
      case "PowerShell":
      case "powershell":
        return String(parsedArgs.command || "").substring(0, 80);
      case "read_file":
      case "write_file":
      case "edit_file":
      case "NotebookEdit":
      case "notebook_edit":
        return String(parsedArgs.path || parsedArgs.notebook_path || "");
      case "grep_search":
      case "grep":
        return `"${parsedArgs.pattern}" in ${parsedArgs.path || "."}`;
      case "glob_search":
      case "glob":
        return String(parsedArgs.pattern || "");
      case "WebSearch":
      case "web_search":
        return String(parsedArgs.query || "");
      case "WebFetch":
      case "web_fetch":
        return String(parsedArgs.url || "").substring(0, 60);
      case "Agent":
      case "sub_agent":
        return String(parsedArgs.description || parsedArgs.task || "").substring(0, 60);
      case "SendUserMessage":
      case "Brief":
      case "ask_user":
        return String(parsedArgs.message || parsedArgs.question || "").substring(0, 60);
      case "TestingPermission":
        return `check: ${parsedArgs.tool || "unknown"}`;
      case "ToolSearch":
      case "tool_search":
        return String(parsedArgs.query || "");
      case "Config":
        return parsedArgs.value !== undefined
          ? `${parsedArgs.setting} = ${parsedArgs.value}`
          : String(parsedArgs.setting || "all");
      case "config_read":
        return String(parsedArgs.key || "all");
      case "config_write":
        return `${parsedArgs.key} = ${parsedArgs.value}`;
      case "Skill":
      case "skill":
        return String(parsedArgs.skill || parsedArgs.name || "");
      case "Sleep":
        return `${parsedArgs.duration_ms || 0}ms`;
      case "REPL":
        return `${parsedArgs.language || "python"}: ${String(parsedArgs.code || "").substring(0, 50)}`;
      case "TodoWrite":
        return "Update task list";
      // Extended tools
      case "TaskCreate":
        return String(parsedArgs.description || "").substring(0, 60);
      case "TaskGet":
      case "TaskOutput":
      case "TaskStop":
      case "TaskUpdate":
        return String(parsedArgs.id || "");
      case "TaskList":
        return "List background tasks";
      case "CronCreate":
        return `${parsedArgs.schedule} — ${String(parsedArgs.command || "").substring(0, 40)}`;
      case "CronDelete":
        return String(parsedArgs.id || "");
      case "CronList":
        return "List cron jobs";
      case "LSP":
        return `${parsedArgs.action || ""} ${parsedArgs.path || ""}`;
      case "EnterPlanMode":
        return "Enter plan mode";
      case "ExitPlanMode":
        return "Exit plan mode";
      case "EnterWorktree":
        return String(parsedArgs.branch || "");
      case "ExitWorktree":
        return "Exit worktree";
      case "TeamCreate":
        return String(parsedArgs.name || "");
      case "TeamDelete":
        return String(parsedArgs.id || "");
      case "RemoteTrigger":
        return `${parsedArgs.method || "POST"} ${String(parsedArgs.url || "").substring(0, 50)}`;
      case "SyntheticOutput":
        return String(parsedArgs.format || "json");
      default:
        return tool.name;
    }
  };

  const copyResult = () => {
    if (tool.result) {
      navigator.clipboard.writeText(tool.result);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  };

  return (
    <div className="tool-card rounded-lg border border-border bg-secondary/30 my-2 overflow-hidden">
      {/* Header */}
      <button
        onClick={() => setExpanded(!expanded)}
        className="w-full flex items-center gap-2 px-3 py-2 text-left hover:bg-accent/30 transition-colors"
      >
        <Icon className={cn("size-4 shrink-0", colorClass)} />
        <span className="font-mono text-xs font-medium text-foreground/80">
          {tool.name}
        </span>
        <span className="text-xs text-muted-foreground truncate flex-1 font-mono">
          {getSummary()}
        </span>

        {/* Status indicator */}
        <div className="flex items-center gap-1.5 shrink-0">
          {tool.isExecuting && (
            <Loader2 className="size-3.5 animate-spin text-primary" />
          )}
          {!tool.isExecuting && tool.result !== undefined && !tool.isError && (
            <Check className="size-3.5 text-green-400" />
          )}
          {!tool.isExecuting && tool.isError && (
            <X className="size-3.5 text-destructive" />
          )}
          {tool.durationMs !== undefined && tool.durationMs > 0 && (
            <span className="text-[10px] text-muted-foreground flex items-center gap-0.5">
              <Clock className="size-2.5" />
              {tool.durationMs < 1000
                ? `${tool.durationMs}ms`
                : `${(tool.durationMs / 1000).toFixed(1)}s`}
            </span>
          )}
          {showDiff && (
            <GitBranch className="size-3 text-orange-400" />
          )}
          {expanded ? (
            <ChevronDown className="size-3.5 text-muted-foreground" />
          ) : (
            <ChevronRight className="size-3.5 text-muted-foreground" />
          )}
        </div>
      </button>

      {/* Expanded content */}
      {expanded && (
        <div className="border-t border-border">
          {/* Arguments */}
          <div className="px-3 py-2">
            <div className="text-[10px] uppercase tracking-wider text-muted-foreground mb-1">
              Input
            </div>
            <pre className="text-xs font-mono text-foreground/80 whitespace-pre-wrap break-all bg-background/50 rounded p-2 max-h-48 overflow-auto">
              {tool.name === "bash" || tool.name === "PowerShell" || tool.name === "powershell"
                ? String(parsedArgs.command || "")
                : JSON.stringify(parsedArgs, null, 2)}
            </pre>
          </div>

          {/* Result */}
          {tool.result !== undefined && (
            <div className="px-3 py-2 border-t border-border">
              <div className="flex items-center justify-between mb-1">
                <div className="text-[10px] uppercase tracking-wider text-muted-foreground">
                  Output
                  {tool.isError && (
                    <span className="text-destructive ml-1">(error)</span>
                  )}
                  {showDiff && (
                    <span className="text-orange-400 ml-1">(diff)</span>
                  )}
                </div>
                <button
                  onClick={(e) => {
                    e.stopPropagation();
                    copyResult();
                  }}
                  className="text-muted-foreground hover:text-foreground transition-colors"
                >
                  {copied ? (
                    <Check className="size-3" />
                  ) : (
                    <Copy className="size-3" />
                  )}
                </button>
              </div>
              {showDiff ? (
                <div className="bg-background/50 rounded max-h-64 overflow-auto">
                  <DiffView content={tool.result} />
                </div>
              ) : (
                <pre
                  className={cn(
                    "text-xs font-mono whitespace-pre-wrap break-all rounded p-2 max-h-64 overflow-auto",
                    tool.isError
                      ? "bg-destructive/10 text-destructive"
                      : "bg-background/50 text-foreground/80"
                  )}
                >
                  {tool.result}
                </pre>
              )}
            </div>
          )}
        </div>
      )}
    </div>
  );
}
