<template>
  <div class="minimal-blocks-container">
    <!-- 按真实顺序显示分组 -->
    <template v-for="group in blockGroups" :key="group.id">
      <!-- 摘要组（thinking/tool） -->
      <div v-if="group.type === 'summary' && group.actions" class="summary-group">
        <!-- 摘要行（只有文字，可点击展开） -->
        <div
          class="summary-line-text"
          :class="{ running: isSummaryRunning(group.actions, group.id) }"
          @click="toggleExpand(group.id)"
        >
          <div class="summary-content-wrapper">
            <span class="summary-preview">
              <template v-if="isSummaryRunning(group.actions, group.id)">
                <span
                  v-for="(char, idx) in getAnimatedSummaryChars(getSummaryPreview(group.actions))"
                  :key="`${group.id}-${idx}`"
                  class="summary-char"
                  :style="{ animationDelay: `${(idx + 1) * 0.12}s` }"
                >
                  {{ char === ' ' ? '\u00A0' : char }}
                </span>
              </template>
              <template v-else>
                {{ getSummaryPreview(group.actions) }}
              </template>
            </span>
          </div>
          <!-- 加载动画或完成图标 -->
          <div class="summary-status-icon">
            <component
              v-if="isSummaryRunning(group.actions, group.id)"
              :is="getSummaryLoader(group.id)"
            />
            <svg
              v-else
              class="check-icon"
              width="18"
              height="18"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
            >
              <circle cx="12" cy="12" r="10" />
              <polyline points="7.5 12 10.5 15 16.5 9" />
            </svg>
          </div>
        </div>

        <!-- 步骤容器（展开时显示所有步骤） -->
        <div class="steps-container" :class="{ show: expandedGroups.has(group.id) }">
          <div class="steps-wrapper">
            <div v-for="step in getSummarySteps(group.actions)" :key="step.id" class="step-item">
              <div class="step-timeline">
                <span
                  class="step-icon icon icon-sm"
                  :style="getStepIconStyle(step)"
                  aria-hidden="true"
                ></span>
                <div class="step-line"></div>
              </div>
              <div class="step-content">
                <div v-if="step.type === 'thinking'" class="step-body">
                  <div
                    class="thinking-content"
                    :ref="(el) => registerThinking(step.id, el)"
                    @scroll="handleScroll(step.id, $event)"
                    v-html="renderContent(step.content)"
                  ></div>
                </div>
                <div v-else-if="step.type === 'tool'" class="step-body">
                  <div class="step-header">{{ getToolName(step.action) }}</div>
                  <div class="tool-intent" v-if="getToolIntent(step.action)">
                    {{ getToolIntent(step.action) }}
                  </div>
                  <div class="tool-result" v-if="step.action.tool?.result">
                    <div v-html="renderToolResult(step.action)"></div>
                  </div>
                  <div v-else class="tool-result">
                    <div class="result-item">执行中...</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 文本组 -->
      <div
        v-else-if="group.type === 'text'"
        class="text-output"
        :class="{ 'streaming-text': group.streaming }"
      >
        <div class="text-content" :class="{ 'streaming-text': group.streaming }">
          <div v-if="group.streaming" v-html="renderMarkdown(group.content || '', true)"></div>
          <div v-else v-html="renderMarkdown(group.content || '', false)"></div>
        </div>
      </div>
      <div v-else-if="group.type === 'system'" class="summary-group sub-agent-system-group">
        <div class="summary-line-text sub-agent-system-summary-line">
          <div class="summary-content-wrapper">
            <span class="summary-preview">{{ group.content || '' }}</span>
          </div>
          <div class="summary-status-icon">
            <svg
              class="check-icon"
              width="18"
              height="18"
              viewBox="0 0 24 24"
              fill="none"
              stroke="currentColor"
              stroke-width="2"
            >
              <circle cx="12" cy="12" r="10" />
              <polyline points="7.5 12 10.5 15 16.5 9" />
            </svg>
          </div>
        </div>
      </div>
    </template>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, Component } from 'vue';
