<template>
  <div class="messages-area" ref="rootEl">
    <div class="messages-flow">
      <div v-for="(msg, index) in messages" :key="index" class="message-block">
        <div v-if="msg.role === 'user'" class="user-message">
          <div class="message-header icon-label">
            <span class="icon icon-sm" :style="iconStyleSafe('user')" aria-hidden="true"></span>
            <span>用户</span>
          </div>
          <div class="message-text">{{ msg.content }}</div>
        </div>
        <div v-else-if="msg.role === 'assistant'" class="assistant-message">
          <div class="message-header icon-label">
            <span class="icon icon-sm" :style="iconStyleSafe('bot')" aria-hidden="true"></span>
            <span>AI Assistant</span>
          </div>
          <div
            v-if="msg.awaitingFirstContent"
            class="action-item streaming-content immediate-show assistant-generating-block"
          >
            <div class="text-output">
              <div
                class="text-content assistant-generating-placeholder"
                role="status"
                aria-live="polite"
              >
                <span
                  v-for="(letter, letterIndex) in getGeneratingLetters(msg)"
                  :key="letterIndex"
                  class="assistant-generating-letter"
                  :style="{ animationDelay: `${letterIndex * 0.08}s` }"
                >
                  {{ letter }}
                </span>
              </div>
            </div>
          </div>
          <div
            v-for="(action, actionIndex) in msg.actions || []"
            :key="action.id || `${index}-${actionIndex}`"
            class="action-item"
            :class="{
              'streaming-content': action.streaming,
              'completed-tool': action.type === 'tool' && !action.streaming,
              'immediate-show': action.streaming || action.type === 'text'
            }"
          >
            <div
              v-if="action.type === 'thinking'"
              class="collapsible-block thinking-block"
              :class="{ expanded: expandedBlocks?.has(action.blockId || `${index}-thinking-${actionIndex}`) }"
            >
              <div class="collapsible-header" @click="toggleBlock(action.blockId || `${index}-thinking-${actionIndex}`)">
                <div class="arrow"></div>
                <div class="status-icon">
                  <span class="thinking-icon" :class="{ 'thinking-animation': action.streaming }">
                    <span class="icon icon-sm" :style="iconStyleSafe('brain')" aria-hidden="true"></span>
                  </span>
                </div>
                <span class="status-text">{{ action.streaming ? '正在思考...' : '思考过程' }}</span>
              </div>
              <div class="collapsible-content">
                <div
                  class="content-inner thinking-content"
                  :ref="el => registerThinkingRef(action.blockId || `${index}-thinking-${actionIndex}`, el)"
                  @scroll="
                    handleThinkingScroll(
                      action.blockId || `${index}-thinking-${actionIndex}`,
                      $event
                    )
                  "
                  style="max-height: 240px; overflow-y: auto;"
                >
                  {{ action.content }}
                </div>
              </div>
              <div v-if="action.streaming" class="progress-indicator"></div>
            </div>

            <div v-else-if="action.type === 'text'" class="text-output">
              <div class="text-content" :class="{ 'streaming-text': action.streaming }">
                <div v-if="action.streaming" v-html="renderMarkdown(action.content, true)"></div>
                <div v-else v-html="renderMarkdown(action.content, false)"></div>
              </div>
            </div>

            <div v-else-if="action.type === 'system'" class="system-action">
              <div class="system-action-content">
                {{ action.content }}
              </div>
            </div>

            <div
              v-else-if="action.type === 'append_payload'"
              class="append-placeholder"
              :class="{ 'append-error': action.append?.success === false }"
            >
              <div class="append-placeholder-content">
                <template v-if="action.append?.success !== false">
                  <div class="icon-label append-status">
                    <span class="icon icon-sm" :style="iconStyleSafe('pencil')" aria-hidden="true"></span>
                    <span>已写入 {{ action.append?.path || '目标文件' }} 的追加内容（内容已保存至文件）</span>
                  </div>
                </template>
                <template v-else>
                  <div class="icon-label append-status append-error-text">
                    <span class="icon icon-sm" :style="iconStyleSafe('x')" aria-hidden="true"></span>
                    <span>向 {{ action.append?.path || '目标文件' }} 写入失败，内容已截获供后续修复。</span>
                  </div>
                </template>
                <div class="append-meta" v-if="action.append">
                  <span v-if="action.append.lines !== null && action.append.lines !== undefined">
                    · 行数 {{ action.append.lines }}
                  </span>
                  <span v-if="action.append.bytes !== null && action.append.bytes !== undefined">
                    · 字节 {{ action.append.bytes }}
                  </span>
                </div>
                <div class="append-warning icon-label" v-if="action.append?.forced">
                  <span class="icon icon-sm" :style="iconStyleSafe('triangleAlert')" aria-hidden="true"></span>
                  <span>未检测到结束标记，请根据提示继续补充。</span>
                </div>
              </div>
            </div>

            <div
              v-else-if="action.type === 'append'"
              class="append-placeholder"
              :class="{ 'append-error': action.append?.success === false }"
            >
              <div class="append-placeholder-content">
                <div class="icon-label append-status">
                  <span class="icon icon-sm" :style="iconStyleSafe('pencil')" aria-hidden="true"></span>
                  <span>{{ action.append?.summary || '文件追加完成' }}</span>
                </div>
                <div class="append-meta" v-if="action.append">
                  <span>{{ action.append.path || '目标文件' }}</span>
                  <span v-if="action.append.lines">· 行数 {{ action.append.lines }}</span>
                  <span v-if="action.append.bytes">· 字节 {{ action.append.bytes }}</span>
                </div>
                <div class="append-warning icon-label" v-if="action.append?.forced">
                  <span class="icon icon-sm" :style="iconStyleSafe('triangleAlert')" aria-hidden="true"></span>
                  <span>未检测到结束标记，请按提示继续补充。</span>
                </div>
              </div>
            </div>

            <ToolAction
              v-else-if="action.type === 'tool'"
              :action="action"
              :expanded="expandedBlocks?.has(action.blockId || `${index}-tool-${actionIndex}`)"
              :icon-style="iconStyleSafe"
              :get-tool-animation-class="getToolAnimationClass"
              :get-tool-icon="getToolIcon"
              :get-tool-status-text="getToolStatusText"
              :get-tool-description="getToolDescription"
              :format-search-topic="formatSearchTopic"
              :format-search-time="formatSearchTime"
              :streaming-message="streamingMessage"
              @toggle="toggleBlock(action.blockId || `${index}-tool-${actionIndex}`)"
            />
          </div>
        </div>
        <div v-else class="system-message">
          <div class="collapsible-block system-block" :class="{ expanded: expandedBlocks?.has(`system-${index}`) }">
            <div class="collapsible-header" @click="toggleBlock(`system-${index}`)">
              <div class="arrow"></div>
              <div class="status-icon">
                <span class="tool-icon icon icon-md" :style="iconStyleSafe('info')" aria-hidden="true"></span>
              </div>
              <span class="status-text">系统消息</span>
            </div>
            <div class="collapsible-content">
              <div class="content-inner">
                {{ msg.content }}
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import ToolAction from '@/components/chat/actions/ToolAction.vue';

