<script setup lang="ts">
import { computed } from 'vue'
import type { ToolCallGroup, ToolCallEntry } from '@/types/chat'

const props = defineProps<{
  group: ToolCallGroup
}>()

const emit = defineEmits<{
  approve: []
  skip: []
}>()

const isPending = computed(() => props.group.status === 'pending')
const isExecuting = computed(() => props.group.status === 'executing')
const isDone = computed(() => props.group.status === 'done')
const isSkipped = computed(() => props.group.status === 'skipped')

// 工具图标（SVG path）
const TOOL_ICONS: Record<string, string> = {
  // 大纲
  list_outlines: 'M3 4h10M3 8h10M3 12h6',
  create_outline: 'M8 3v10M3 8h10',
  update_outline: 'M3 12l2-2 4 4-2 2H3v-4zM9 6l2-2 4 4-2 2-4-4z',
  delete_outline: 'M3 5h10M5 5V3h6v2M4 5v8h8V5',
  reorder_outlines: 'M3 4h7M3 8h7M3 12h7M12 3l2 2-2 2M12 9l2 2-2 2',
  // 世界观
  get_world_setting: 'M8 1a7 7 0 100 14A7 7 0 008 1zM1 8h14M8 1c2 2 3 4.5 3 7s-1 5-3 7M8 1c-2 2-3 4.5-3 7s1 5 3 7',
  save_world_setting: 'M8 1a7 7 0 100 14A7 7 0 008 1zM4 8l3 3 5-5',
  // 角色
  list_characters: 'M5.5 5a2.5 2.5 0 105 0 2.5 2.5 0 00-5 0zM3 13c0-2.5 2-4 5-4s5 1.5 5 4',
  create_character: 'M5 5a2.5 2.5 0 105 0 2.5 2.5 0 00-5 0zM2 13c0-2.5 2-4 5-4M12 6v5M9.5 8.5h5',
  update_character: 'M5 5a2.5 2.5 0 105 0 2.5 2.5 0 00-5 0zM3 13c0-2.5 2-4 5-4M10 10l2-2 2 2-2 2z',
  delete_character: 'M5 5a2.5 2.5 0 105 0 2.5 2.5 0 00-5 0zM3 13c0-2.5 2-4 5-4M10 8l4 4M14 8l-4 4',
  // 章节
  list_chapters: 'M4 2h8v12H4zM6 5h4M6 8h4M6 11h2',
  create_chapter: 'M3 2h7v12H3zM12 5v5M9.5 7.5h5',
  update_chapter: 'M4 2h8v12H4zM7 7l2-2 2 2-2 2z',
  delete_chapter: 'M4 2h8v12H4zM6 6l4 4M10 6l-4 4',
  // 文件
  list_files: 'M13.5 7.5l-5.8 5.8a3.2 3.2 0 01-4.5-4.5l5.8-5.8a2.1 2.1 0 013 3L6.2 11.8',
  read_file: 'M4 2h5l3 3v9H4V2zM9 2v3h3M6 8h4M6 10h4M6 12h2',
}

// 工具颜色主题
const TOOL_COLORS: Record<string, string> = {
  // 大纲
  list_outlines: 'var(--bamboo)',
  create_outline: 'var(--bamboo)',
  update_outline: '#d4a017',
  delete_outline: 'var(--danger)',
  reorder_outlines: '#d4a017',
  // 世界观
  get_world_setting: 'var(--ink-500)',
  save_world_setting: 'var(--bamboo)',
  // 角色
  list_characters: '#7c6bc4',
  create_character: '#7c6bc4',
  update_character: '#d4a017',
  delete_character: 'var(--danger)',
  // 章节
  list_chapters: '#4a90d9',
  create_chapter: '#4a90d9',
  update_chapter: '#d4a017',
  delete_chapter: 'var(--danger)',
  // 文件
  list_files: '#e8833a',
  read_file: '#e8833a',
}

function getIcon(name: string): string {
  return TOOL_ICONS[name] ?? 'M8 3v10M3 8h10'
}

function getColor(name: string): string {
  return TOOL_COLORS[name] ?? 'var(--ink-400)'
}