import { usePersonalizationStore } from '@/stores/personalization';
import { renderEnhancedToolResult } from './actions/toolRenderers';
import { getRandomLoader } from './loaders/index';

interface Action {
  id?: string;
  type: 'thinking' | 'tool' | 'text' | 'system';
  content: string;
  streaming?: boolean;
  blockId?: string;
  tool?: {
    name?: string;
    intent?: string;
    arguments?: any;
    result?: any;
  };
}

interface Step {
  id: string;
  type: 'thinking' | 'tool';
  content: string;
  streaming: boolean;
  action: Action;
}

interface BlockGroup {
  type: 'summary' | 'text' | 'system';
  id: string;
  actions?: Action[];
  content?: string;
  streaming?: boolean;
}

const props = defineProps<{
  actions: Action[];
  conversationRunning?: boolean;
  isLatestMessage?: boolean;
  iconStyle?: (name: string) => any;
  getToolIcon?: (tool: any) => string;
  getToolStatusText?: (tool: any) => string;
  getToolDescription?: (tool: any) => string;
  formatSearchTopic?: (filters: Record<string, any>) => string;
  formatSearchTime?: (filters: Record<string, any>) => string;
  formatSearchDomains?: (filters: Record<string, any>) => string;
  renderMarkdown?: (content: string, isStreaming: boolean) => string;
  registerThinkingRef?: (key: string, el: Element | null) => void;
  handleThinkingScroll?: (blockId: string, event: Event) => void;
}>();

const personalizationStore = usePersonalizationStore();
const expandedGroups = ref(new Set<string>());
const thinkingRefs = new Map<string, HTMLElement>();
const summaryLoaders = new Map<string, Component>();
const SUMMARY_PREVIEW_MAX_CHARS = 25;

const truncateSummaryPreview = (raw: string) => {
  const text = typeof raw === 'string' ? raw : '';
  if (text.length > SUMMARY_PREVIEW_MAX_CHARS) {
    return `${text.slice(0, SUMMARY_PREVIEW_MAX_CHARS)}...`;
  }
  return text;
};

const getAnimatedSummaryChars = (text: string) => Array.from(text || '');

// 获取摘要组的加载动画组件（每次action类型切换时随机一次）
const getSummaryLoader = (groupId: string) => {
  const group = blockGroups.value.find((g) => g.id === groupId);
  if (!group || !group.actions) return getRandomLoader();

  // 找到当前正在streaming的action，或最后一个action
  const streamingAction = group.actions.find((a) => a.streaming);
  const currentAction = streamingAction || group.actions[group.actions.length - 1];

  if (!currentAction) return getRandomLoader();

  // 找到当前action之前最近的一个不同类型的action
  // 用于判断是否发生了类型切换（thinking <-> tool）
  const currentIndex = group.actions.indexOf(currentAction);
  let lastDifferentTypeIndex = -1;

  for (let i = currentIndex - 1; i >= 0; i--) {
    if (group.actions[i].type !== currentAction.type) {
      lastDifferentTypeIndex = i;
      break;
    }
  }

  // 使用"类型切换点"作为key
  // 如果是第一个action，或者类型发生了切换，就会生成新的key
  // 如果是相同类型的连续action（如多个工具并行），使用相同的key
  const typeSegmentKey =
    lastDifferentTypeIndex >= 0
      ? `${group.actions[lastDifferentTypeIndex].id}-${currentAction.type}`
      : `start-${currentAction.type}`;

  const cacheKey = `${groupId}-${typeSegmentKey}`;

  if (!summaryLoaders.has(cacheKey)) {
    summaryLoaders.set(cacheKey, getRandomLoader());
  }
  return summaryLoaders.get(cacheKey);
};

