<template>
  <div ref="graphContainerRef" class="mxgraph-container"></div>
</template>

<script setup lang="ts">
import { myMxGraph, myMxRubberband, myMxConstants, myMxEvent, myMxPopupMenu } from '@/graph/mxGraph'
const graphContainerRef = ref<HTMLElement | null>(null)
const graphInstance = ref<InstanceType<typeof myMxGraph> | null>(null)
provide('mxgraph-instance', graphInstance)

function initGraph(container: HTMLElement): InstanceType<typeof myMxGraph> {
  const graph = new myMxGraph(container)

  // 基本配置
  graph.setPanning(true)
  graph.setConnectable(true)
  new myMxRubberband(graph)

  // 配置样式
  configureStyles(graph)

  // 设置事件监听
  setupGraphListeners(graph)

  // 添加上下文菜单
  setupContextMenu(graph)

  // 初始示例图形
  createSampleGraph(graph)

  return graph
}

function configureStyles(graph: InstanceType<typeof myMxGraph>) {
  const style = graph.getStylesheet().getDefaultVertexStyle()
  Object.assign(style, {
    [myMxConstants.STYLE_SHAPE]: myMxConstants.SHAPE_RECTANGLE,
    [myMxConstants.STYLE_STROKECOLOR]: '#2d8cf0',
    [myMxConstants.STYLE_FILLCOLOR]: '#ffffff',
    [myMxConstants.STYLE_FONTCOLOR]: '#333333',
    [myMxConstants.STYLE_STROKEWIDTH]: 2
  })

  const edgeStyle = graph.getStylesheet().getDefaultEdgeStyle()
  Object.assign(edgeStyle, {
    [myMxConstants.STYLE_ENDARROW]: myMxConstants.ARROW_CLASSIC,
    [myMxConstants.STYLE_STROKECOLOR]: '#666666',
    [myMxConstants.STYLE_STROKEWIDTH]: 2
  })
}

function setupGraphListeners(graph: InstanceType<typeof myMxGraph>) {
  graph
    .getSelectionModel()
    .addListener(myMxConstants.EVENT_CHANGE, (_sender: unknown, evt: any) => {
      const cells = evt.getProperty('added')
      console.log('Selected cells:', cells)
    })

  graph.addListener(myMxConstants.EVENT_DOUBLE_CLICK, (_sender: unknown, evt: any) => {
    const cell = evt.getProperty('cell')
    if (cell) {
      const newValue = prompt('输入新值:', graph.convertValueToString(cell) || '')
      if (newValue !== null) {
        graph.getModel().setValue(cell, newValue)
      }
    }
  })
}

function setupContextMenu(graph: InstanceType<typeof myMxGraph>) {
  myMxEvent.disableContextMenu(graph.container)

  graph.addListener(myMxConstants.EVENT_CONTEXT_MENU, (_sender: unknown, evt: any) => {
    const cell = evt.getProperty('cell')
    evt.preventDefault()

    if (!cell) return

    const menu = new myMxPopupMenu((menu: any) => {
      menu.addItem('删除', null, () => {
        graph.removeCells([cell])
      })

      menu.addItem('复制', null, () => {
        graph.setSelectionCell(graph.cloneCell(cell))
      })
    })

    const pt = myMxEvent.getClientXY(evt.getEvent())
    menu.popup(pt.x, pt.y, null, evt.getEvent())
  })
}

function createSampleGraph(graph: InstanceType<typeof myMxGraph>) {
  const parent = graph.getDefaultParent()
  graph.getModel().beginUpdate()
  try {
    const v1 = graph.insertVertex(parent, null, '开始', 20, 20, 80, 40)
    const v2 = graph.insertVertex(parent, null, '步骤1', 20, 80, 80, 40)
    const v3 = graph.insertVertex(parent, null, '结束', 20, 140, 80, 40)
    graph.insertEdge(parent, null, '', v1, v2)
    graph.insertEdge(parent, null, '', v2, v3)
  } finally {
    graph.getModel().endUpdate()
  }
}
onMounted(async () => {
  if (graphContainerRef.value) {
    graphInstance.value = initGraph(graphContainerRef.value)
  }
})
</script>
<style lang="scss" scoped>
.mxgraph-container {
  flex: 1;
  height: calc(100vh - 90px);
  background: url('@/assets/graph/images/grid.gif');
}
</style>
