<script setup lang="ts">
import type {
  ChatTimeAssistantSegment,
  ChatTimeAssistantTextSegment,
  ChatTimeTimelineItem,
} from '@easyflow/types';

import {computed, ref} from 'vue';

import {ChatThinkingBlock, ChatTimeMarkdown} from '@easyflow/common-ui';
import {IconifyIcon} from '@easyflow/icons';

import {CircleCheck} from '@element-plus/icons-vue';
import {ElIcon} from 'element-plus';

import ShowJson from '#/components/json/ShowJson.vue';

interface Props {
  item: ChatTimeTimelineItem;
  readonlyThinking?: boolean;
}

const props = withDefaults(defineProps<Props>(), {
  readonlyThinking: false,
});
const toolExpanded = ref(false);

const renderableSegments = computed(() => {
  if (props.item.role !== 'assistant') {
    return [] as ChatTimeAssistantSegment[];
  }
  if (props.item.segments.length > 0) {
    const textSegments = props.item.segments.filter(
      (segment): segment is ChatTimeAssistantTextSegment =>
        segment.type === 'text',
    );
    if (textSegments.length <= 1) {
      return props.item.segments;
    }
    const mergedTextSegment: ChatTimeAssistantTextSegment = {
      content: textSegments.map((segment) => segment.content).join(''),
      id: `${props.item.id}-merged-text`,
      type: 'text',
    };
    return [
      ...props.item.segments.filter((segment) => segment.type !== 'text'),
      mergedTextSegment,
    ];
  }
  if (!props.item.content) {
    return [] as ChatTimeAssistantSegment[];
  }
  return [
    {
      content: props.item.content,
      id: `${props.item.id}-fallback-text`,
      type: 'text' as const,
    },
  ] satisfies ChatTimeAssistantSegment[];
});

function getToolName() {
  if (props.item.role !== 'tool') {
    return '';
  }
  return props.item.name || '工具调用';
}

const hasToolDetails = computed(() => {
  return props.item.role === 'tool' && Boolean(props.item.arguments || props.item.result);
});

function toggleToolExpanded() {
  if (!hasToolDetails.value) {
    return;
  }
  toolExpanded.value = !toolExpanded.value;
}
</script>

<template>
  <template v-if="item.role === 'assistant'">
    <div class="flex flex-col gap-2">
      <template v-for="segment in renderableSegments" :key="segment.id">
        <ChatThinkingBlock
          v-if="segment.type === 'thinking'"
          v-model:expanded="segment.expanded"
          :content="segment.content"
          :readonly="readonlyThinking"
          :status="segment.status"
          class="chat-thinking-block-item"
        />
        <ChatTimeMarkdown
          v-else
          :content="segment.content"
          :streaming="item.typing"
        />
      </template>
    </div>
  </template>

  <template v-else-if="item.role === 'tool'">
    <div class="chat-tool-panel" :class="{ 'is-expanded': toolExpanded }">
      <button
        type="button"
        class="chat-tool-header"
        :class="{ 'is-clickable': hasToolDetails }"
        @click="toggleToolExpanded"
      >
        <div class="chat-tool-title">
          <ElIcon size="14">
            <IconifyIcon icon="svg:wrench" />
          </ElIcon>
          <span class="chat-tool-title-text">{{ getToolName() }}</span>
        </div>
        <div class="chat-tool-meta">
          <span
            class="chat-tool-status"
            :class="item.status === 'TOOL_CALL' ? 'is-calling' : 'is-done'"
          >
            <ElIcon size="13">
              <IconifyIcon
                v-if="item.status === 'TOOL_CALL'"
                icon="mdi:clock-time-five-outline"
              />
              <CircleCheck v-else />
            </ElIcon>
            <span>{{ item.status === 'TOOL_CALL' ? '调用中' : '已完成' }}</span>
          </span>
          <ElIcon
            v-if="hasToolDetails"
            size="14"
            class="chat-tool-arrow"
            :class="{ 'is-expanded': toolExpanded }"
          >
            <IconifyIcon icon="ep:arrow-right" />
          </ElIcon>
        </div>
      </button>
      <div v-if="toolExpanded && hasToolDetails" class="chat-tool-body">
        <ShowJson v-if="item.arguments" :value="item.arguments" plain />
        <ShowJson v-if="item.result" :value="item.result" plain />
      </div>
    </div>
  </template>

  <ChatTimeMarkdown v-else :content="item.content" :streaming="item.typing" />
</template>

<style scoped>
.chat-thinking-block-item {
  margin-bottom: 0;
}

.chat-tool-panel {
  min-width: 0;
  background: hsl(var(--surface-panel) / 0.98);
  border: 1px solid hsl(var(--divider-faint) / 0.16);
  border-radius: 10px;
  box-shadow: none;
}

.chat-tool-header {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  min-height: 34px;
  padding: 0 10px;
  text-align: left;
  background: transparent;
  border: none;
}

.chat-tool-header.is-clickable {
  cursor: pointer;
}

.chat-tool-title {
  display: inline-flex;
  gap: 6px;
  align-items: center;
  min-width: 0;
  color: hsl(var(--text-strong));
}

.chat-tool-title-text {
  overflow: hidden;
  font-size: 12px;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.chat-tool-meta {
  display: inline-flex;
  flex-shrink: 0;
  gap: 6px;
  align-items: center;
}

.chat-tool-status {
  display: inline-flex;
  flex-shrink: 0;
  gap: 4px;
  align-items: center;
  padding: 1px 8px;
  font-size: 11px;
  line-height: 1.4;
  border: 1px solid transparent;
  border-radius: 999px;
}

.chat-tool-status.is-calling {
  color: hsl(var(--primary));
  background: hsl(var(--primary) / 0.08);
  border-color: hsl(var(--primary) / 0.12);
}

.chat-tool-status.is-done {
  color: hsl(var(--success));
  background: hsl(var(--success) / 0.08);
  border-color: hsl(var(--success) / 0.12);
}

.chat-tool-arrow {
  color: hsl(var(--text-muted));
  transition: transform 0.15s ease;
}

.chat-tool-arrow.is-expanded {
  transform: rotate(90deg);
}

.chat-tool-body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 0 10px 10px;
}
</style>
