<template>
  <div ref="processRef" class="process-block" :class="{ 'is-streaming': streaming }">
    <!-- Single loop: render all steps in index order for proper alternation -->
    <template v-for="item in orderedItems">
      <!-- Thinking Step -->
      <div v-if="item.type === 'thinking'" :key="`thinking-${item.key}`" class="step-item thinking">
        <div class="step-header" @click="toggleExpand(item.key)">
          <span v-html="brainIcon"></span>
          <span class="step-label">思考中</span>
          <span class="step-brief">{{ item.brief || '正在思考...' }}</span>
          <span v-if="streaming && item.key === lastThinkingKey" class="loading-dots">...</span>
          <span class="arrow" :class="{ open: expandedKeys.has(item.key) }" v-html="chevronDown"></span>
        </div>
        <div v-if="expandedKeys.has(item.key)" class="step-content">
          <div class="thinking-text">{{ item.content }}</div>
        </div>
      </div>

      <!-- Tool Call Step -->
      <div v-else-if="item.type === 'tool_call'" :key="`tool-${item.key}`" class="step-item tool_call" :class="{ loading: item.loading }">
        <div class="step-header" @click="toggleExpand(item.key)">
          <span v-html="toolIcon"></span>
          <span class="step-label">{{ item.name || '工具调用' }}</span>
          <span class="step-brief">{{ item.brief || '' }}</span>
          <span v-if="item.loading" class="loading-dots">...</span>
          <span v-else-if="item.isSuccess === true" class="step-badge success">成功</span>
          <span v-else-if="item.isSuccess === false" class="step-badge error">失败</span>
          <span class="arrow" :class="{ open: expandedKeys.has(item.key) }" v-html="chevronDown"></span>
        </div>
        <div v-if="expandedKeys.has(item.key)" class="step-content">
          <div class="tool-detail">
            <span class="detail-label">参数</span>
            <pre>{{ formatArgs(item.args) }}</pre>
          </div>
          <div v-if="item.resultSummary || item.fullResult" class="tool-detail" style="margin-top: 8px;">
            <span class="detail-label">结果</span>
            <pre>{{ item.fullResult || item.resultSummary }}</pre>
          </div>
        </div>
      </div>

      <!-- Text Step -->
      <div v-else-if="item.type === 'text'" :key="`text-${item.key}`" class="text-content md-content" v-html="renderMarkdown(item.content)"></div>
    </template>

    <!-- Streaming indicator -->
    <div v-if="streaming && !hasContent" class="streaming-indicator">
      <span v-html="sparkleIcon"></span>
      <span>AI 正在输入...</span>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue'
import { renderMarkdown } from '../utils/markdown.js'

const props = defineProps({
  processSteps: { type: Array, default: () => [] },
  toolCalls: { type: Array, default: () => [] },
  streaming: { type: Boolean, default: false },
})

const processRef = ref(null)
const expandedKeys = ref(new Set())

