<template>
  <div class="mapdata">
    <div id="container" ref="container" style="width: 1200px"></div>
    <div class="left">
      <el-card class="box-card">
        <div slot="header" class="clearfix">
          <span style="font-size: 18px">地图预览</span>
        </div>
        <div style="height: 100%; padding-bottom: 10px">
          <el-input v-model="value" type="textarea" :rows="34"></el-input>
        </div>
        <div
          class="bottombtn"
          style="width: 100%; height: 35px; padding: 10px 0 0;"
        >
          <el-button
            v-no-more-click
            @click="close"
            type="primary"
            icon="el-icon-close"
            style="float: right; height: 33px; line-height: 2px;margin: 0 10px"
          >关闭
          </el-button>
          <el-button
            v-no-more-click
            @click="save"
            type="primary"
            icon="el-icon-check"
            style="float: right; height: 33px; line-height: 2px; margin: 0 10px"
          >保存
          </el-button>
          <el-button
            v-no-more-click
            @click="reset"
            type="primary"
            icon="el-icon-setting"
            style="float: right; height: 33px; line-height: 2px; margin: 0 5px"
          >重置
          </el-button>
          <!--          <el-button-->
          <!--            v-no-more-click-->
          <!--            @click="view"-->
          <!--            type="primary"-->
          <!--            icon="el-icon-refresh"-->
          <!--            style="float: right; height: 33px; line-height: 2px"-->
          <!--            >刷新-->
          <!--          </el-button>-->
        </div>
      </el-card>
    </div>
  </div>
</template>

<script>
import Konva from 'konva'
import {
  getLotoMapInfo,
  getLotoInfo,
  updateLoto,
  unbundlePointPage
} from '@/api/mes/lotoStation/lotoStation'
import { getIsIsolationPointPage } from '@/api/mes/spm/segregationPoint'

