<template>
  <section class="model-result-viewer">
    <header class="result-viewer-toolbar">
      <div>
        <strong>{{ result.input_name }}</strong>
        <span>{{ modelTypeLabel(String(result.prediction?.model_type || result.modality)) }} · {{ result.model_version }}</span>
      </div>
      <div class="result-layer-controls">
        <el-checkbox v-model="showPrediction">预测结果</el-checkbox>
        <el-checkbox v-model="showGroundTruth">标注真值</el-checkbox>
        <el-tooltip content="适应窗口" placement="bottom"><el-button :icon="FullScreen" circle size="small" /></el-tooltip>
      </div>
    </header>

    <PointCloudViewer v-if="viewer === 'pointcloud-3d'" :points="pointCloudPoints" />

    <div v-else-if="viewer === 'thermal-map'" class="thermal-result-canvas">
      <div class="thermal-equipment"><span></span><span></span><span></span><i></i></div>
      <button
        v-for="(spot, index) in hotspots"
        v-show="showPrediction"
        :key="index"
        class="thermal-hotspot"
        :style="{ left: `${spot.x}%`, top: `${spot.y}%` }"
      >
        <i></i><strong>{{ spot.temperature_c }}°C</strong><small>{{ spot.severity === 'high' ? '高温热点' : '温升区域' }}</small>
      </button>
      <div class="thermal-scale"><span>92°C</span><i></i><span>24°C</span></div>
    </div>

    <div v-else-if="viewer === 'raster-difference'" class="raster-result-canvas">
      <div class="raster-grid"></div>
      <div class="rail-corridor"></div>
      <div
        v-for="(region, index) in regions"
        v-show="showPrediction"
        :key="index"
        class="change-region"
        :style="{ left: `${region.x}%`, top: `${region.y}%`, width: `${region.width}%`, height: `${region.height}%` }"
      ><span>变化 {{ Math.round(Number(region.change) * 100) }}%</span></div>
      <div class="raster-legend"><i></i>变化区域 <span>基线 {{ String(result.artifacts?.baseline_date || '-') }}</span></div>
    </div>

    <div v-else class="image-result-canvas" :class="`modality-${result.modality}`">
      <img v-if="result.preview_url && ['image', 'thermal'].includes(result.modality)" :src="result.preview_url" alt="上传测试样本" />
      <div v-else class="synthetic-rail-scene">
        <div class="scene-sky"></div><div class="scene-ground"></div><div class="scene-rail rail-left"></div><div class="scene-rail rail-right"></div><div class="scene-catenary"></div>
      </div>
      <template v-if="showPrediction && viewer === 'image-overlay'">
        <button
          v-for="(box, index) in boxes"
          :key="index"
          class="prediction-box"
          :style="{ left: `${box.x}%`, top: `${box.y}%`, width: `${box.width}%`, height: `${box.height}%` }"
        ><span>{{ box.label }} {{ Math.round(Number(box.confidence) * 100) }}%</span></button>
      </template>
      <svg v-if="showPrediction && viewer === 'mask-overlay'" class="mask-layer" viewBox="0 0 100 100" preserveAspectRatio="none">
        <polygon v-for="(polygon, index) in polygons" :key="index" :points="polygonText(polygon.points)" />
      </svg>
      <div v-if="showGroundTruth" class="ground-truth-box"><span>标注真值</span></div>
    </div>

    <footer class="result-viewer-footer">
      <span>查看器：{{ viewerLabel }}</span>
      <span>结果 {{ Number(result.prediction?.result_count || 0) }} 项</span>
      <span>总耗时 {{ result.timings?.total_ms || 0 }} ms</span>
    </footer>
  </section>
</template>

<script setup lang="ts">
import { computed, defineAsyncComponent, ref } from "vue";
import { FullScreen } from "@element-plus/icons-vue";
import { modelTypeLabel, type JsonMap, type TestResult } from "../../types/model-management";

const PointCloudViewer = defineAsyncComponent(() => import("./PointCloudViewer.vue"));

const props = defineProps<{ result: TestResult }>();
const showPrediction = ref(true);
const showGroundTruth = ref(false);
const viewer = computed(() => String(props.result.artifacts?.viewer || "image-overlay"));
const boxes = computed(() => (props.result.artifacts?.boxes as JsonMap[] | undefined) || []);
const polygons = computed(() => (props.result.artifacts?.polygons as JsonMap[] | undefined) || []);
const hotspots = computed(() => (props.result.artifacts?.hotspots as JsonMap[] | undefined) || []);
const regions = computed(() => (props.result.artifacts?.regions as JsonMap[] | undefined) || []);
const pointCloudPoints = computed(() => (props.result.artifacts?.points as Array<{ x: number; y: number; z: number; value?: number }> | undefined) || []);
const viewerLabel = computed(() => ({
  "image-overlay": "目标叠加", "mask-overlay": "掩码叠加", "thermal-map": "温度热力",
  "pointcloud-3d": "三维点云", "raster-difference": "栅格差分"
} as Record<string, string>)[viewer.value] || viewer.value);

function polygonText(value: unknown) {
  if (!Array.isArray(value)) return "";
  return value.map((point) => Array.isArray(point) ? point.join(",") : "").join(" ");
}
</script>