// 构建 processItems 从 processSteps
const allItems = computed(() => {
  const items = []
  
  if (props.processSteps && props.processSteps.length > 0) {
    for (const step of props.processSteps) {
      if (step.type === 'thinking') {
        items.push({
          key: step.id || `thinking-${step.index}`,
          type: 'thinking',
          index: step.index,
          content: step.content || '',
          brief: step.content ? step.content.slice(0, 50) + (step.content.length > 50 ? '...' : '') : '',
        })
      } else if (step.type === 'tool_call') {
        items.push({
          key: step.id || `tool-${step.index}`,
          type: 'tool_call',
          index: step.index,
          id: step.id,
          name: step.name,
          args: step.arguments || step.args || '{}',  // 后端发送 arguments 字段
          brief: step.name || '',
          loading: step.loading,
          isSuccess: step.isSuccess,
          resultSummary: step.resultSummary,
          fullResult: step.fullResult,
        })
      } else if (step.type === 'tool_result') {
        // 合并 tool_result 到对应的 tool_call
        const toolId = step.id_ref || step.id
        const match = items.findLast(it => it.type === 'tool_call' && it.id === toolId)
        if (match) {
          match.resultSummary = step.content ? step.content.slice(0, 200) : ''
          match.fullResult = step.content || ''
          match.isSuccess = step.success !== false
          match.loading = false
        } else {
          // 如果没有找到对应的 tool_call，创建一个占位符
          items.push({
            key: `result-${step.id || step.index}`,
            type: 'tool_call',
            index: step.index,
            id: step.id_ref || step.id,
            name: step.name || '工具结果',
            args: '{}',  // 占位符默认空参数
            brief: step.name || '工具结果',
            loading: false,
            isSuccess: true,
            resultSummary: step.content ? step.content.slice(0, 200) : '',
            fullResult: step.content || ''
          })
        }
      } else if (step.type === 'text') {
        items.push({
          key: step.id || `text-${step.index}`,
          type: 'text',
          index: step.index,
          content: step.content || '',
        })
      }
    }
  } else if (props.toolCalls && props.toolCalls.length > 0) {
    // 兼容旧的 toolCalls 格式
    for (const tc of props.toolCalls) {
      items.push({
        key: tc.id || `tool-${tc.index}`,
        type: 'tool_call',
        id: tc.id,
        name: tc.name,
        args: tc.arguments,
        brief: tc.name || '',
      })
    }
  }
  
  return items
})

// Ordered by index for proper step alternation
const orderedItems = computed(() => 
  [...allItems.value].sort((a, b) => (a.index || 0) - (b.index || 0))
)

const orderedThinkingItems = computed(() => 
  allItems.value
    .filter(i => i.type === 'thinking')
    .sort((a, b) => (a.index || 0) - (b.index || 0))
)

const orderedToolCallItems = computed(() => 
  allItems.value
    .filter(i => i.type === 'tool_call')
    .sort((a, b) => (a.index || 0) - (b.index || 0))
)

const orderedTextItems = computed(() => 
  allItems.value
    .filter(i => i.type === 'text')
    .sort((a, b) => (a.index || 0) - (b.index || 0))
)

const hasContent = computed(() => allItems.value.length > 0)
const lastThinkingKey = computed(() => {
  const items = allItems.value.filter(i => i.type === 'thinking')
  return items.length > 0 ? items[items.length - 1].key : null
})

function toggleExpand(key) {
  if (expandedKeys.value.has(key)) {
    expandedKeys.value.delete(key)
  } else {
    expandedKeys.value.add(key)
  }
  expandedKeys.value = new Set(expandedKeys.value)
}

function formatArgs(args) {
  if (!args) return '{}'
  if (typeof args === 'string') {
    try {
      return JSON.stringify(JSON.parse(args), null, 2)
    } catch {
      return args
    }
  }
  return JSON.stringify(args, null, 2)
}

// Icons
const brainIcon = `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 5a3 3 0 1 0-5.997.125 4 4 0 0 0-2.526 5.77 4 4 0 0 0 .556 6.588A4 4 0 1 0 12 18Z"></path><path d="M12 5a3 3 0 1 1 5.997.125 4 4 0 0 1 2.526 5.77 4 4 0 0 1-.556 6.588A4 4 0 1 1 12 18Z"></path><path d="M15 13a4.5 4.5 0 0 1-3-4 4.5 4.5 0 0 1-3 4"></path><path d="M17.599 6.5a3 3 0 0 0 .399-1.375"></path><path d="M6.003 5.125A3 3 0 0 0 6.401 6.5"></path><path d="M3.477 10.896a4 4 0 0 1 .585-.396"></path><path d="M19.938 10.5a4 4 0 0 1 .585.396"></path><path d="M6 18a4 4 0 0 1-1.967-.516"></path><path d="M19.967 17.484A4 4 0 0 1 18 18"></path></svg>`