// 将 actions 分组：连续的 thinking/tool 为一组，text 单独为一组
const blockGroups = computed(() => {
  const groups: BlockGroup[] = [];
  let currentGroup: Action[] = [];
  let groupIndex = 0;

  props.actions.forEach((action, idx) => {
    if (action.type === 'thinking' || action.type === 'tool') {
      currentGroup.push(action);
    } else if (action.type === 'text' || action.type === 'system') {
      // 先保存当前的 thinking/tool 组
      if (currentGroup.length > 0) {
        // 使用第一个 action 的 id 作为 group id，保证稳定性
        const firstActionId =
          currentGroup[0].id || currentGroup[0].blockId || `summary-${groupIndex}`;
        groups.push({
          type: 'summary',
          id: `summary-${firstActionId}`,
          actions: currentGroup
        });
        groupIndex++;
        currentGroup = [];
      }
      if (action.type === 'text') {
        const text = typeof action.content === 'string' ? action.content : '';
        if (!text.trim()) {
          return;
        }
        // 添加 text 组
        groups.push({
          type: 'text',
          id: `text-${idx}`,
          content: text,
          streaming: action.streaming
        });
      } else {
        // 添加 system 组（用于子智能体完成通知，保持顺序）
        groups.push({
          type: 'system',
          id: `system-${idx}`,
          content: action.content
        });
      }
    }
  });

  // 处理最后剩余的 thinking/tool 组
  if (currentGroup.length > 0) {
    // 使用第一个 action 的 id 作为 group id，保证稳定性
    const firstActionId = currentGroup[0].id || currentGroup[0].blockId || `summary-${groupIndex}`;
    groups.push({
      type: 'summary',
      id: `summary-${firstActionId}`,
      actions: currentGroup
    });
  }

  return groups;
});

// 获取摘要组的预览文本（始终显示最新的思考/工具）
const getSummaryPreview = (actions: Action[]) => {
  // 优先返回正在 streaming 的最后一个
  const streamingActions = actions.filter((a) => a.streaming);

  let currentStep;
  if (streamingActions.length > 0) {
    // 如果有 streaming 的，返回最后一个 streaming 的
    currentStep = streamingActions[streamingActions.length - 1];
  } else {
    // 如果没有 streaming 的（全部完成了），优先返回最后一个工具
    const toolActions = actions.filter((a) => a.type === 'tool');
    if (toolActions.length > 0) {
      currentStep = toolActions[toolActions.length - 1];
    } else {
      // 如果没有工具，返回最后一个思考
      currentStep = actions[actions.length - 1];
    }
  }

  if (!currentStep) return '';

  if (currentStep.type === 'thinking') {
    // 思考内容：最多显示到第一个换行，且不超过25字符（不含...）
    const content = currentStep.content || '';
    const firstLineEnd = content.indexOf('\n');
    const textToShow = firstLineEnd > 0 ? content.substring(0, firstLineEnd) : content;
    return truncateSummaryPreview(textToShow);
  } else if (currentStep.type === 'tool') {
    // 工具：优先显示 intent_rendered 或 intent_full
    const tool = currentStep.tool;
    if (!tool) return '';

    const intentEnabled = personalizationStore.form.tool_intent_enabled;
    const intentText = tool.intent_rendered || tool.intent_full || '';

    if (intentEnabled && intentText) {
      // 开启intent模式且有intent时，只显示intent
      const firstLineEnd = intentText.indexOf('\n');
      const textToShow = firstLineEnd > 0 ? intentText.substring(0, firstLineEnd) : intentText;
      return truncateSummaryPreview(textToShow);
    }

    // 没有intent或未开启intent模式时显示状态
    if (tool.status === 'preparing') {
      return `准备调用 ${tool.name || '工具'}...`;
    }
    if (tool.status === 'running') {
      return `正在调用 ${tool.name || '工具'}...`;
    }
    if (tool.status === 'completed') {
      return '工具执行完成';
    }
    return currentStep.streaming ? '正在执行工具...' : '工具执行完成';
  }
  return '';
};

