<script setup>
/**
 * 工作流节点缩略图
 *
 * 保留节点之间的位置关系与连线，节点用纯颜色圆点表示。
 * 用于：WorkflowList 卡片、TemplatePicker、TemplateManagement 列表。
 *
 * 实现要点：
 *   - 通过 parseGraph 将节点坐标规范化到 [0,1]，再映射到 SVG viewBox
 *   - SVG 设置 preserveAspectRatio="xMidYMid meet" 自动保留长宽比
 *   - 节点半径与连线粗细随节点数衰减，避免拥挤
 */
import { computed } from 'vue'
import { parseGraph } from '../../utils/workflowNode'

const props = defineProps({
  graphData: { type: [String, Object], default: '' },
  width: { type: [Number, String], default: '100%' },
  height: { type: [Number, String], default: 64 },
  // SVG 内边距（viewBox 单位）
  padding: { type: Number, default: 8 },
})

// viewBox 固定 100x60；通过 preserveAspectRatio 保留长宽比
const VB_W = 100
const VB_H = 60

const graph = computed(() => parseGraph(props.graphData))

const nodesSvg = computed(() => {
  const pad = props.padding
  return graph.value.nodes.map(n => ({
    ...n,
    sx: pad + n.rx * (VB_W - 2 * pad),
    sy: pad + n.ry * (VB_H - 2 * pad),
  }))
})

const edgesSvg = computed(() => {
  const map = new Map(nodesSvg.value.map(n => [n.id, n]))
  return graph.value.edges
    .map(e => ({
      source: map.get(e.source.id),
      target: map.get(e.target.id),
    }))
    .filter(e => e.source && e.target)
})

// 节点半径：节点数越多越小
const nodeR = computed(() => {
  const n = graph.value.nodes.length
  if (n <= 2) return 4.5
  if (n <= 4) return 3.8
  if (n <= 8) return 3
  return 2.4
})

const edgeWidth = computed(() => {
  const n = graph.value.nodes.length
  return n > 8 ? 0.6 : 0.9
})

const widthStyle = computed(() =>
  typeof props.width === 'number' ? `${props.width}px` : props.width
)
const heightStyle = computed(() =>
  typeof props.height === 'number' ? `${props.height}px` : props.height
)
</script>

<template>
  <div class="node-thumbnail" :style="{ width: widthStyle, height: heightStyle }">
    <svg
      v-if="graph.hasContent"
      :viewBox="`0 0 ${VB_W} ${VB_H}`"
      preserveAspectRatio="xMidYMid meet"
      class="thumb-svg"
    >
      <!-- 连线（先画，避免覆盖节点） -->
      <line
        v-for="(e, i) in edgesSvg"
        :key="`e-${i}`"
        :x1="e.source.sx"
        :y1="e.source.sy"
        :x2="e.target.sx"
        :y2="e.target.sy"
        :stroke-width="edgeWidth"
        stroke="rgba(148, 163, 184, 0.45)"
        stroke-linecap="round"
      />
      <!-- 节点圆点 -->
      <circle
        v-for="(n, i) in nodesSvg"
        :key="`n-${i}`"
        :cx="n.sx"
        :cy="n.sy"
        :r="nodeR"
        :fill="n.color"
      >
        <title>{{ n.label }}</title>
      </circle>
    </svg>
    <div v-else class="empty-thumb">空工作流</div>
  </div>
</template>

<style scoped>
.node-thumbnail {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
}
.thumb-svg {
  width: 100%;
  height: 100%;
  display: block;
}
.empty-thumb {
  font-size: 11px;
  color: var(--text-muted);
  text-align: center;
}
</style>
