<template>
	<div class="detection-result">
		<!-- 顶部操作栏 -->
		<div class="detection-result__header">
			<div class="header-left">
				<el-button :icon="ArrowLeft" @click="goBack">返回</el-button>
				<h3 v-if="summary">汽车旧伤检测报告</h3>
			</div>
			<div class="header-right">
				<el-input
					v-model="taskIdInput"
					placeholder="输入 taskId 查看报告"
					clearable
					style="width: 280px"
					@keyup.enter="loadReport"
				>
					<template #prefix>
						<el-icon><Search /></el-icon>
					</template>
					<template #append>
						<el-button @click="loadReport" :loading="loading">
							查看
						</el-button>
					</template>
				</el-input>
				<el-button
					v-if="taskId"
					type="primary"
					link
					@click="openHtmlReport"
				>
					查看原始HTML报告
				</el-button>
			</div>
		</div>

		<!-- 加载中 -->
		<div v-if="loading" class="loading-wrap">
			<el-icon class="is-loading" :size="32"><Loading /></el-icon>
			<p>加载检测报告...</p>
		</div>

		<!-- 空状态 -->
		<el-empty
			v-else-if="!summary"
			description="请输入 taskId 查看检测报告"
			:image-size="120"
		/>

		<!-- 报告内容 -->
		<el-scrollbar v-else class="detection-result__content">
			<div class="report-body">
				<!-- 统计卡片 -->
				<div class="stat-grid">
					<div class="stat-card">
						<div class="stat-value score">
							{{ summary.conditionScore || 'N/A' }}
						</div>
						<div class="stat-label">车况评分/10</div>
					</div>
					<div class="stat-card">
						<div class="stat-value orange">
							{{ summary.totalDamages || 0 }}
						</div>
						<div class="stat-label">发现损伤</div>
					</div>
					<div class="stat-card">
						<div class="stat-value blue">
							{{ totalMarkedFrames }}
						</div>
						<div class="stat-label">标注帧数</div>
					</div>
					<div class="stat-card">
						<div class="stat-value">
							{{ summary.videoInfo?.extractedFrames || 0 }}
						</div>
						<div class="stat-label">分析帧数</div>
					</div>
				</div>

				<!-- 视频信息 -->
				<div class="section" v-if="summary.videoInfo">
					<h3>视频信息</h3>
					<div class="video-info-grid">
						<div class="info-item">
							<div class="info-val">
								{{ (summary.videoInfo.duration || 0).toFixed(1) }}s
							</div>
							<div class="info-lbl">时长</div>
						</div>
						<div class="info-item">
							<div class="info-val">
								{{ summary.videoInfo.resolution || '-' }}
							</div>
							<div class="info-lbl">分辨率</div>
						</div>
						<div class="info-item">
							<div class="info-val">
								{{ (summary.videoInfo.videoFps || 0).toFixed(1) }}
							</div>
							<div class="info-lbl">原始FPS</div>
						</div>
						<div class="info-item">
							<div class="info-val">
								{{ summary.videoInfo.extractedFrames || 0 }}
							</div>
							<div class="info-lbl">抽取帧</div>
						</div>
					</div>
				</div>

				<!-- 整体评估 -->
				<div class="section" v-if="summary.assessment">
					<h3>整体评估</h3>
					<div class="assessment-box">{{ summary.assessment }}</div>
				</div>

				<!-- 损伤汇总表 -->
				<div class="section" v-if="damagesSummary.length > 0">
					<h3>损伤汇总表</h3>
					<el-table :data="damagesSummary" stripe border size="small">
						<el-table-column prop="id" label="#" width="50" />
						<el-table-column prop="location" label="位置" width="100" />
						<el-table-column prop="type" label="类型" width="100" />
						<el-table-column prop="severity" label="程度" width="80">
							<template #default="{ row }">
								<el-tag
									:type="severityTagType(row.severity)"
									size="small"
								>
									{{ row.severity }}
								</el-tag>
							</template>
						</el-table-column>
						<el-table-column
							prop="time_range"
							label="时间"
							width="100"
						/>
						<el-table-column prop="description" label="描述" />
					</el-table>
				</div>

				<!-- 损伤详情 -->
				<div class="section" v-if="groundingResults.length > 0">
					<h3>损伤详情与多帧定位标注</h3>
					<div
						class="damage-card"
						v-for="gr in groundingResults"
						:key="gr.damageId"
					>
						<div class="damage-header">
							<span class="damage-id">#{{ gr.damageId }}</span>
							<el-tag
								:type="severityTagType(gr.severity)"
								size="small"
							>
								{{ gr.severity || '未知' }}
							</el-tag>
							<span class="damage-location">{{
								gr.location
							}}</span>
							<span class="damage-type">{{ gr.type }}</span>
							<span class="damage-time">
								{{ (gr.timeSecond || 0).toFixed(1) }}s
							</span>
							<el-tag type="info" size="small">
								{{ (gr.markedFrames || []).length }}帧
							</el-tag>
						</div>
						<div class="damage-desc" v-if="gr.description">
							{{ gr.description }}
						</div>

						<!-- 最佳帧 -->
						<div
							class="best-section"
							v-if="getBestFrames(gr).length > 0"
						>
							<div class="best-label">
								★ 最佳展示帧 ({{ getBestFrames(gr).length }}张)
								<span v-if="gr.bestSelectionReason">
									- {{ gr.bestSelectionReason }}
								</span>
							</div>
							<div class="frames-gallery">
								<div
									class="frame-pair best"
									v-for="(mf, idx) in getBestFrames(gr)"
									:key="idx"
								>
									<div class="frame-time">
										{{ mf.frameTimestamp.toFixed(2) }}s
										★最佳
									</div>
									<div class="frame-images">
										<el-image
											:src="getFrameUrl(mf.frameRelativePath || mf.framePath)"
											fit="contain"
											:preview-src-list="[
												getFrameUrl(mf.frameRelativePath || mf.framePath)
											]"
										>
											<template #placeholder>
												<div class="img-placeholder">
													原图
												</div>
											</template>
										</el-image>
										<el-image
											:src="getFrameUrl(mf.markedRelativePath || mf.markedPath)"
											fit="contain"
											:class="{ 'has-box': mf.bboxes?.length > 0 }"
											:preview-src-list="[
												getFrameUrl(mf.markedRelativePath || mf.markedPath)
											]"
										>
											<template #placeholder>
												<div class="img-placeholder">
													标注
												</div>
											</template>
										</el-image>
									</div>
								</div>
							</div>
						</div>

						<!-- 其他帧 -->
						<el-collapse
							v-if="getOtherFrames(gr).length > 0"
							class="other-collapse"
						>
							<el-collapse-item>
								<template #title>
									其他参考帧
									({{ getOtherFrames(gr).length }}张) -
									点击展开
								</template>
								<div class="frames-gallery">
									<div
										class="frame-pair"
										v-for="(mf, idx) in getOtherFrames(gr)"
										:key="idx"
									>
										<div class="frame-time">
											{{ mf.frameTimestamp.toFixed(2) }}s
											{{
												mf.bboxes?.length > 0
													? '✓'
													: '○'
											}}
										</div>
										<div class="frame-images">
											<el-image
												:src="getFrameUrl(mf.frameRelativePath || mf.framePath)"
												fit="contain"
												:preview-src-list="[
													getFrameUrl(mf.frameRelativePath || mf.framePath)
												]"
											>
												<template #placeholder>
													<div class="img-placeholder">
														原图
													</div>
												</template>
											</el-image>
											<el-image
												:src="getFrameUrl(mf.markedRelativePath || mf.markedPath)"
												fit="contain"
												:class="{ 'has-box': mf.bboxes?.length > 0 }"
												:preview-src-list="[
													getFrameUrl(mf.markedRelativePath || mf.markedPath)
												]"
											>
												<template #placeholder>
													<div
														class="img-placeholder"
													>
														标注
													</div>
												</template>
											</el-image>
										</div>
									</div>
								</div>
							</el-collapse-item>
						</el-collapse>
					</div>
				</div>

				<!-- 处理建议 -->
				<div
					class="section"
					v-if="
						summary.summary?.recommendations &&
						summary.summary.recommendations.length > 0
					"
				>
					<h3>处理建议</h3>
					<ol class="recommendations">
						<li
							v-for="(rec, idx) in summary.summary.recommendations"
							:key="idx"
						>
							{{ rec }}
						</li>
					</ol>
				</div>

				<!-- 报告时间 -->
				<div class="report-footer">
					汽车旧伤检测报告 | AI Agent Swarm |
					{{ summary.reportTime }}
				</div>
			</div>
		</el-scrollbar>
	</div>