// 判断摘要组是否正在运行（显示加载动画还是对勾）
const isSummaryRunning = (actions: Action[], groupId: string) => {
  if (!props.conversationRunning || !props.isLatestMessage) {
    return false;
  }

  // 找到当前 group 在 blockGroups 中的索引
  const currentIndex = blockGroups.value.findIndex((g) => g.id === groupId);
  if (currentIndex === -1) return false;

  // 检查后面是否有文本输出
  const hasTextAfter = blockGroups.value.slice(currentIndex + 1).some((g) => g.type === 'text');

  // 只有当后面有文本输出时，才显示对勾（说明这个摘要组已经完成并开始输出了）
  // 否则一直显示加载动画（即使工具执行完了，也要等下一个步骤或文本输出）
  return !hasTextAfter;
};

// 获取摘要组的所有步骤（用于展开显示）
const getSummarySteps = (actions: Action[]) => {
  return actions.map((action, idx) => ({
    id: action.id || action.blockId || `step-${idx}`,
    type: action.type as 'thinking' | 'tool',
    content: action.content || '',
    streaming: action.streaming || false,
    action
  }));
};

const toggleExpand = (groupId: string) => {
  if (expandedGroups.value.has(groupId)) {
    expandedGroups.value.delete(groupId);

    // 折叠后，取消注册该组中的思考内容 ref
    nextTick(() => {
      const group = blockGroups.value.find((g) => g.id === groupId);
      if (group && group.actions) {
        group.actions.forEach((action) => {
          if (action.type === 'thinking') {
            const blockId = action.id || action.blockId;
            if (blockId && typeof props.registerThinkingRef === 'function') {
              props.registerThinkingRef(blockId, null);
            }
          }
        });
      }
    });
  } else {
    expandedGroups.value.add(groupId);

    // 展开后，注册该组中的思考内容 ref
    nextTick(() => {
      const group = blockGroups.value.find((g) => g.id === groupId);
      if (group && group.actions) {
        group.actions.forEach((action) => {
          if (action.type === 'thinking') {
            const blockId = action.id || action.blockId;
            if (blockId) {
              const el = thinkingRefs.get(blockId);
              if (el && typeof props.registerThinkingRef === 'function') {
                props.registerThinkingRef(blockId, el);
                // 如果正在 streaming，滚动到底部
                if (action.streaming) {
                  el.scrollTop = el.scrollHeight;
                }
              }
            }
          }
        });
      }
    });
  }
};

const getStepIconStyle = (step: Step) => {
  if (step.type === 'thinking') {
    return props.iconStyle ? props.iconStyle('brain') : {};
  } else if (step.type === 'tool' && step.action.tool) {
    const iconKey = props.getToolIcon ? props.getToolIcon(step.action.tool) : 'terminal';
    return props.iconStyle ? props.iconStyle(iconKey) : {};
  }
  return props.iconStyle ? props.iconStyle('terminal') : {};
};

const getToolName = (action: Action) => {
  const tool = action.tool;
  if (!tool) return '执行工具';

  const intentEnabled = personalizationStore.form.tool_intent_enabled;
  const intentText = tool.intent_rendered || tool.intent_full || '';

  if (intentEnabled && intentText) {
    // 开启intent模式且有intent时，只显示intent
    return intentText;
  }

  // 没有intent或未开启intent模式时显示状态
  if (tool.status === 'preparing') {
    return `准备调用 ${tool.name || '工具'}...`;
  }
  if (tool.status === 'running') {
    return `正在调用 ${tool.name || '工具'}...`;
  }
  if (tool.status === 'completed') {
    return '工具执行完成';
  }
  return tool.name || '执行工具';
};

const getToolIntent = (action: Action) => {
  return action.tool?.intent || '';
};

const renderToolResult = (action: Action) => {
  if (personalizationStore.form.enhanced_tool_display) {
    const rendered = renderEnhancedToolResult(
      action,
      props.formatSearchTopic || (() => ''),
      props.formatSearchTime || (() => ''),
      props.formatSearchDomains || (() => '')
    );
    if (rendered) return rendered;
  }

  const result = action.tool?.result;
  if (!result) return '<div class="result-item">执行中...</div>';

  if (typeof result === 'string') {
    return `<div class="result-item"><pre>${escapeHtml(result)}</pre></div>`;
  }

  return `<div class="result-item"><pre>${escapeHtml(JSON.stringify(result, null, 2))}</pre></div>`;
};

