import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
  Search,
  Globe,
  Terminal,
  FileText,
  FilePlus,
  FolderOpen,
  FileEdit,
  HelpCircle,
  Code2,
  Wrench,
  ChevronDown,
  Loader2,
  CheckCircle2,
  XCircle,
} from 'lucide-react';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export interface ToolCallStep {
  id: string;
  toolName: string;
  input?: string;
  output?: string;
  status: 'running' | 'completed' | 'error';
  timestamp: Date;
}

interface ToolCallChainProps {
  steps: ToolCallStep[];
  isStreaming?: boolean;
  className?: string;
}

// ---------------------------------------------------------------------------
// Icon mapping — each tool type gets a distinctive icon
// ---------------------------------------------------------------------------

const TOOL_ICONS: Record<string, typeof Search> = {
  web_search: Search,
  web_fetch: Globe,
  bash: Terminal,
  read_file: FileText,
  write_file: FilePlus,
  ls: FolderOpen,
  str_replace: FileEdit,
  ask_clarification: HelpCircle,
  code_execute: Code2,
  // Default fallback
};

const TOOL_LABELS: Record<string, string> = {
  web_search: '搜索',
  web_fetch: '获取网页',
  bash: '执行命令',
  read_file: '读取文件',
  write_file: '写入文件',
  ls: '列出目录',
  str_replace: '编辑文件',
  ask_clarification: '澄清问题',
  code_execute: '执行代码',
};

function getToolIcon(toolName: string): typeof Search {
  const lower = toolName.toLowerCase();
  for (const [key, icon] of Object.entries(TOOL_ICONS)) {
    if (lower.includes(key)) return icon;
  }
  return Wrench;
}

function getToolLabel(toolName: string): string {
  const lower = toolName.toLowerCase();
  for (const [key, label] of Object.entries(TOOL_LABELS)) {
    if (lower.includes(key)) return label;
  }
  return toolName;
}

// ---------------------------------------------------------------------------
// Truncate helper
// ---------------------------------------------------------------------------

function truncate(str: string, maxLen: number): string {
  if (!str) return '';
  const oneLine = str.replace(/\n/g, ' ').trim();
  return oneLine.length > maxLen ? oneLine.slice(0, maxLen) + '...' : oneLine;
}

// ---------------------------------------------------------------------------
// ToolCallChain — main component
// ---------------------------------------------------------------------------

/**
 * Collapsible tool-call step chain.
 *
 * Inspired by DeerFlow's message-group.tsx convertToSteps():
 * - Each tool call shows a type-specific icon + label
 * - The latest 2 steps are expanded by default
 * - Earlier steps collapse into "查看其他 N 个步骤"
 * - Running steps show a spinner; completed show a checkmark
 */

const DEFAULT_EXPANDED_COUNT = 2;