</template>

<script lang="ts" setup>
defineOptions({
	name: 'detection-result'
});

import { ref, computed, onMounted } from 'vue';
import { useRoute, useRouter } from 'vue-router';
import { ArrowLeft, Search, Loading } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';
import { config } from '/@/config';

const route = useRoute();
const router = useRouter();

const loading = ref(false);
const taskId = ref('');
const taskIdInput = ref('');
const summary = ref<any>(null);
const groundingResults = ref<any[]>([]);

// 从 grounding 数据计算总标注帧数
const totalMarkedFrames = computed(() => {
	return groundingResults.value.reduce(
		(sum: number, d: any) => sum + (d.markedFrames || []).length,
		0
	);
});

// 损伤汇总表数据
const damagesSummary = computed(() => {
	return summary.value?.summary?.damages_summary || [];
});

// 严重程度对应的 tag 类型
function severityTagType(
	severity: string
): 'danger' | 'warning' | 'success' | 'info' {
	switch (severity) {
		case '严重':
			return 'danger';
		case '中等':
			return 'warning';
		case '轻微':
			return 'success';
		default:
			return 'info';
	}
}

// 获取最佳帧
function getBestFrames(gr: any): any[] {
	return (gr.markedFrames || []).filter((mf: any) => mf.isBest);
}

