<template>
	<div class="compaction-bubble" :class="statusClass">
		<el-icon class="icon">
			<Loading v-if="message.status === 'running'" class="spin" />
			<CircleCheck v-else-if="message.status === 'done'" />
			<CircleClose v-else-if="message.status === 'error'" />
		</el-icon>

		<div class="content">
			<div class="title">
				<template v-if="message.status === 'running'">
					{{ message.reason === 'manual' ? '手动' : '自动' }}压缩进行中... ({{ message.messageCount }} 条消息)
				</template>
				<template v-else-if="message.status === 'done'">
					上下文已压缩 — 压缩 {{ message.compactedCount }} 条 / 保留 {{ message.keepRecentCount }} 条 ·
					{{ formatNum(message.tokensBefore) }} → {{ formatNum(message.tokensAfter) }} tokens
				</template>
				<template v-else>
					压缩失败：{{ message.errorMessage }}
				</template>
			</div>
			<el-button
				v-if="message.status === 'done'"
				size="small"
				link
				@click="showSummary = true"
			>
				查看摘要
			</el-button>
		</div>

		<el-drawer v-model="showSummary" title="压缩摘要" size="40%" direction="rtl">
			<div class="summary-content" v-html="renderedSummary" />
		</el-drawer>
	</div>
</template>

<script setup lang="ts">
// 压缩事件气泡组件 — 展示上下文压缩的进行中/完成/失败三种状态
import { ref, computed } from 'vue';
import { Loading, CircleCheck, CircleClose } from '@element-plus/icons-vue';
import MarkdownIt from 'markdown-it';

const props = defineProps<{
	message: {
		status?: 'running' | 'done' | 'error';
		reason?: 'manual' | 'auto';
		messageCount?: number;
		compactedCount?: number;
		keepRecentCount?: number;
		tokensBefore?: number;
		tokensAfter?: number;
		errorMessage?: string;
		summaryContent?: string;
	};
}>();

const showSummary = ref(false);
const md = new MarkdownIt({ html: false, linkify: false });

// 将摘要内容渲染为 HTML
const renderedSummary = computed(() => md.render(props.message.summaryContent || ''));

// 根据状态动态设置样式类
const statusClass = computed(() => `status-${props.message.status || 'running'}`);

/** 格式化 token 数量，>=1000 显示为 k */
function formatNum(n?: number): string {
	if (!n) return '0';
	if (n >= 1000) return (n / 1000).toFixed(1) + 'k';
	return String(n);
}
</script>

<style scoped>
.compaction-bubble {
	display: flex;
	align-items: center;
	gap: 8px;
	padding: 8px 12px;
	margin: 8px 0;
	border-radius: 6px;
	background: var(--el-fill-color-light);
	font-size: 13px;
	color: var(--el-text-color-regular);
}
.status-error {
	background: var(--el-color-danger-light-9);
	color: var(--el-color-danger);
}
.status-done {
	background: var(--el-color-success-light-9);
}
.icon {
	font-size: 16px;
}
.spin {
	animation: spin 1s linear infinite;
}
@keyframes spin {
	to { transform: rotate(360deg); }
}
.content {
	flex: 1;
	display: flex;
	align-items: center;
	gap: 12px;
}
.summary-content {
	padding: 16px;
	line-height: 1.6;
}
</style>
