<script setup lang="ts">
import { watch, ref, onMounted } from 'vue'
import { VueFlow, useVueFlow } from '@vue-flow/core'
import { Background } from '@vue-flow/background'
import { Controls } from '@vue-flow/controls'
import '@vue-flow/core/dist/style.css'
import '@vue-flow/controls/dist/style.css'
import '@vue-flow/core/dist/theme-default.css'
import type { Node, Edge, Connection } from '@vue-flow/core'

const props = defineProps<{
  sceneNodes: { id: string; label: string }[]
  sceneEdges: { id: string; source: string; target: string; label?: string }[]
  startScene: string
  selectedNodeId: string | null
}>()

const emit = defineEmits<{
  selectNode: [id: string]
  addNode: []
  addEdge: [source: string, target: string]
}>()

const { nodes, edges, onNodeClick, onConnect, fitView } = useVueFlow()

function rebuild() {
  nodes.value = props.sceneNodes.map((n, i) => ({
    id: n.id,
    type: 'default',
    position: { x: (i % 4) * 220 + 50, y: Math.floor(i / 4) * 120 + 50 },
    data: { label: n.id === props.startScene ? `▶ ${n.label}` : n.label },
    style: n.id === props.startScene
      ? 'background:#1b5e20; color:#fff; border-color:#388e3c'
      : n.id === props.selectedNodeId
        ? 'background:#1565c0; color:#fff; border-color:#1976d2'
        : '',
    sourcePosition: 'right' as const,
    targetPosition: 'left' as const,
    connectable: true,
  }))

  edges.value = props.sceneEdges.map((e) => ({
    id: e.id,
    source: e.source,
    target: e.target,
    label: e.label || '',
    animated: true,
    style: { stroke: '#4fc3f7' },
    labelStyle: { fill: '#aaa', fontWeight: 400, fontSize: 11 },
    labelBgStyle: { fill: 'rgba(0,0,0,0.7)' },
  }))
}

watch(() => [props.sceneNodes, props.sceneEdges, props.startScene, props.selectedNodeId], () => {
  rebuild()
}, { deep: true, immediate: true })

onNodeClick((event) => {
  emit('selectNode', event.node.id)
})

onConnect((connection: Connection) => {
  if (connection.source && connection.target) {
    emit('addEdge', connection.source, connection.target)
  }
})

onMounted(() => {
  setTimeout(() => fitView({ padding: 0.2 }), 100)
})
</script>

<template>
  <div class="scene-graph">
    <VueFlow
      :nodes="nodes"
      :edges="edges"
      :min-zoom="0.2"
      :max-zoom="2"
    >
      <Background :gap="20" />
      <Controls />
    </VueFlow>
  </div>
</template>

<style scoped>
.scene-graph {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: #0d0d1a;
}
</style>