// 获取非最佳帧
function getOtherFrames(gr: any): any[] {
	return (gr.markedFrames || []).filter((mf: any) => !mf.isBest);
}

// 通过 workspace API 获取帧图片 URL
function getFrameUrl(relativePath: string): string {
	if (!relativePath || !taskId.value) return '';
	// 如果是绝对路径，提取相对路径部分
	const cleanPath = relativePath.replace(/\\/g, '/');
	const parts = cleanPath.split('/');
	// 取最后两段路径，如 frames/xxx.jpg 或 marked_frames/xxx.jpg
	let path = cleanPath;
	const framesIdx = parts.findIndex(
		(p) => p === 'frames' || p === 'marked_frames'
	);
	if (framesIdx >= 0) {
		path = parts.slice(framesIdx).join('/');
	}
	return `${config.baseUrl}/open/agent/workspace/file?taskId=${taskId.value}&path=${encodeURIComponent(path)}`;
}

// 打开原始 HTML 报告
function openHtmlReport() {
	if (!taskId.value) return;
	const url = `${config.baseUrl}/open/agent/workspace/file?taskId=${taskId.value}&path=report.html`;
	window.open(url, '_blank');
}

// 加载报告数据
async function loadReport() {
	const tid = taskIdInput.value.trim();
	if (!tid) {
		ElMessage.warning('请输入 taskId');
		return;
	}

	loading.value = true;
	summary.value = null;
	groundingResults.value = [];
	taskId.value = tid;

	try {
		// 并行加载 summary.json 和 grounding.json
		const [summaryResp, groundingResp] = await Promise.all([
			fetch(
				`${config.baseUrl}/open/agent/workspace/file?taskId=${tid}&path=summary.json`
			),
			fetch(
				`${config.baseUrl}/open/agent/workspace/file?taskId=${tid}&path=grounding.json`
			)
		]);

		if (!summaryResp.ok) {
			ElMessage.error('未找到该 taskId 的检测报告');
			taskId.value = '';
			return;
		}

		const summaryData = await summaryResp.json();
		summary.value = summaryData;

		if (groundingResp.ok) {
			const groundingData = await groundingResp.json();
			groundingResults.value = groundingData.groundingResults || [];
		}
	} catch {
		ElMessage.error('加载报告失败');
		taskId.value = '';
	} finally {
		loading.value = false;
	}
}

// 返回上一页
function goBack() {
	router.back();
}

// 如果 URL 中有 taskId 参数，自动加载
onMounted(() => {
	const tid = (route.query.taskId as string) || '';
	if (tid) {
		taskIdInput.value = tid;
		loadReport();
	}
});
</script>

<style lang="scss" scoped>
.detection-result {
	height: 100%;
	display: flex;
	flex-direction: column;
	background-color: var(--el-bg-color-page);

	&__header {
		display: flex;
		align-items: center;
		justify-content: space-between;
		padding: 12px 20px;
		background-color: var(--el-bg-color);
		border-bottom: 1px solid var(--el-border-color-lighter);

		.header-left {
			display: flex;
			align-items: center;
			gap: 12px;

			h3 {
				margin: 0;
				font-size: 16px;
			}
		}

		.header-right {
			display: flex;
			align-items: center;
			gap: 12px;
		}
	}

	&__content {
		flex: 1;
		padding: 20px;
	}
}

.loading-wrap {
	display: flex;
	flex-direction: column;
	align-items: center;
	justify-content: center;
	gap: 12px;
	padding: 80px 0;
	color: var(--el-text-color-secondary);
}

.report-body {
	max-width: 1200px;
	margin: 0 auto;
}

/* 统计卡片 */
.stat-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
	gap: 16px;
	margin-bottom: 20px;
}