const renderContent = (content: string) => {
  if (!content) return '';
  return escapeHtml(content).replace(/\n/g, '<br>');
};

const renderMarkdown = (content: string, isStreaming: boolean) => {
  if (props.renderMarkdown) {
    return props.renderMarkdown(content, isStreaming);
  }
  // 降级：如果没有提供renderMarkdown，使用简单的HTML转义
  return renderContent(content);
};

const escapeHtml = (text: string) => {
  const div = document.createElement('div');
  div.textContent = text;
  return div.innerHTML;
};

const registerThinking = (key: string, el: Element | null) => {
  // 本地保存一份，用于展开/折叠时管理
  if (el instanceof HTMLElement) {
    thinkingRefs.set(key, el);
  } else {
    thinkingRefs.delete(key);
  }

  // 检查当前思考内容所在的摘要是否展开
  const group = blockGroups.value.find(
    (g) =>
      g.type === 'summary' && g.actions && g.actions.some((a) => a.id === key || a.blockId === key)
  );

  // 只有展开的摘要中的思考内容才注册到父组件
  if (group && expandedGroups.value.has(group.id)) {
    if (typeof props.registerThinkingRef === 'function') {
      props.registerThinkingRef(key, el);
    }
  }
};

const handleScroll = (blockId: string, event: Event) => {
  if (typeof props.handleThinkingScroll === 'function') {
    props.handleThinkingScroll(blockId, event);
  }
};

watch(
  () => props.actions,
  () => {
    // 简化：不需要动态更新高度
  },
  { deep: true }
);
</script>

<style scoped>
.minimal-blocks-container {
  margin: 16px 0;
}

/* 摘要组 */
.summary-group {
  margin: 16px 0;
}

.sub-agent-system-group {
  margin: 0;
}

.sub-agent-system-group .sub-agent-system-summary-line {
  cursor: default;
}

.sub-agent-system-group .sub-agent-system-summary-line:hover {
  background-color: transparent;
}

/* 摘要行（只有文字） */
.summary-line-text {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: start;
  column-gap: 8px;
  padding: 0 6px 0 6px;
  cursor: pointer;
  transition: background-color 0.2s;
}

.summary-line-text:hover {
  background-color: var(--claude-panel);
}

.summary-content-wrapper {
  min-width: 0;
  font-size: 15px;
  color: var(--claude-text-secondary);
  line-height: 1.7;
  padding: 0;
}

.summary-preview {
  display: block;
  white-space: normal;
  overflow-wrap: anywhere;
  word-break: break-word;
  color: inherit;
}

.summary-status-icon {
  flex-shrink: 0;
  margin-left: 0;
  align-self: start;
  margin-top: calc((1.7em - 18px) / 2);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
}

.check-icon {
  color: var(--claude-text-tertiary);
  width: 18px;
  height: 18px;
}

/* 运行中文本：按字符依次闪烁 */
.summary-line-text.running .summary-char {
  display: inline-block;
  color: var(--claude-text-secondary);
  animation: summaryPass 2s ease-in-out infinite;
}

@keyframes summaryPass {
  0%,
  100% {
    color: var(--claude-text-secondary);
  }
  50% {
    color: var(--claude-accent);
  }
}

/* 步骤容器 */
.steps-container {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.3s cubic-bezier(0.4, 0, 0.2, 1);
  margin-top: 8px;
  padding: 0 6px 0 6px;
}

/* 桌面端与正式文本输出左边距保持一致（text-content: 0 20px 0 15px） */
@media (min-width: 769px) {
  .summary-line-text,
  .steps-container {
    padding: 0 20px 0 15px;
  }
}

.steps-wrapper {
  overflow: hidden;
  min-height: 0;
}

.steps-container.show {
  grid-template-rows: 1fr;
}

/* 步骤项 */
.step-item {
  display: flex;
  gap: 12px;
}

.step-item:not(:last-child) {
  margin-bottom: 16px;
}

.step-timeline {
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
  padding-top: 2px;
  align-self: stretch; /* 填充整个 step-item 的高度 */
}