const toolIcon = `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"></path></svg>`

const chevronDown = `<svg viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>`

const sparkleIcon = `<svg viewBox="0 0 24 24" width="14" height="14" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="m12 3-1.912 5.813a2 2 0 0 1-1.275 1.275L3 12l5.813 1.912a2 2 0 0 1 1.275 1.275L12 21l1.912-5.813a2 2 0 0 1 1.275-1.275L21 12l-5.813-1.912a2 2 0 0 1-1.275-1.275L12 3Z"></path></svg>`
</script>

<style scoped>
.process-block {
  width: 100%;
}

/* Step items (shared) */
.step-item {
  margin-bottom: 8px;
}

.step-item:last-child {
  margin-bottom: 0;
}

@keyframes pulse {
  0%, 100% { opacity: 0.4; }
  50% { opacity: 1; }
}

/* Step header (shared by thinking and tool_call) */
.thinking .step-header,
.tool_call .step-header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  background: var(--bg-secondary);
  border: 1px solid var(--border-light);
  border-radius: 8px;
  cursor: pointer;
  font-size: 13px;
  transition: background 0.15s;
}

.thinking .step-header:hover,
.tool_call .step-header:hover {
  background: var(--bg-hover);
}

.thinking .step-header svg:first-child {
  color: #f59e0b;
}

.tool_call .step-header svg:first-child {
  color: var(--tool-color);
}

.step-label {
  font-weight: 500;
  color: var(--text-primary);
  flex-shrink: 0;
  min-width: 130px;
  max-width: 130px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.arrow {
  margin-left: auto;
  transition: transform 0.2s;
  color: var(--text-tertiary);
  flex-shrink: 0;
}

.step-badge {
  font-size: 11px;
  padding: 2px 8px;
  border-radius: 10px;
  font-weight: 500;
}

.step-badge.success {
  background: var(--success-bg);
  color: var(--success-color);
}

.step-badge.error {
  background: var(--danger-bg);
  color: var(--danger-color);
}

.step-brief {
  font-size: 11px;
  color: var(--text-tertiary);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  flex: 1;
  min-width: 0;
}

.arrow.open {
  transform: rotate(180deg);
}

.loading-dots {
  font-size: 16px;
  font-weight: 700;
  color: var(--tool-color);
  animation: pulse 1s ease-in-out infinite;
}

.tool_call.loading .step-header {
  background: var(--bg-hover);
}

/* Expandable step content panel */
.step-content {
  padding: 12px;
  margin-top: 4px;
  background: var(--bg-code);
  border: 1px solid var(--border-light);
  border-radius: 8px;
  overflow: hidden;
}

.thinking-text {
  font-size: 13px;
  color: var(--text-secondary);
  line-height: 1.6;
  white-space: pre-wrap;
}

.tool-detail {
  font-size: 13px;
}

.detail-label {
  color: var(--text-tertiary);
  font-size: 11px;
  font-weight: 600;
  display: block;
  margin-bottom: 4px;
}

.tool-detail pre {
  padding: 8px;
  background: var(--bg-primary);
  border-radius: 4px;
  border: 1px solid var(--border-light);
  font-family: 'JetBrains Mono', 'Fira Code', monospace;
  font-size: 12px;
  line-height: 1.5;
  color: var(--text-secondary);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-word;
}

/* Text content */
.text-content {
  padding: 0;
  font-size: 15px;
  line-height: 1.7;
  color: var(--text-primary);
  word-break: break-word;
  contain: layout style;
}

.text-content :deep(.placeholder) {
  color: var(--text-tertiary);
}

/* Streaming cursor indicator */
.streaming-indicator {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 12px;
  color: var(--text-tertiary);
}

/* Add separator only when there are step items above the indicator */
.process-block:has(.step-item) .streaming-indicator {
  margin-top: 8px;
  padding: 8px 0 0;
  border-top: 1px solid var(--border-light);
}
</style>