.stat-card {
	background: var(--el-bg-color);
	padding: 20px;
	border-radius: 12px;
	text-align: center;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.stat-value {
	font-size: 32px;
	font-weight: 700;
	color: var(--el-text-color-primary);

	&.score {
		color: var(--el-color-danger);
	}
	&.orange {
		color: var(--el-color-warning);
	}
	&.blue {
		color: var(--el-color-primary);
	}
}

.stat-label {
	font-size: 13px;
	color: var(--el-text-color-secondary);
	margin-top: 4px;
}

/* 通用分区 */
.section {
	background: var(--el-bg-color);
	padding: 20px;
	border-radius: 12px;
	box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
	margin-bottom: 20px;

	h3 {
		font-size: 16px;
		margin: 0 0 14px 0;
		padding-bottom: 10px;
		border-bottom: 2px solid var(--el-border-color-lighter);
	}
}

/* 视频信息 */
.video-info-grid {
	display: grid;
	grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
	gap: 10px;
}

.info-item {
	text-align: center;
	padding: 10px;
	background: var(--el-fill-color-lighter);
	border-radius: 8px;
}

.info-val {
	font-size: 16px;
	font-weight: 600;
}

.info-lbl {
	font-size: 11px;
	color: var(--el-text-color-secondary);
	margin-top: 2px;
}

/* 整体评估 */
.assessment-box {
	padding: 16px;
	background: var(--el-fill-color-lighter);
	border-radius: 8px;
	border-left: 4px solid var(--el-color-primary);
	line-height: 1.8;
}

/* 损伤卡片 */
.damage-card {
	border: 1px solid var(--el-border-color-lighter);
	border-radius: 12px;
	padding: 20px;
	margin-bottom: 16px;
}

.damage-header {
	display: flex;
	align-items: center;
	gap: 10px;
	flex-wrap: wrap;
	margin-bottom: 10px;
}

.damage-id {
	font-size: 18px;
	font-weight: 700;
	color: var(--el-color-danger);
}

.damage-location {
	font-weight: 600;
}

.damage-type,
.damage-time {
	color: var(--el-text-color-secondary);
	font-size: 13px;
}

.damage-desc {
	color: var(--el-text-color-secondary);
	font-size: 13px;
	padding: 10px;
	background: var(--el-fill-color-lighter);
	border-radius: 6px;
	margin-bottom: 14px;
}

/* 最佳帧 */
.best-section {
	margin-bottom: 12px;
}

.best-label {
	font-size: 14px;
	font-weight: 600;
	color: var(--el-color-danger);
	margin-bottom: 10px;
	padding: 8px 12px;
	background: var(--el-color-danger-light-9);
	border-radius: 6px;
	border-left: 4px solid var(--el-color-danger);
}

/* 帧画廊 */
.frames-gallery {
	display: flex;
	flex-wrap: wrap;
	gap: 12px;
}

.frame-pair {
	background: var(--el-fill-color-lighter);
	border-radius: 8px;
	padding: 10px;
	min-width: 260px;
	flex: 1;
	max-width: 340px;

	&.best {
		background: var(--el-color-danger-light-9);
		border: 2px solid var(--el-color-danger);
	}
}

.frame-time {
	font-size: 12px;
	color: var(--el-text-color-secondary);
	margin-bottom: 6px;
	font-weight: 500;

	.best & {
		color: var(--el-color-danger);
		font-weight: 600;
	}
}

.frame-images {
	display: flex;
	gap: 6px;

	:deep(.el-image) {
		width: 48%;
		border-radius: 6px;
		border: 2px solid var(--el-border-color-lighter);
		overflow: hidden;

		&.has-box {
			border-color: var(--el-color-danger);
		}
	}
}

.img-placeholder {
	display: flex;
	align-items: center;
	justify-content: center;
	height: 80px;
	color: var(--el-text-color-placeholder);
	font-size: 12px;
	background: var(--el-fill-color);
}

/* 其他帧折叠 */
.other-collapse {
	margin-top: 8px;

	:deep(.el-collapse-item__header) {
		font-size: 13px;
		color: var(--el-text-color-secondary);
	}
}

/* 处理建议 */
.recommendations {
	padding-left: 20px;

	li {
		padding: 6px 0;
		border-bottom: 1px solid var(--el-border-color-extra-light);
		line-height: 1.6;

		&:last-child {
			border-bottom: none;
		}
	}
}

/* 页脚 */
.report-footer {
	text-align: center;
	padding: 20px;
	color: var(--el-text-color-placeholder);
	font-size: 12px;
}
</style>