/** 格式化参数为可读文本 */
function formatArgs(call: ToolCallEntry): string {
  const args = call.arguments
  if (!args || Object.keys(args).length === 0) return ''

  switch (call.name) {
    case 'create_outline':
      return args.summary as string ?? ''
    case 'update_outline':
      return `#${args.outline_id}` + (args.summary ? ` → ${args.summary}` : '')
    case 'delete_outline':
      return `#${args.outline_id}`
    case 'reorder_outlines': {
      const ids = args.ordered_ids as number[]
      return ids ? `${ids.length} 个节点` + (args.parent_id ? ` (父节点 #${args.parent_id})` : '') : ''
    }
    case 'save_world_setting': {
      const content = (args.content as string) ?? ''
      return content.length > 80 ? content.slice(0, 80) + '…' : content
    }
    // 角色
    case 'create_character':
      return args.name as string ?? ''
    case 'update_character':
      return `#${args.character_id}` + (args.name ? ` → ${args.name}` : '')
    case 'delete_character':
      return `#${args.character_id}`
    // 章节
    case 'create_chapter':
      return args.title as string ?? ''
    case 'update_chapter':
      return `#${args.chapter_id}` + (args.title ? ` → ${args.title}` : '')
    case 'delete_chapter':
      return `#${args.chapter_id}`
    // 文件
    case 'read_file':
      return `#${args.file_id}` + (args.offset ? ` (偏移 ${args.offset})` : '')
    default:
      return ''
  }
}

/** 格式化工具结果 */
function formatResult(call: ToolCallEntry): string {
  if (!call.result) return ''
  try {
    const data = call.parsedResult ?? JSON.parse(call.result)
    // 通用错误检查
    if ((data as { error?: string }).error) return `失败: ${(data as { error: string }).error}`

    switch (call.name) {
      // 大纲
      case 'list_outlines': {
        const items = (data as { outlines: { id: number; summary: string }[] }).outlines
        if (!items?.length) return '暂无大纲'
        return items.map((o: { id: number; summary: string }) => `• ${o.summary}`).join('\n')
      }
      case 'create_outline':
        return `已创建: ${(data as { summary: string }).summary}`
      case 'update_outline':
        return `已更新: ${(data as { summary: string }).summary}`
      case 'delete_outline':
        return '已删除'
      case 'reorder_outlines':
        return `已调整 ${(data as { count: number }).count} 个节点的排序`
      // 世界观
      case 'get_world_setting': {
        const content = (data as { content: string }).content
        if (!content) return '暂无世界观设定'
        return content.length > 120 ? content.slice(0, 120) + '…' : content
      }
      case 'save_world_setting':
        return `已保存 (${(data as { content_length: number }).content_length} 字)`
      // 角色
      case 'list_characters': {
        const chars = (data as { characters: { id: number; name: string }[] }).characters
        if (!chars?.length) return '暂无角色'
        return chars.map((c: { id: number; name: string }) => `• ${c.name}`).join('\n')
      }
      case 'create_character':
        return `已创建: ${(data as { name: string }).name}`
      case 'update_character':
        return `已更新: ${(data as { name: string }).name}`
      case 'delete_character':
        return '已删除'
      // 章节
      case 'list_chapters': {
        const chs = (data as { chapters: { id: number; title: string }[] }).chapters
        if (!chs?.length) return '暂无章节'
        return chs.map((c: { id: number; title: string }) => `• ${c.title}`).join('\n')
      }
      case 'create_chapter':
        return `已创建: ${(data as { title: string }).title}`
      case 'update_chapter':
        return `已更新: ${(data as { title: string }).title}`
      case 'delete_chapter':
        return '已删除'
      // 文件
      case 'list_files': {
        const files = (data as { files: { id: number; filename: string; text_length: number }[] }).files
        if (!files?.length) return '暂无文件'
        return files.map((f: { id: number; filename: string; text_length: number }) => `• ${f.filename} (${f.text_length} 字)`).join('\n')
      }
      case 'read_file': {
        const d = data as { filename: string; total_length: number; offset: number; limit: number; has_more: boolean }
        return `${d.filename} [${d.offset}–${d.offset + d.limit}] / ${d.total_length} 字${d.has_more ? '（还有更多）' : ''}`
      }
      default:
        return call.result.slice(0, 100)
    }
  } catch {
    return call.result.slice(0, 100)
  }
}
</script>