export function ToolCallChain({ steps, isStreaming = false, className = '' }: ToolCallChainProps) {
  const [showAll, setShowAll] = useState(false);

  if (steps.length === 0) return null;

  const visibleSteps = showAll
    ? steps
    : steps.slice(-DEFAULT_EXPANDED_COUNT);

  const hiddenCount = steps.length - visibleSteps.length;

  // The last step is "active" during streaming
  const activeStepIdx = isStreaming ? steps.length - 1 : -1;

  return (
    <div className={`my-1.5 ${className}`}>
      {/* Collapsed indicator */}
      {hiddenCount > 0 && !showAll && (
        <button
          onClick={() => setShowAll(true)}
          className="flex items-center gap-1.5 text-xs text-gray-400 dark:text-gray-500 hover:text-orange-500 dark:hover:text-orange-400 transition-colors mb-1.5 ml-0.5 group"
        >
          <ChevronDown className="w-3 h-3 group-hover:text-orange-500 dark:group-hover:text-orange-400 transition-transform" />
          <span>查看其他 {hiddenCount} 个步骤</span>
        </button>
      )}

      {/* Steps list */}
      <div className="space-y-0.5">
        {visibleSteps.map((step, idx) => {
          const globalIdx = showAll ? idx : hiddenCount + idx;
          const isActive = globalIdx === activeStepIdx;
          const isLast = globalIdx === steps.length - 1;

          return (
            <ToolStepRow
              key={step.id}
              step={step}
              isActive={isActive}
              showConnector={!isLast}
            />
          );
        })}
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// ToolStepRow — a single step in the chain
// ---------------------------------------------------------------------------

interface ToolStepRowProps {
  step: ToolCallStep;
  isActive: boolean;
  showConnector: boolean;
}

function ToolStepRow({ step, isActive, showConnector }: ToolStepRowProps) {
  const [expanded, setExpanded] = useState(false);
  const Icon = getToolIcon(step.toolName);
  const label = getToolLabel(step.toolName);
  const isRunning = step.status === 'running';
  const isError = step.status === 'error';

  return (
    <div>
      <button
        onClick={() => setExpanded(!expanded)}
        className={`
          flex items-center gap-2 w-full text-left px-2 py-1 rounded-md transition-colors
          ${isActive
            ? 'bg-orange-50 dark:bg-orange-900/15'
            : 'hover:bg-gray-50 dark:hover:bg-gray-800/60'
          }
        `}
      >
        {/* Status indicator */}
        {isRunning ? (
          <Loader2 className="w-3.5 h-3.5 text-orange-500 animate-spin flex-shrink-0" />
        ) : isError ? (
          <XCircle className="w-3.5 h-3.5 text-red-400 flex-shrink-0" />
        ) : (
          <CheckCircle2 className="w-3.5 h-3.5 text-green-400 flex-shrink-0" />
        )}

        {/* Tool icon */}
        <Icon className={`w-3.5 h-3.5 flex-shrink-0 ${isActive ? 'text-orange-500' : 'text-gray-400 dark:text-gray-500'}`} />

        {/* Tool label */}
        <span className={`text-xs font-medium ${isActive ? 'text-orange-600 dark:text-orange-400' : 'text-gray-600 dark:text-gray-400'}`}>
          {label}
        </span>

        {/* Input preview */}
        {step.input && !expanded && (
          <span className="text-[11px] text-gray-400 dark:text-gray-500 truncate flex-1">
            {truncate(step.input, 60)}
          </span>
        )}

        {/* Expand chevron */}
        {(step.input || step.output) && (
          <motion.span
            animate={{ rotate: expanded ? 180 : 0 }}
            transition={{ duration: 0.15 }}
            className="ml-auto flex-shrink-0"
          >
            <ChevronDown className="w-3 h-3 text-gray-400" />
          </motion.span>
        )}
      </button>

      {/* Expanded details */}
      <AnimatePresence>
        {expanded && (step.input || step.output) && (
          <motion.div
            initial={{ height: 0, opacity: 0 }}
            animate={{ height: 'auto', opacity: 1 }}
            exit={{ height: 0, opacity: 0 }}
            transition={{ duration: 0.15 }}
            className="overflow-hidden"
          >
            <div className="ml-9 mr-2 mb-1 space-y-1">
              {step.input && (
                <div className="text-[11px] text-gray-500 dark:text-gray-400 bg-gray-50 dark:bg-gray-800/80 rounded px-2 py-1 font-mono overflow-x-auto">
                  {truncate(step.input, 500)}
                </div>
              )}
              {step.output && (
                <div className={`text-[11px] font-mono rounded px-2 py-1 overflow-x-auto ${isError ? 'text-red-500 bg-red-50 dark:bg-red-900/10' : 'text-green-600 dark:text-green-400 bg-green-50 dark:bg-green-900/10'}`}>
                  {truncate(step.output, 500)}
                </div>
              )}
            </div>
          </motion.div>
        )}
      </AnimatePresence>

      {/* Vertical connector */}
      {showConnector && (
        <div className="ml-[18px] w-px h-1.5 bg-gray-200 dark:bg-gray-700" />
      )}
    </div>
  );
}