.step-icon {
  flex-shrink: 0;
  color: var(--claude-text-tertiary); /* 和竖线、字体一样的灰色 */
}

.step-line {
  width: 2px;
  flex: 1; /* 自动填充剩余空间 */
  background: var(--claude-border);
  margin-top: 4px;
  margin-bottom: -14px; /* 延伸到下一个 step-item，保持上下距离 SVG 相等 */
  flex-shrink: 0;
}

/* 最后一个步骤隐藏竖线 */
.step-item:last-child .step-line {
  display: none;
}

.step-content {
  flex: 1;
  min-width: 0;
  padding-top: 2px;
}

.step-header {
  font-size: 12px;
  font-weight: 600;
  color: var(--claude-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin-bottom: 8px;
}

.step-body {
  font-size: 14px;
  color: var(--claude-text-secondary);
  line-height: 1.7;
}

/* 思考内容 */
.thinking-content {
  color: var(--claude-text-secondary);
  font-size: 14px;
  line-height: 1.7;
  white-space: pre-wrap;
  word-wrap: break-word;
  max-height: calc(1.7em * 6); /* 6行 */
  overflow-y: auto;
  margin: 0;
  padding: 0;
  display: block;
  /* 让第一行文字中心和 SVG 中心对齐：向上移动半个行高减去半个字高 */
  margin-top: calc((1em - 1.7em) / 2);
  /* 滚动条样式（参考 git 状态侧边栏文件列表，滚动槽透明贴合灰色底色） */
  scrollbar-width: thin; /* Firefox */
  scrollbar-color: color-mix(in srgb, var(--claude-text-secondary) 55%, transparent)
    transparent;
}

.thinking-content::-webkit-scrollbar {
  width: 10px;
  height: 10px;
}

.thinking-content::-webkit-scrollbar-track {
  background: transparent;
  border-radius: 999px;
  margin: 8px;
}

.thinking-content::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--claude-text-secondary) 55%, transparent);
  border-radius: 999px;
  border: 2px solid transparent;
  background-clip: padding-box;
}

/* 工具内容 */
.step-header {
  font-size: 12px;
  font-weight: 600;
  color: var(--claude-text-tertiary);
  text-transform: uppercase;
  letter-spacing: 0.5px;
  margin: 0 0 8px 0;
  padding: 0;
  line-height: 1;
}
.tool-intent {
  font-weight: 500;
  color: var(--claude-text);
  margin-bottom: 12px;
  font-size: 14px;
  line-height: 1.7;
  /* 让第一行文字紧贴顶部 */
  margin-top: calc((1.7em - 1em) / -2);
}

.tool-result {
  background: var(--claude-panel);
  border: 1px solid var(--claude-border);
  border-radius: 8px;
  padding: 12px;
  font-size: 13px;
  max-height: 200px; /* 约为原来卡片的三分之一 */
  overflow-y: auto;
  /* 隐藏滚动条 */
  scrollbar-width: none; /* Firefox */
  -ms-overflow-style: none; /* IE and Edge */
}

.tool-result::-webkit-scrollbar {
  display: none; /* Chrome, Safari, Opera */
}

.tool-result * {
  /* 隐藏所有子元素的滚动条 */
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.tool-result *::-webkit-scrollbar {
  display: none;
}

.tool-result pre {
  margin: 0;
  white-space: pre-wrap;
  word-wrap: break-word;
  font-family: 'SF Mono', 'Monaco', 'Consolas', monospace;
  font-size: 12px;
  color: var(--claude-text-secondary);
}

.result-item {
  padding: 8px 0;
  border-bottom: 1px solid var(--claude-border);
}

.result-item:last-child {
  border-bottom: none;
}

/* 文本输出 */
.text-output {
  margin: 16px 0;
  padding: 0;
}

@media (max-width: 768px) {
  .text-output {
    margin: 16px -9px;
  }
}

.text-content {
  font-size: 15px;
  line-height: 1.7;
  color: var(--claude-text);
  word-wrap: break-word;
}
</style>