export default {
  name: 'KonvaExample',
  data() {
    return {
      stage: null,
      layer: null,
      selectedStates: [], // 用于存储每个元素的选中状态
      selectedText: [], // 用于存储未选中的元素文本
      rects: [], // 白色rect合集
      texts: [], // 白色text合集
      redrects: [], // 红色rect合集
      redtexts: [], // 白色text合集
      value: '',
      form: {}, //拿到单个数据
      originData: null, //原始数据
      filterData: null, //用来过滤掉已经渲染出来的隔离点
      leftPoints: [], //绑定的但未指定位置的集合
      orgLeftPoints: [],//原始左边数据
      rightPoints: [], //解绑的数据集合
      orgRightPoints: [],//原始右边数据
      groups: [], //组移动数据
      bindingPointIds: [], //存放从未绑定中放入物资柜的数据 id集合
      unbindPointIds: [], //解绑的数据接口参数 id集合
      isSave:false
    }
  },

  created() {
    this.getIsIsolationPointPage()
  },
  beforeRouteEnter(to, from, next) {
    next((vm) => {
      vm.getIsIsolationPointPage()
      vm.addPointsToRightPointsBox()
    })
  },
  mounted() {
    this.$nextTick(() => {
      this.getIsIsolationPointPage()
      this.getInfo()
      this.addPointsToRightPointsBox()

    })
    console.log(this.$route.query.lotoId, 'lotoId')
  },
  methods: {

    getInfo() {
      const lotoId = this.$route.query.lotoId
      const sopId = ''
      const ticketId = ''
      getLotoInfo(lotoId).then((response) => {
        console.log(response, '作业区域信息')
        this.form = response.data
      })
      // 获取map-json
      getLotoMapInfo(lotoId, sopId, ticketId).then((response) => {
        console.log(response, '作业区域预览接口调用')
        this.form.map = response.data
        this.filterData = response.data
        const data = {
          current: 1,
          size: -1,
          lotoId: this.$route.query.lotoId
        }
        getIsIsolationPointPage(data).then((res) => {
          const data1 = res.data.records
          const data2 = this.filterData
          console.log(data1, data2, '隔离点获取左侧列表啊哈哈哈哈')
          // 创建一个 Set 来存储 data2 中的 pointId
          const data2PointIds = new Set(data2.map(item => item.pointId))
          const filterData = data1.filter(item => !data2PointIds.has(item.pointId))

          this.leftPoints = filterData.map((item) => {
            return {
              pointId: item.pointId,
              pointName: item.pointName,
              remark: item.remark,
              prePointId: item.prePointId,
              pointType: item.pointType,
              pointTypeName: item.pointTypeName,
              powerType: item.powerType,
              powerTypeName: item.powerTypeName,
              pointIcon: item.pointIcon,
              status: false,
              pointPicture: item.pointPicture,
              mapImg: null
            }
          })
          this.addPointsToLeftPointsBox(filterData)
          this.orgLeftPoints = res.data.records.map((item) => {
            return {
              pointId: item.pointId,
              pointName: item.pointName,
              remark: item.remark,
              prePointId: item.prePointId,
              pointType: item.pointType,
              pointTypeName: item.pointTypeName,
              powerType: item.powerType,
              powerTypeName: item.powerTypeName,
              pointIcon: item.pointIcon,
              status: false,
              pointPicture: item.pointPicture,
              mapImg: null
            }
          })
        })
        if (response.data) {
          try {
            this.value = JSON.stringify(response.data, null, 4)
            this.originData = this.value
          } catch (err) {
          }
        }
        this.initKonva()
      })
    },
    // 获取所有隔离点
    getIsIsolationPointPage() {
      //   拿到解绑的隔离点数据
      const data1 = {
        current: 1,
        size: -1,
        lotoId: 0
      }
      getIsIsolationPointPage(data1).then((res) => {
        this.rightPoints = res.data.records.map((item) => {
          return {
            pointId: item.pointId,
            pointName: item.pointName,
            remark: item.remark,
            prePointId: item.prePointId,
            pointType: item.pointType,
            pointTypeName: item.pointTypeName,
            powerType: item.powerType,
            powerTypeName: item.powerTypeName,
            pointIcon: item.pointIcon,
            status: false,
            pointPicture: item.pointPicture,
            mapImg: null
          }
        })
        this.orgRightPoints = res.data.records.map((item) => {
          return {
            pointId: item.pointId,
            pointName: item.pointName,
            remark: item.remark,
            prePointId: item.prePointId,
            pointType: item.pointType,
            pointTypeName: item.pointTypeName,
            powerType: item.powerType,
            powerTypeName: item.powerTypeName,
            pointIcon: item.pointIcon,
            status: false,
            pointPicture: item.pointPicture,
            mapImg: null
          }
        })
      })
    },
    // 重置
    reset() {
      this.value = this.originData
      // 清空并重新赋值
      this.rightPoints = JSON.parse(JSON.stringify(this.orgRightPoints)) // 深拷贝
      this.leftPoints = JSON.parse(JSON.stringify(this.orgLeftPoints))  // 深拷贝
      this.initKonva() // 重新初始化 Konva
    },
    // 刷新
    // view() {
    //   if (this.isJson(this.value)) {
    //     this.form.map = this.value
    //     this.initKonva()
    //     this.getIsIsolationPointPage()
    //     // this.addPointsToLeftPointsBox();
    //     this.addPointsToRightPointsBox()
    //   } else {
    //     this.$message({
    //       type: 'error',
    //       message: '地图数据格式不正确，请输入有效的 JSON 格式!'
    //     })
    //   }
    // },
    close() {
      this.$router.push('/mes/dv/lotoStation')
    },
    save() {
      this.$confirm('请确认是否保存修改内容', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      })
        .then(() => {
          // 校验 this.value 是否为有效的 JSON
          if (this.isJson(this.value)) {
            const mapData =
              typeof this.value === 'string'
                ? this.value
                : JSON.stringify(this.value)
            const formData = {
              ...this.form,
              map: mapData
            }
            console.log(formData, 'map')
            updateLoto(formData).then((response) => {
              console.log(response, '修改车间区域地图')
              this.$message({
                type: 'success',
                message: '保存成功!'
              })
            })

            const data = {
              bindingPointIds: this.bindingPointIds,
              lotoId: this.$route.query.lotoId,
              unbindPointIds: this.unbindPointIds
            }
            console.log(data, '解绑与绑定数据参数')
            unbundlePointPage(data).then((res) => {
              console.log(res, '解绑接口返回值')
              this.bindingPointIds = []
              this.unbindPointIds = []
            })
          } else {
            this.$message({
              type: 'error',
              message: '地图数据格式不正确，请输入有效的 JSON 格式!'
            })
          }
        })
        .catch(() => {
          // 取消操作
        })
    },

    // 校验字符串是否为有效的 JSON
    isJson(str) {
      try {
        JSON.parse(str)
        return true
      } catch (e) {
        return false
      }
    },
    initKonva() {
      // 创建舞台
      this.stage = new Konva.Stage({
        container: this.$refs.container, // 容器元素
        width: 1250,
        height: 860
      })

      // 创建图层
      this.layer = new Konva.Layer()
      // 绘制隔离点等其他内容
      this.drawGrid(50, 50, '#e0e0e0') // 每个单元格50x50，浅灰色网格
      // 创建物资柜底图
      const bgImage = new Image()
      bgImage.src = require('@/assets/images/table.png')
      bgImage.onload = () => {
        // 创建背景图并添加到图层
        const knovaImage = new Konva.Image({
          x: 330,
          y: 10,
          image: bgImage,
          width: 500,
          height: 790,
          draggable: false
        })
        this.layer.add(knovaImage)

        // 创建所有隔离点父盒子 放置于网格线上
        const rightPointsBox = new Konva.Rect({
          x: 990,
          y: 15,
          width: 200,
          height: 800,
          cornerRadius: 5,
          stroke: 'black',
          strokeWidth: 2,
          fill: 'white'
        })
        const rightnoLoto = new Konva.Text({
          x: 1000, // 调整位置以适应网格
          y: 20, // 调整位置以适应网格
          text: '未绑定锁定站的隔离点数据',
          fontSize: 15,
          fill: 'black'
        })

        this.layer.add(rightPointsBox)
        this.layer.add(rightnoLoto)

        // 将隔离点添加到 rightPointsBox
        this.addPointsToRightPointsBox(rightPointsBox)

        // 渲染数据
        const imageSrc = require('@/assets/images/localSetIcon.jpg') // 图片路径
        this.renderGrid(imageSrc, 6, 3, 450, 100, 120, 100, 50, 50, 60, 25)

        // 将图层添加到舞台
        this.stage.add(this.layer)
        this.layer.draw()
      }

      // 禁止舞台拖拽
      this.stage.draggable(false)
    },

    // 绘制无限网格
    drawGrid(cellWidth, cellHeight, gridColor) {
      const width = 1200
      const height = 860

      // 绘制竖线
      for (let i = 0; i <= width; i += cellWidth) {
        const verticalLine = new Konva.Line({
          points: [i, 0, i, height],
          stroke: gridColor,
          strokeWidth: 1
        })
        this.layer.add(verticalLine)
      }

      // 绘制横线
      for (let j = 0; j <= height; j += cellHeight) {
        const horizontalLine = new Konva.Line({
          points: [0, j, width, j],
          stroke: gridColor,
          strokeWidth: 1
        })
        this.layer.add(horizontalLine)
      }

      // 添加网格坐标文本
      // for (let row = 0; row < height / cellHeight; row++) {
      //   for (let col = 0; col < width / cellWidth; col++) {
      //     const text = new Konva.Text({
      //       x: col * cellWidth + 5, // 调整位置以适应网格
      //       y: row * cellHeight + 5, // 调整位置以适应网格
      //       text: `(${col},${row})`,
      //       fontSize: 10,
      //       fill: 'gray',
      //     });
      //     this.layer.add(text);
      //   }
      // }

      this.layer.draw()
    },

    renderGrid(imageSrc) {
      this.selectedStates = [] // 用数组来存储选中状态
      this.rects = []
      this.texts = []
      this.bgrects = {}
      this.redrects = []
      this.redtexts = []
      this.selectedText = []

      const positions = JSON.parse(this.value)

      positions.forEach((pos, index) => {
        const x = pos.col * 50 // 每个单元格宽度为50
        const y = pos.row * 50 // 每个单元格高度为50
        const labelText = pos.pointName // 对应的文字

        const point = new Image()
        point.src = pos.pointIcon

        point.onload = () => {
          // 创建一个新的Group来包含整个隔离点
          const group = new Konva.Group({
            x: x,
            y: y,
            draggable: true // 设置为可拖拽
          })

          // 底部白色背景
          const bgrect = new Konva.Rect({
            x: -6,
            y: -5,
            width: 62,
            height: 80,
            cornerRadius: 5,
            stroke: 'white',
            strokeWidth: 2,
            fill: 'white'
          })

          // 普通矩形
          const rect = new Konva.Rect({
            x: 0,
            y: -1,
            width: 50,
            height: 72,
            cornerRadius: 5,
            stroke: 'red',
            strokeWidth: 2,
            fill: 'white'
          })

          // 图片
          const knovaImage = new Konva.Image({
            x: 0,
            y: 0,
            image: point,
            width: 50,
            height: 50
          })

          // 文字
          const text = new Konva.Text({
            x: 8,
            y: 50,
            fontSize: 17,
            text: labelText,
            fontFamily: 'Calibri',
            fill: 'red'
          })

          // 将所有元素添加到group中
          group.add(bgrect)
          group.add(rect)
          group.add(knovaImage)
          group.add(text)

          // 将group添加到layer
          this.layer.add(group)
          // 定义右侧盒子的范围
          const rightBoxBounds = {
            x: 990,
            y: 15,
            width: 200,
            height: 800
          }
          // 定义物资柜的范围
          const cabinetBounds = {
            x: 330, // 物资柜的 x 坐标
            y: 10, // 物资柜的 y 坐标
            width: 500, // 物资柜的宽度
            height: 790 // 物资柜的高度
          }

          group.on('dragend', () => {
            // 获取拖拽的内容对应的点名称
            const labelText = group.findOne('Text').text()

            // 获取 group 的位置
            const groupPos = group.getAbsolutePosition()

            // 检查是否仍在物资柜范围内
            const isInCabinet =
              groupPos.x >= cabinetBounds.x &&
              groupPos.x <= cabinetBounds.x + cabinetBounds.width &&
              groupPos.y >= cabinetBounds.y &&
              groupPos.y <= cabinetBounds.y + cabinetBounds.height

            // 检查是否在右侧盒子范围内
            const isInRightBox =
              groupPos.x >= rightBoxBounds.x &&
              groupPos.x <= rightBoxBounds.x + rightBoxBounds.width &&
              groupPos.y >= rightBoxBounds.y &&
              groupPos.y <= rightBoxBounds.y + rightBoxBounds.height

            // 查找并删除对应的点数据
            const indexToRemove = positions.findIndex(
              (item) => item.pointName === labelText
            )

            if (indexToRemove !== -1) {
              // 从 positions 中移除并获取移动的点
              const movedPoint = positions.splice(indexToRemove, 1)[0]

              if (movedPoint) {
                // 如果点位在物资柜外但不在右侧列表中，进行位置更新
                if (!isInCabinet && !isInRightBox) {
                  // 更新位置为新的列和行
                  const newCol = Math.round(groupPos.x / 50) // 四舍五入到最近的列
                  const newRow = Math.round(groupPos.y / 50) // 四舍五入到最近的行

                  // 限制列和行的范围，防止超出网格边界
                  const maxCols = Math.floor(1200 / 50) - 1 // 最大列索引
                  const maxRows = Math.floor(860 / 50) - 1 // 最大行索引

                  const boundedCol = Math.max(0, Math.min(newCol, maxCols)) // 限制列范围
                  const boundedRow = Math.max(0, Math.min(newRow, maxRows)) // 限制行范围

                  // 更新点位数据
                  const updatedPosition = {
                    ...movedPoint,
                    col: boundedCol,
                    row: boundedRow
                  }

                  // 更新 positions 数组中的点位
                  positions[indexToRemove] = updatedPosition
                  this.value = JSON.stringify(positions, null, 4)
                }

                // 如果从物资柜外移动到右侧列表
                else if (isInRightBox) {
                  // 确保点位没有被重复添加到 rightPoints 中
                  if (
                    !this.rightPoints.find(
                      (point) => point.pointName === movedPoint.pointName
                    )
                  ) {
                    // 从 positions 中删除该点
                    const updatedPositions = positions.filter(
                      (item) => item.pointName !== movedPoint.pointName
                    )
                    this.value = JSON.stringify(updatedPositions, null, 4)

                    // 将 movedPoint 添加到 rightPoints 数组
                    this.rightPoints.push(movedPoint)

                    // 将 pointId 添加到 unbindPointIds 数组
                    this.unbindPointIds.push(movedPoint.pointId)
                  }
                }
                // 如果是从物资柜内拿出来并移到柜外但不进入右侧列表
                else if (isInCabinet && !isInRightBox) {
                  // 更新位置并保存
                  const newCol = Math.round(groupPos.x / 50) // 四舍五入到最近的列
                  const newRow = Math.round(groupPos.y / 50) // 四舍五入到最近的行

                  // 限制列和行的范围，防止超出网格边界
                  const maxCols = Math.floor(1200 / 50) - 1 // 最大列索引
                  const maxRows = Math.floor(860 / 50) - 1 // 最大行索引

                  const boundedCol = Math.max(0, Math.min(newCol, maxCols)) // 限制列范围
                  const boundedRow = Math.max(0, Math.min(newRow, maxRows)) // 限制行范围

                  // 更新点位数据
                  const updatedPosition = {
                    ...movedPoint,
                    col: boundedCol,
                    row: boundedRow
                  }

                  // 更新 positions 数组中的点位
                  positions[indexToRemove] = updatedPosition
                  this.value = JSON.stringify(positions, null, 4)
                }
              }
            } else {
              // 如果点不在 positions 中，可能是从右侧列表移动回来
              const rightIndex = this.rightPoints.findIndex(
                (item) => item.pointName === labelText
              )

              if (rightIndex !== -1) {
                // 从右侧拖拽到物资柜外或物资柜内
                const movedPoint = this.rightPoints.splice(rightIndex, 1)[0]

                // 如果点不在右侧列表中且不在物资柜中，更新位置
                if (!isInRightBox && !isInCabinet) {
                  // 更新位置为新的列和行
                  const newCol = Math.round(groupPos.x / 50) // 四舍五入到最近的列
                  const newRow = Math.round(groupPos.y / 50) // 四舍五入到最近的行

                  // 限制列和行的范围，防止超出网格边界
                  const maxCols = Math.floor(1200 / 50) - 1 // 最大列索引
                  const maxRows = Math.floor(860 / 50) - 1 // 最大行索引

                  const boundedCol = Math.max(0, Math.min(newCol, maxCols)) // 限制列范围
                  const boundedRow = Math.max(0, Math.min(newRow, maxRows)) // 限制行范围

                  // 更新点位数据
                  const updatedPosition = {
                    ...movedPoint,
                    col: boundedCol,
                    row: boundedRow
                  }

                  // 更新 positions 数组中的点位
                  positions.push(updatedPosition)
                  this.value = JSON.stringify(positions, null, 4)
                }

                // 如果点从右侧拖拽到物资柜内
                if (isInCabinet) {
                  // 更新位置为新的列和行
                  const newCol = Math.round(groupPos.x / 50) // 四舍五入到最近的列
                  const newRow = Math.round(groupPos.y / 50) // 四舍五入到最近的行

                  // 限制列和行的范围，防止超出网格边界
                  const maxCols = Math.floor(1200 / 50) - 1 // 最大列索引
                  const maxRows = Math.floor(860 / 50) - 1 // 最大行索引

                  const boundedCol = Math.max(0, Math.min(newCol, maxCols)) // 限制列范围
                  const boundedRow = Math.max(0, Math.min(newRow, maxRows)) // 限制行范围

                  // 更新点位数据
                  const updatedPosition = {
                    ...movedPoint,
                    col: boundedCol,
                    row: boundedRow
                  }

                  // 更新 positions 数组中的点位
                  positions.push(updatedPosition)
                  this.value = JSON.stringify(positions, null, 4)

                  // 确保点位没有被重复添加到 leftPoints 中
                  if (
                    !this.leftPoints.find(
                      (point) => point.pointName === movedPoint.pointName
                    )
                  ) {
                    this.leftPoints.push(movedPoint)
                  }
                }
              }
            }

            // 清理 undefined 数据
            this.rightPoints = this.rightPoints.filter(Boolean)

            // 打印调试信息
            console.log('Updated positions:', positions)
            console.log('Right Points:', this.rightPoints)
            console.log('Left Points:', this.leftPoints)

            // 重新绘制图层
            this.layer.draw()
          })
        }
      })
    },

    // renderGrid(imageSrc) {
    //   this.selectedStates = [] // 用数组来存储选中状态
    //   this.rects = []
    //   this.texts = []
    //   this.bgrects = {}
    //   this.redrects = []
    //   this.redtexts = []
    //   this.selectedText = []
    //
    //   const positions = JSON.parse(this.value)
    //
    //   positions.forEach((pos, index) => {
    //     const x = pos.col * 50 // 每个单元格宽度为50
    //     const y = pos.row * 50 // 每个单元格高度为50
    //     const labelText = pos.pointName // 对应的文字
    //
    //     const point = new Image()
    //     point.src = pos.pointIcon
    //
    //     point.onload = () => {
    //       // 创建一个新的Group来包含整个隔离点
    //       const group = new Konva.Group({
    //         x: x,
    //         y: y,
    //         draggable: true // 设置为可拖拽
    //       })
    //
    //       // 底部白色背景
    //       const bgrect = new Konva.Rect({
    //         x: -6,
    //         y: -5,
    //         width: 62,
    //         height: 80,
    //         cornerRadius: 5,
    //         stroke: 'white',
    //         strokeWidth: 2,
    //         fill: 'white'
    //       })
    //
    //       // 普通矩形
    //       const rect = new Konva.Rect({
    //         x: 0,
    //         y: -1,
    //         width: 50,
    //         height: 72,
    //         cornerRadius: 5,
    //         stroke: 'red',
    //         strokeWidth: 2,
    //         fill: 'white'
    //       })
    //
    //       // 图片
    //       const knovaImage = new Konva.Image({
    //         x: 0,
    //         y: 0,
    //         image: point,
    //         width: 50,
    //         height: 50
    //       })
    //
    //       // 文字
    //       const text = new Konva.Text({
    //         x: 8,
    //         y: 50,
    //         fontSize: 17,
    //         text: labelText,
    //         fontFamily: 'Calibri',
    //         fill: 'red'
    //       })
    //
    //       // 将所有元素添加到group中
    //       group.add(bgrect)
    //       group.add(rect)
    //       group.add(knovaImage)
    //       group.add(text)
    //
    //       // 将group添加到layer
    //       this.layer.add(group)
    //       // 定义右侧盒子的范围
    //       const rightBoxBounds = {
    //         x: 990,
    //         y: 15,
    //         width: 200,
    //         height: 800
    //       }
    //       // 定义物资柜的范围
    //       const cabinetBounds = {
    //         x: 330, // 物资柜的 x 坐标
    //         y: 10, // 物资柜的 y 坐标
    //         width: 500, // 物资柜的宽度
    //         height: 790 // 物资柜的高度
    //       }
    //
    //       // 定义是否已经在物资柜中的状态
    //
    //       group.on('dragend', () => {
    //         // 获取拖拽的内容对应的点名称
    //         const labelText = group.findOne('Text').text()
    //
    //         // 获取 group 的位置
    //         const groupPos = group.getAbsolutePosition()
    //
    //         // 检查是否仍在物资柜范围内
    //         const isInCabinet =
    //           groupPos.x >= cabinetBounds.x &&
    //           groupPos.x <= cabinetBounds.x + cabinetBounds.width &&
    //           groupPos.y >= cabinetBounds.y &&
    //           groupPos.y <= cabinetBounds.y + cabinetBounds.height
    //
    //         // 检查是否在右侧盒子范围内
    //         const isInRightBox =
    //           groupPos.x >= rightBoxBounds.x &&
    //           groupPos.x <= rightBoxBounds.x + rightBoxBounds.width &&
    //           groupPos.y >= rightBoxBounds.y &&
    //           groupPos.y <= rightBoxBounds.y + rightBoxBounds.height
    //
    //         // 查找并删除对应的点数据
    //         const indexToRemove = positions.findIndex(
    //           (item) => item.pointName === labelText
    //         )
    //
    //         if (indexToRemove !== -1) {
    //           // 从 positions 中移除并获取移动的点
    //           const movedPoint = positions.splice(indexToRemove, 1)[0]
    //
    //           if (movedPoint) {
    //             // 如果点位在物资柜外但不在右侧列表中，进行位置更新
    //             if (!isInCabinet && !isInRightBox) {
    //               // 更新位置为新的列和行
    //               const newCol = Math.round(groupPos.x / 50) // 四舍五入到最近的列
    //               const newRow = Math.round(groupPos.y / 50) // 四舍五入到最近的行
    //
    //               // 限制列和行的范围，防止超出网格边界
    //               const maxCols = Math.floor(1200 / 50) - 1 // 最大列索引
    //               const maxRows = Math.floor(860 / 50) - 1 // 最大行索引
    //
    //               const boundedCol = Math.max(0, Math.min(newCol, maxCols)) // 限制列范围
    //               const boundedRow = Math.max(0, Math.min(newRow, maxRows)) // 限制行范围
    //
    //               // 更新点位数据
    //               const updatedPosition = {
    //                 ...movedPoint,
    //                 col: boundedCol,
    //                 row: boundedRow
    //               }
    //
    //               // 更新 positions 数组中的点位
    //               positions[indexToRemove] = updatedPosition
    //               this.value = JSON.stringify(positions, null, 4)
    //             }
    //
    //             // 如果从物资柜外移动到右侧列表
    //             else if (isInRightBox) {
    //               // 确保点位没有被重复添加到 rightPoints 中
    //               if (
    //                 !this.rightPoints.find(
    //                   (point) => point.pointName === movedPoint.pointName
    //                 )
    //               ) {
    //                 // 从 positions 中删除该点
    //                 const updatedPositions = positions.filter(
    //                   (item) => item.pointName !== movedPoint.pointName
    //                 )
    //                 this.value = JSON.stringify(updatedPositions, null, 4)
    //
    //                 // 将 movedPoint 添加到 rightPoints 数组
    //                 this.rightPoints.push(movedPoint)
    //
    //                 // 将 pointId 添加到 unbindPointIds 数组
    //                 this.unbindPointIds.push(movedPoint.pointId)
    //               }
    //             }
    //             // 如果是从物资柜内拿出来并移到柜外但不进入右侧列表
    //             else if (isInCabinet && !isInRightBox) {
    //               // 更新位置并保存
    //               const newCol = Math.round(groupPos.x / 50) // 四舍五入到最近的列
    //               const newRow = Math.round(groupPos.y / 50) // 四舍五入到最近的行
    //
    //               // 限制列和行的范围，防止超出网格边界
    //               const maxCols = Math.floor(1200 / 50) - 1 // 最大列索引
    //               const maxRows = Math.floor(860 / 50) - 1 // 最大行索引
    //
    //               const boundedCol = Math.max(0, Math.min(newCol, maxCols)) // 限制列范围
    //               const boundedRow = Math.max(0, Math.min(newRow, maxRows)) // 限制行范围
    //
    //               // 更新点位数据
    //               const updatedPosition = {
    //                 ...movedPoint,
    //                 col: boundedCol,
    //                 row: boundedRow
    //               }
    //
    //               // 更新 positions 数组中的点位
    //               positions[indexToRemove] = updatedPosition
    //               this.value = JSON.stringify(positions, null, 4)
    //             }
    //           }
    //         } else {
    //           // 如果点不在 positions 中，可能是从右侧列表移动回来
    //           const rightIndex = this.rightPoints.findIndex(
    //             (item) => item.pointName === labelText
    //           )
    //
    //           if (rightIndex !== -1 && !isInRightBox && !isInCabinet) {
    //             // 从右侧拖拽到物资柜外
    //             const movedPoint = this.rightPoints.splice(rightIndex, 1)[0]
    //             if (
    //               !this.leftPoints.find(
    //                 (point) => point.pointName === movedPoint.pointName
    //               )
    //             ) {
    //               this.leftPoints.push(movedPoint)
    //             }
    //           }
    //         }
    //
    //         // 清理 undefined 数据
    //         this.rightPoints = this.rightPoints.filter(Boolean)
    //
    //         // 打印调试信息
    //         console.log('Updated positions:', positions)
    //         console.log('Right Points:', this.rightPoints)
    //       })
    //
    //       this.layer.draw()
    //     }
    //   })
    // },
    // 左侧的列表
    addPointsToLeftPointsBox(filterData) {
      // 获取接口返回的 leftPoints 数据
      const pointsData = filterData

      let row = 1  // 当前行
      let col = 1  // 当前列

      // 遍历 pointsData 并根据是否存在于 this.value 中来决定位置
      pointsData.forEach((point) => {
        const existingPoint = JSON.parse(this.value).find(
          (item) => item.pointId === point.pointId
        )

        // 如果该点在 this.value 中，使用它的原始位置
        if (existingPoint) {
          point.row = existingPoint.row
          point.col = existingPoint.col
        } else {
          // 否则，按顺序从 (0, 0) 位置开始，每行三个点
          point.row = row
          point.col = col

          // 每行最多三个点，换行处理
          col++
          if (col >= 3) {
            col = 0
            row++
          }
        }

        // 渲染该点
        this.renderPoint(point)
      })
    },

// 渲染每个点
    renderPoint(point) {
      const x = point.col * 50 // 每个单元格宽度为50
      const y = point.row * 50 // 每个单元格高度为50

      const labelText = point.pointName // 对应的文字
      const pointImage = new Image()
      pointImage.src = point.pointIcon

      pointImage.onload = () => {
        // 创建一个新的 Group 来包含整个隔离点
        const group = new Konva.Group({
          x: x,
          y: y,
          draggable: true // 设置为可拖拽
        })

        // 背景矩形
        const bgrect = new Konva.Rect({
          x: -6,
          y: -5,
          width: 62,
          height: 80,
          cornerRadius: 5,
          stroke: 'white',
          strokeWidth: 2,
          fill: 'white'
        })

        // 普通矩形
        const rect = new Konva.Rect({
          x: 0,
          y: -1,
          width: 50,
          height: 72,
          cornerRadius: 5,
          stroke: 'red',
          strokeWidth: 2,
          fill: 'white'
        })

        // 图片
        const knovaImage = new Konva.Image({
          x: 0,
          y: 0,
          image: pointImage,
          width: 50,
          height: 50
        })

        // 文字
        const text = new Konva.Text({
          x: 8,
          y: 50,
          fontSize: 17,
          text: labelText,
          fontFamily: 'Calibri',
          fill: 'red'
        })

        // 将所有元素添加到 group 中
        group.add(bgrect)
        group.add(rect)
        group.add(knovaImage)
        group.add(text)

        // 将 group 添加到 layer
        this.layer.add(group)

        // 定义右侧盒子的范围
        const rightBoxBounds = {
          x: 990,
          y: 15,
          width: 200,
          height: 800
        }

        // 定义物资柜的范围
        const cabinetBounds = {
          x: 330,
          y: 10,
          width: 500,
          height: 790
        }

        // 处理拖拽事件
        group.on('dragend', () => {
          const groupPos = group.getAbsolutePosition()
          const isInRightBox =
            groupPos.x >= rightBoxBounds.x &&
            groupPos.x <= rightBoxBounds.x + rightBoxBounds.width &&
            groupPos.y >= rightBoxBounds.y &&
            groupPos.y <= rightBoxBounds.y + rightBoxBounds.height

          const isInCabinet =
            groupPos.x >= cabinetBounds.x &&
            groupPos.x <= cabinetBounds.x + cabinetBounds.width &&
            groupPos.y >= cabinetBounds.y &&
            groupPos.y <= cabinetBounds.y + cabinetBounds.height

          // 如果点进入右侧列表，执行删除操作
          if (isInRightBox) {
            this.removePointFromJson(point)
          } else if (isInCabinet) {
            // 如果点回到物资柜，执行更新操作
            this.updatePointInJson(point, groupPos)
          } else if (!isInCabinet && !isInRightBox) {
            // 如果点位在物资柜外但不在右侧列表中，进行位置更新
            this.updatePointInJson(point, groupPos)
          }

        })

        this.layer.draw()
      }
    },

// 从 json 删除对应的点
    removePointFromJson(point) {
      // 更新 leftPoints 和 rightPoints
      this.rightPoints.push(point)
      this.unbindPointIds.push(point.pointId) // 给接口传递需要解绑的数据Id

      // 删除 JSON 中对应的点
      const updatedData = JSON.parse(this.value).filter(
        (item) => item.pointId !== point.pointId
      )
      this.value = JSON.stringify(updatedData, null, 4)

      // console.log('Updated value after removal:', this.value)
    },

// 更新 JSON 中对应点的位置
    updatePointInJson(point, groupPos) {
      // 计算新的位置
      const newCol = Math.round(groupPos.x / 50)
      const newRow = Math.round(groupPos.y / 50)

      // 更新 positions 数组中的点位
      const updatedPosition = {
        row: newRow,
        col: newCol,
        pointId: point.pointId,
        pointName: point.pointName,
        remark: point.remark,
        prePointId: point.prePointId,
        pointType: point.pointType,
        pointTypeName: point.pointTypeName,
        powerType: point.powerType,
        powerTypeName: point.powerTypeName,
        state: point.state,
        pointIcon: point.pointIcon,
        pointPicture: point.pointPicture,
        mapImg: point.mapImg
      }

      let positions = JSON.parse(this.value)
      const index = positions.findIndex((item) => item.pointId === point.pointId)
      if (index !== -1) {
        positions[index] = updatedPosition
        this.value = JSON.stringify(positions, null, 4)
      } else {
        // 如果点位不在 this.value 中，则重新插入
        positions.push(updatedPosition)
        this.value = JSON.stringify(positions, null, 4)
      }

      console.log('Updated value after update:', this.value)
    },

    addPointsToRightPointsBox(rightPointsBox) {
      if (this.rightPoints && this.rightPoints.length > 0) {
        const boxWidth = rightPointsBox.width();
        const boxHeight = rightPointsBox.height();
        const boxX = rightPointsBox.x();
        const boxY = rightPointsBox.y();
        const padding = 10; // 每个隔离点之间的间距
        const pointWidth = 50; // 每个隔离点的宽度
        const pointHeight = 70; // 每个隔离点的高度（包括图片和文字）

        let currentX = boxX + padding;
        let currentY = boxY + padding;
        const rightBoxBounds = {
          x: 990,
          y: 15,
          width: 200,
          height: 800,
        };
        const cabinetBounds = {
          x: 330,
          y: 10,
          width: 500,
          height: 790,
        };

        this.rightPoints.forEach((point) => {
          // 创建一个组来组合红色边框、图片和文字
          const group = new Konva.Group({
            x: currentX,
            y: currentY + 14,
            draggable: true, // 启用拖拽功能
          });

          // 创建红色边框
          const borderRect = new Konva.Rect({
            x: 0,
            y: 0,
            width: pointWidth,
            height: pointHeight,
            cornerRadius: 5,
            stroke: 'red',
            strokeWidth: 2,
            fill: 'white',
          });
          group.add(borderRect);

          // 创建图片
          const image = new Image();
          image.src = point.pointIcon;
          image.onload = () => {
            const knovaImage = new Konva.Image({
              x: 1, // 图片在组内的位置
              y: 5, // 图片在组内的位置
              image: image,
              width: 50, // 图片宽度
              height: 50, // 图片高度
            });
            group.add(knovaImage);

            // 创建文字
            const pointText = new Konva.Text({
              x: 12, // 文字在组内的位置
              y: 53, // 文字在组内的位置
              text: point.pointName,
              fontSize: 12,
              fill: 'red',
            });
            group.add(pointText);

            // 将组添加到图层
            this.layer.add(group);
            this.groups[point.pointName] = group; // 用文字作为键存储

            group.on('dragmove', () => {
              // 获取当前组的位置
              const groupPos = group.getAbsolutePosition();

              // 更新组的位置，无限制
              group.x(groupPos.x);
              group.y(groupPos.y);
            });

            // 监听组的拖拽结束事件
            group.on('dragend', () => {
              const gridX = 50; // 网格单元格宽度
              const gridY = 50; // 网格单元格高度

              // 计算最近的网格点位置
              const snappedX = Math.round(group.x() / gridX) * gridX;
              const snappedY = Math.round(group.y() / gridY) * gridY;

              // 设置组到最近的网格点位置
              group.x(snappedX);
              group.y(snappedY);

              // 计算网格坐标
              const row = Math.floor(snappedY / gridY);
              const col = Math.floor(snappedX / gridX);

              // 更新点位数据
              const updatedPointData = {
                row: row,
                col: col,
                pointId: point.pointId,
                pointName: point.pointName,
                remark: point.remark,
                prePointId: point.prePointId,
                pointType: point.pointType,
                pointTypeName: point.pointTypeName,
                powerType: point.powerType,
                powerTypeName: point.powerTypeName,
                state: point.status,
                pointIcon: point.pointIcon,
                pointPicture: point.pointPicture,
                mapImg: null,

              };

              // 解析 this.value 为数组
              let valueArray = [];
              try {
                valueArray = JSON.parse(this.value);
              } catch (e) {
                console.error('Failed to parse value:', e);
              }

              // 判断拖拽目标区域
              if (
                snappedX >= rightBoxBounds.x &&
                snappedX <= rightBoxBounds.x + rightBoxBounds.width &&
                snappedY >= rightBoxBounds.y &&
                snappedY <= rightBoxBounds.y + rightBoxBounds.height
              ) {
                // 进入右侧盒子区域
                console.log('进入右侧盒子区域');

                // 检查点是否已经存在于 valueArray 中
                // const index = valueArray.findIndex(item => item.pointId === point.pointId);
                // if (index !== -1) {
                //   // 更新已有点位
                //   valueArray[index] = updatedPointData;
                // } else {
                //   // 如果点位不存在，则新增
                //   valueArray.push(updatedPointData);
                // }
                //
                // this.value = JSON.stringify(valueArray, null, 4);
// 如果点不在目标区域，从 valueArray 中移除
                this.value = JSON.stringify(valueArray.filter(item => item.pointId !== point.pointId), null, 4);
                // 从右侧盒子移除点
                this.rightPoints = this.rightPoints.filter(
                  (item) => item.pointId !== point.pointId
                );
              } else if (
                snappedX >= cabinetBounds.x &&
                snappedX <= cabinetBounds.x + cabinetBounds.width &&
                snappedY >= cabinetBounds.y &&
                snappedY <= cabinetBounds.y + cabinetBounds.height
              ) {
                // 进入物资柜区域
                console.log('进入物资柜区域');

                // 检查点是否已经存在于 valueArray 中
                const index = valueArray.findIndex(item => item.pointId === point.pointId);
                if (index !== -1) {
                  // 更新已有点位
                  valueArray[index] = updatedPointData;
                } else {
                  // 如果点位不存在，则新增
                  valueArray.push(updatedPointData);
                }

                this.value = JSON.stringify(valueArray, null, 4);
                this.bindingPointIds.push(point.pointId);

                // 从右侧盒子移除点
                this.rightPoints = this.rightPoints.filter(
                  (item) => item.pointId !== point.pointId
                );
              } else {
                console.log('未进入目标区域，保持原状态');

                // 如果点不在目标区域，从 valueArray 中移除
                this.value = JSON.stringify(valueArray.filter(item => item.pointId !== point.pointId), null, 4);

                // 如果点不在目标区域，重新添加到 rightPoints
                this.rightPoints.push(point);
              }

              // 重新绘制图层
              this.layer.draw();
            });

            // 重新绘制图层
            this.layer.draw();
          };

          // 更新下一个隔离点的位置
          currentX += pointWidth + padding;
          if (currentX + pointWidth > boxX + boxWidth) {
            currentX = boxX + padding;
            currentY += pointHeight + padding;
          }
        });
      }
    }


  }
}
</script>

<style scoped lang="scss">
#container {
  width: 100%;
  height: 100%;
}

.mapdata {
  width: 100%;
  height: 100%;
  display: flex;
}

.left {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  margin-bottom: 20px;
}
</style>
