<template>
  <div class="mx-properties">
    <div class="properties-title">属性</div>
    <div v-if="selectedCell" class="properties-content">
      <div class="property-item">
        <label>文本:</label>
        <input v-model="cellText" @change="updateCellText" type="text" />
      </div>
      <div class="property-item">
        <label>宽度:</label>
        <input v-model.number="cellGeometry.width" @change="updateCellGeometry" type="number" min="10" />
      </div>
      <div class="property-item">
        <label>高度:</label>
        <input v-model.number="cellGeometry.height" @change="updateCellGeometry" type="number" min="10" />
      </div>
      <div class="property-item">
        <label>填充色:</label>
        <input v-model="cellStyle.fillColor" @change="updateCellStyle" type="color" />
      </div>
      <div class="property-item">
        <label>边框色:</label>
        <input v-model="cellStyle.strokeColor" @change="updateCellStyle" type="color" />
      </div>
    </div>
    <div v-else class="properties-empty">未选中任何元素</div>
  </div>
</template>

<script setup lang="ts">
import { inject, ref, watch } from 'vue'
import { myMxConstants, myMxGraph, myMxUtils } from '@/graph/mxGraph'
export interface CellGeometry {
  width: number
  height: number
}

const graph = inject<Ref<InstanceType<typeof myMxGraph> | null>>('mxgraph-instance')

const selectedCell = ref<any>(null)
const cellText = ref('')
const cellGeometry = ref<CellGeometry>({ width: 0, height: 0 })
const cellStyle = ref({
  fillColor: '#ffffff',
  strokeColor: '#000000'
})

watch(
  () => graph?.value,
  newGraph => {
    if (!newGraph) return

    newGraph.getSelectionModel().addListener(myMxConstants.EVENT_CHANGE, () => {
      const cells = newGraph.getSelectionCells()
      selectedCell.value = cells.length === 1 ? cells[0] : null

      if (selectedCell.value) {
        cellText.value = newGraph.convertValueToString(selectedCell.value) || ''

        const geo = selectedCell.value.getGeometry()
        if (geo) {
          cellGeometry.value = {
            width: geo.width,
            height: geo.height
          }
        }

        const style = newGraph.getCellStyle(selectedCell.value)
        cellStyle.value = {
          fillColor: style[myMxConstants.STYLE_FILLCOLOR] || '#ffffff',
          strokeColor: style[myMxConstants.STYLE_STROKECOLOR] || '#000000'
        }
      }
    })
  },
  { immediate: true }
)

function updateCellText() {
  if (!graph?.value || !selectedCell.value) return
  graph.value.getModel().setValue(selectedCell.value, cellText.value)
}

function updateCellGeometry() {
  if (!graph?.value || !selectedCell.value) return
  const geo = selectedCell.value.getGeometry()
  if (geo) {
    geo.width = cellGeometry.value.width
    geo.height = cellGeometry.value.height
    graph.value.getModel().setGeometry(selectedCell.value, geo)
  }
}

function updateCellStyle() {
  if (!graph?.value || !selectedCell.value) return
  const newStyle = {
    [myMxConstants.STYLE_FILLCOLOR]: cellStyle.value.fillColor,
    [myMxConstants.STYLE_STROKECOLOR]: cellStyle.value.strokeColor
  }
  graph.value
    .getModel()
    .setStyle(
      selectedCell.value,
      myMxUtils.setStyle(graph.value.getModel().getStyle(selectedCell.value) || '', newStyle)
    )
}
</script>
<style scoped>
.mx-properties {
  width: 240px;
  height: 100%;
  border-left: 1px solid #e0e0e0;
  background-color: #f5f5f5;
  overflow-y: auto;
  user-select: none;
}

.properties-title {
  padding: 10px;
  font-weight: bold;
  border-bottom: 1px solid #ddd;
  background-color: #eee;
  position: sticky;
  top: 0;
  z-index: 1;
}

.properties-content {
  padding: 10px;
}

.properties-empty {
  padding: 20px;
  text-align: center;
  color: #999;
}

.property-item {
  margin-bottom: 15px;
}

.property-item label {
  display: block;
  margin-bottom: 5px;
  font-size: 13px;
  color: #666;
}

.property-item input[type='text'],
.property-item input[type='number'] {
  width: 100%;
  padding: 6px;
  border: 1px solid #ddd;
  border-radius: 3px;
}

.property-item input[type='color'] {
  width: 100%;
  height: 30px;
  padding: 2px;
  border: 1px solid #ddd;
  border-radius: 3px;
}
</style>