const props = defineProps<{
  messages: Array<any>;
  iconStyle: (key: string, size?: string) => Record<string, string>;
  expandedBlocks: Set<string>;
  streamingMessage: boolean;
  toggleBlock: (blockId: string) => void;
  handleThinkingScroll: (blockId: string, event: Event) => void;
  renderMarkdown: (content: string, isStreaming: boolean) => string;
  getToolIcon: (tool: any) => string;
  getToolStatusText: (tool: any) => string;
  getToolAnimationClass: (tool: any) => string | Record<string, unknown>;
  getToolDescription: (tool: any) => string;
  formatSearchTopic: (filters: Record<string, any>) => string;
  formatSearchTime: (filters: Record<string, any>) => string;
}>();

const DEFAULT_GENERATING_TEXT = '生成中…';
const rootEl = ref<HTMLElement | null>(null);
const thinkingRefs = new Map<string, HTMLElement | null>();

function registerThinkingRef(key: string, el: Element | null) {
  if (el instanceof HTMLElement) {
    thinkingRefs.set(key, el);
  } else {
    thinkingRefs.delete(key);
  }
}

function getThinkingRef(key: string) {
  return thinkingRefs.get(key) || null;
}

function iconStyleSafe(key: string, size?: string) {
  if (typeof props.iconStyle === 'function') {
    return props.iconStyle(key, size);
  }
  return {};
}

function getGeneratingLetters(message: any) {
  const label =
    typeof message?.generatingLabel === 'string' && message.generatingLabel.trim()
      ? message.generatingLabel.trim()
      : DEFAULT_GENERATING_TEXT;
  return Array.from(label);
}

defineExpose({
  rootEl,
  getThinkingRef
});
</script>
