<template>
  <div :class="['tool-call-card', `tool-call-card--${toolCall.status}`]">
    <div class="tool-call-card__header" @click="expanded = !expanded">
      <div class="tool-call-card__title">
        <component :is="icon" class="tool-call-card__icon" />
        <span class="tool-call-card__name">{{ toolCall.name }}</span>
        <span v-if="toolCall.duration" class="tool-call-card__duration">{{ toolCall.duration }}ms</span>
      </div>
      <div class="tool-call-card__status">
        <LoadingOutlined v-if="toolCall.status === 'running'" spin class="tool-call-card__spinner" />
        <CheckCircleOutlined v-else-if="toolCall.status === 'completed'" class="tool-call-card__check" />
        <CloseCircleOutlined v-else-if="toolCall.status === 'error'" class="tool-call-card__error-icon" />
        <RightOutlined :class="['tool-call-card__expand', { 'tool-call-card__expand--open': expanded }]" />
      </div>
    </div>
    <div v-if="toolCall.params && expanded" class="tool-call-card__params">
      <div class="tool-call-card__label">参数</div>
      <pre class="tool-call-card__pre">{{ toolCall.params }}</pre>
    </div>
    <div v-if="(toolCall.result || toolCall.error) && expanded" class="tool-call-card__result">
      <div class="tool-call-card__label">{{ toolCall.error ? '错误' : '结果' }}</div>
      <pre :class="['tool-call-card__pre', { 'tool-call-card__pre--error': !!toolCall.error }]">{{ toolCall.error || toolCall.result }}</pre>
    </div>
    <div v-if="!expanded && toolCall.result" class="tool-call-card__preview">
      {{ previewText }}
    </div>
    <div v-if="toolCall.children && toolCall.children.length > 0 && expanded && props.depth < MAX_DEPTH" class="tool-call-card__children">
      <ToolCallCard
        v-for="child in toolCall.children"
        :key="child.id"
        :tool-call="child"
        :depth="props.depth + 1"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, type Component } from 'vue'
import {
  LoadingOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  RightOutlined,
  ReadOutlined,
  EditOutlined,
  CodeOutlined,
  FileAddOutlined,
  SearchOutlined,
  FolderOpenOutlined,
  ThunderboltOutlined,
  ApiOutlined,
} from '@ant-design/icons-vue'
import type { IToolCallData } from '@/api/types'

const props = withDefaults(
  defineProps<{
    toolCall: IToolCallData
    depth?: number
  }>(),
  { depth: 0 }
)

const MAX_DEPTH = 5

const expanded = ref(false)

const iconMap: Record<string, Component> = {
  read: ReadOutlined,
  edit: EditOutlined,
  bash: CodeOutlined,
  write: FileAddOutlined,
  search: SearchOutlined,
  grep: SearchOutlined,
  glob: FolderOpenOutlined,
  tool: ApiOutlined,
}

const icon = computed(() => {
  const key = props.toolCall.name.toLowerCase()
  for (const [prefix, component] of Object.entries(iconMap)) {
    if (key.includes(prefix)) return component
  }
  return ThunderboltOutlined
})

const previewText = computed(() => {
  const result = props.toolCall.result || ''
  const lines = result.split('\n').filter(Boolean)
  return lines.slice(0, 2).join('\n') + (lines.length > 2 ? '...' : '')
})
</script>

<style scoped>
.tool-call-card {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  overflow: hidden;
  font-size: var(--font-sm);
  transition: border-color var(--transition-fast);
}

.tool-call-card:hover {
  border-color: var(--color-primary-light);
}

.tool-call-card--running {
  border-color: var(--color-primary);
}

.tool-call-card--error {
  border-color: var(--color-error);
}

.tool-call-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-2) var(--space-3);
  cursor: pointer;
  background: var(--bg-secondary);
  user-select: none;
}

.tool-call-card__header:hover {
  background: var(--bg-tertiary);
}

.tool-call-card__title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}

.tool-call-card__icon {
  font-size: 14px;
  color: var(--color-primary);
}

.tool-call-card__name {
  font-weight: var(--font-weight-medium);
  color: var(--text-primary);
}

.tool-call-card__duration {
  font-size: var(--font-xs);
  color: var(--text-tertiary);
}

.tool-call-card__status {
  display: flex;
  align-items: center;
  gap: var(--space-1);
}

.tool-call-card__spinner {
  font-size: 14px;
  color: var(--color-primary);
}

.tool-call-card__check {
  font-size: 14px;
  color: var(--color-success);
}

.tool-call-card__error-icon {
  font-size: 14px;
  color: var(--color-error);
}

.tool-call-card__expand {
  font-size: 10px;
  color: var(--text-placeholder);
  transition: transform var(--transition-fast);
}

.tool-call-card__expand--open {
  transform: rotate(90deg);
}

.tool-call-card__params,
.tool-call-card__result {
  padding: var(--space-2) var(--space-3);
  border-top: 1px solid var(--border-color-split);
}

.tool-call-card__label {
  font-size: var(--font-xs);
  color: var(--text-tertiary);
  margin-bottom: var(--space-1);
  font-weight: var(--font-weight-medium);
}

.tool-call-card__pre {
  background: var(--code-bg);
  color: var(--code-fg);
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  overflow-x: auto;
  font-size: var(--font-xs);
  margin: 0;
  font-family: 'SF Mono', 'Fira Code', Menlo, Consolas, monospace;
  white-space: pre-wrap;
  word-break: break-all;
}

.tool-call-card__pre--error {
  color: var(--color-error);
}

.tool-call-card__preview {
  padding: var(--space-2) var(--space-3);
  color: var(--text-tertiary);
  font-size: var(--font-xs);
  white-space: pre-wrap;
  border-top: 1px solid var(--border-color-split);
  max-height: 40px;
  overflow: hidden;
}

.tool-call-card__children {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-2) var(--space-3);
  padding-left: var(--space-4);
  border-top: 1px solid var(--border-color-split);
}
</style>