<template>
  <div class="tool-calls-card">
    <div class="tool-calls-header">
      <span class="tool-calls-title">工具调用</span>
      <span v-if="isPending" class="tool-calls-badge badge--pending">待确认</span>
      <span v-else-if="isExecuting" class="tool-calls-badge badge--executing">执行中</span>
      <span v-else-if="isDone" class="tool-calls-badge badge--done">已完成</span>
      <span v-else-if="isSkipped" class="tool-calls-badge badge--skipped">已跳过</span>
    </div>

    <!-- 每个工具调用 -->
    <div
      v-for="call in group.calls"
      :key="call.id"
      class="tool-item"
      :class="{ 'tool-item--danger': call.name.includes('delete') }"
    >
      <div class="tool-item-header">
        <svg class="tool-item-icon" width="16" height="16" viewBox="0 0 16 16" fill="none">
          <path :d="getIcon(call.name)" :stroke="getColor(call.name)" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round" fill="none" />
        </svg>
        <span class="tool-item-label" :style="{ color: getColor(call.name) }">{{ call.label }}</span>
      </div>

      <!-- 参数 -->
      <div v-if="formatArgs(call)" class="tool-item-args">{{ formatArgs(call) }}</div>

      <!-- 结果 -->
      <div v-if="call.result" class="tool-item-result">
        <pre class="result-text">{{ formatResult(call) }}</pre>
      </div>
    </div>

    <!-- 审批按钮 -->
    <div v-if="isPending" class="tool-actions">
      <button class="tool-btn tool-btn--approve" @click="emit('approve')">
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <path d="M3 7l3 3 5-5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" />
        </svg>
        执行
      </button>
      <button class="tool-btn tool-btn--skip" @click="emit('skip')">
        <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
          <path d="M10 4L4 10M4 4l6 6" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
        </svg>
        跳过
      </button>
    </div>

    <!-- 执行中指示 -->
    <div v-if="isExecuting" class="tool-executing">
      <span class="dot" /><span class="dot" /><span class="dot" />
    </div>
  </div>
</template>

<style scoped>
.tool-calls-card {
  background: var(--paper-50);
  border: 1px solid var(--paper-200);
  border-radius: var(--radius-md);
  padding: var(--space-sm) var(--space-md);
  margin-bottom: var(--space-md);
  animation: fadeInUp var(--duration-fast) var(--ease-out-smooth) both;
}

.tool-calls-header {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
  margin-bottom: var(--space-sm);
}

.tool-calls-title {
  font-size: 0.75rem;
  font-weight: 600;
  color: var(--ink-400);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.tool-calls-badge {
  font-size: 0.68rem;
  padding: 1px 6px;
  border-radius: 8px;
  font-weight: 500;
}

.badge--pending {
  background: rgba(212, 160, 23, 0.12);
  color: #b8860b;
}

.badge--executing {
  background: rgba(91, 140, 90, 0.12);
  color: var(--bamboo);
  animation: toolPulse 1.5s ease-in-out infinite;
}

.badge--done {
  background: rgba(91, 140, 90, 0.12);
  color: var(--bamboo);
}

.badge--skipped {
  background: var(--paper-100);
  color: var(--ink-300);
}

.tool-item {
  padding: var(--space-xs) var(--space-sm);
  border-radius: var(--radius-sm);
  background: var(--paper-100);
  margin-bottom: var(--space-xs);
}

.tool-item--danger {
  background: rgba(220, 53, 69, 0.04);
}

.tool-item-header {
  display: flex;
  align-items: center;
  gap: 6px;
}

.tool-item-icon {
  flex-shrink: 0;
}

.tool-item-label {
  font-size: 0.82rem;
  font-weight: 600;
}

.tool-item-args {
  font-size: 0.78rem;
  color: var(--ink-500);
  margin-top: 2px;
  padding-left: 22px;
  word-break: break-word;
}

.tool-item-result {
  margin-top: 4px;
  padding-left: 22px;
}

.result-text {
  font-size: 0.75rem;
  color: var(--ink-600);
  background: var(--paper-50);
  border: 1px solid var(--paper-200);
  border-radius: var(--radius-sm);
  padding: var(--space-xs) var(--space-sm);
  margin: 0;
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 120px;
  overflow-y: auto;
  font-family: var(--font-body);
}

/* 审批按钮 */
.tool-actions {
  display: flex;
  gap: var(--space-sm);
  margin-top: var(--space-sm);
  justify-content: flex-end;
}

.tool-btn {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 4px 12px;
  border-radius: var(--radius-sm);
  border: 1px solid;
  font-size: 0.78rem;
  font-weight: 500;
  cursor: pointer;
  transition: all var(--duration-fast) ease;
}

.tool-btn--approve {
  background: var(--bamboo);
  border-color: var(--bamboo);
  color: white;
}

.tool-btn--approve:hover {
  opacity: 0.85;
}

.tool-btn--skip {
  background: var(--paper-50);
  border-color: var(--paper-300);
  color: var(--ink-500);
}

.tool-btn--skip:hover {
  background: var(--paper-100);
  color: var(--ink-700);
}

/* 执行中 */
.tool-executing {
  display: flex;
  gap: 4px;
  justify-content: center;
  padding: var(--space-xs) 0;
}

.tool-executing .dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--bamboo);
  animation: typingBounce 1.4s ease-in-out infinite;
}

.tool-executing .dot:nth-child(2) { animation-delay: 0.2s; }
.tool-executing .dot:nth-child(3) { animation-delay: 0.4s; }

@keyframes toolPulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.5; }
}

@keyframes typingBounce {
  0%, 60%, 100% { transform: translateY(0); }
  30% { transform: translateY(-4px); }
}
</style>
