<template>
  <div class="mapdata">
    <div id="container" ref="container" style="width: 1600px"></div>
    <div class="left">
      <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: 10px 0"
          >关闭
        </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: 10px 0"
          >保存
        </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: 10px 0"
          >重置
        </el-button>

      </div>
    </div>
<!--       <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>
</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: true,
      isInitialized: false, // 添加初始化标志
    };
  },
  // watch: {
  //   bindingPointIds(newVal, oldVal) {
  //     if (newVal) {
  //       this.isSave = false;
  //     }
  //   },
  //   unbindPointIds(newVal, oldVal) {
  //     if (newVal) {
  //       this.isSave = false;
  //     }
  //   },
  //   // value: {
  //   //   handler(newVal, oldVal) {
  //   //     if (this.isInitialized && newVal) {
  //   //       // 只有在初始化后才监听 value 变化
  //   //       const parsedValue = JSON.parse(newVal);
  //   //       console.log(parsedValue, "deep watch for value");
  //   //       this.isSave = false;
  //   //     }
  //   //   },
  //   //   deep: true,
  //   // },
  // },

  created() {
    this.getIsIsolationPointPage();
    this.isInitialized = true;
  },
  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 = [];
            });
            this.close();
          } 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: 1600,
        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 = 1600;
      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) => {
        // console.log(pos,'单条数据');
        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];
              const movedPoint=positions.find((item) => item.pointName == labelText);

              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 = {
                    row: boundedRow,
                    col: boundedCol,
                    pointId: movedPoint.pointId,
                    pointName: movedPoint.pointName,
                    remark: movedPoint.remark,
                    prePointId: movedPoint.prePointId,
                    pointType: movedPoint.pointType,
                    pointTypeName: movedPoint.pointTypeName,
                    powerType: movedPoint.powerType,
                    powerTypeName: movedPoint.powerTypeName,
                    state: movedPoint.state,
                    pointIcon: movedPoint.pointIcon,
                    pointPicture: movedPoint.pointPicture,
                    mapImg: movedPoint.mapImg,
                  };

                  // 更新 positions 数组中的点位
                  const updatedPositionCopy = JSON.parse(JSON.stringify(updatedPosition));
                  positions[indexToRemove] = updatedPositionCopy;

                  console.log(updatedPositionCopy, positions[indexToRemove], 'updatedPosition');
                  this.value = JSON.stringify(positions, null, 4);

                }

                // 如果从物资柜外移动到右侧列表
                else if (isInRightBox) {
                  console.log(isInRightBox,'进入右侧盒子');
                  // 确保点位没有被重复添加到 rightPoints 中
                  if (
                    !this.rightPoints.find(
                      (point) => point.pointName == movedPoint.pointName
                    )
                  ) {
                    // console.log(isInRightBox,'进入右侧盒子');
                    // // 从 positions 中删除该点
                    // const updatedPositions = positions.filter(
                    //   (item) => item.pointName !== movedPoint.pointName
                    // );
                    // console.log(updatedPositions, 'updatedPositions');
                    // this.value = JSON.stringify(updatedPositions, null, 4);
// 遍历 positions 数组
                    for (let i = 0; i < positions.length; i++) {
                      // 找到当前移动的元素
                      if (positions[i].pointName === movedPoint.pointName) {
                        // 使用 splice 删除该元素
                        positions.splice(i, 1);

                        console.log('Removed item:', movedPoint);  // 输出被删除的元素
                        this.value = JSON.stringify(positions, null, 4); // 更新值

                        break; // 找到并删除后退出循环
                      }
                    }
                    // 将 movedPoint 添加到 rightPoints 数组
                    this.rightPoints.push(movedPoint);

                    // 将 pointId 添加到 unbindPointIds 数组
                    this.unbindPointIds.push(movedPoint.pointId);
                    // 从 bindingPointIds 中移除该 pointId
                    const bindingIndex = this.bindingPointIds.indexOf(
                      movedPoint.pointId
                    );
                    if (bindingIndex !== -1) {
                      this.bindingPointIds.splice(bindingIndex, 1);
                    }
                  }
                }
                // 如果是从物资柜内拿出来并移到柜外但不进入右侧列表
                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 = {
                    row: boundedRow,
                    col: boundedCol,
                    pointId: movedPoint.pointId,
                    pointName: movedPoint.pointName,
                    remark: movedPoint.remark,
                    prePointId: movedPoint.prePointId,
                    pointType: movedPoint.pointType,
                    pointTypeName: movedPoint.pointTypeName,
                    powerType: movedPoint.powerType,
                    powerTypeName: movedPoint.powerTypeName,
                    state: movedPoint.state,
                    pointIcon: movedPoint.pointIcon,
                    pointPicture: movedPoint.pointPicture,
                    mapImg: movedPoint.mapImg,
                  };

                  // 更新 positions 数组中的点位
                  // 使用深拷贝确保不影响原始数据
                  const updatedPositionCopy = JSON.parse(JSON.stringify(updatedPosition));
                  positions[indexToRemove] = updatedPositionCopy;

                  console.log(updatedPositionCopy, 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 = {
                    row: boundedRow,
                    col: boundedCol,
                    pointId: movedPoint.pointId,
                    pointName: movedPoint.pointName,
                    remark: movedPoint.remark,
                    prePointId: movedPoint.prePointId,
                    pointType: movedPoint.pointType,
                    pointTypeName: movedPoint.pointTypeName,
                    powerType: movedPoint.powerType,
                    powerTypeName: movedPoint.powerTypeName,
                    state: movedPoint.state,
                    pointIcon: movedPoint.pointIcon,
                    pointPicture: movedPoint.pointPicture,
                    mapImg: movedPoint.mapImg,
                  };

                  // 更新 positions 数组中的点位
                  const updatedPositionCopy = JSON.parse(JSON.stringify(updatedPosition));
                  positions[indexToRemove] = updatedPositionCopy;

                  console.log(updatedPositionCopy, positions[indexToRemove], '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 = {
                    row: boundedRow,
                    col: boundedCol,
                    pointId: movedPoint.pointId,
                    pointName: movedPoint.pointName,
                    remark: movedPoint.remark,
                    prePointId: movedPoint.prePointId,
                    pointType: movedPoint.pointType,
                    pointTypeName: movedPoint.pointTypeName,
                    powerType: movedPoint.powerType,
                    powerTypeName: movedPoint.powerTypeName,
                    state: movedPoint.state,
                    pointIcon: movedPoint.pointIcon,
                    pointPicture: movedPoint.pointPicture,
                    mapImg: movedPoint.mapImg,
                  };

                  // 更新 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);
                  }
                  // 从 unbindPointIds 中移除该 pointId
                  const unbindIndex = this.unbindPointIds.indexOf(
                    movedPoint.pointId
                  );
                  if (unbindIndex !== -1) {
                    this.unbindPointIds.splice(unbindIndex, 1);
                  }

                  // 将 pointId 添加到 bindingPointIds 数组
                  this.bindingPointIds.push(movedPoint.pointId);
                }
              }
            }

            // 清理 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();
          });
        };
      });
    },

    // 左侧的列表
    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 * 2;

          // 每行最多三个点，换行处理
          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);
        const updatedPositionCopy = JSON.parse(JSON.stringify(updatedPosition));
        positions[index] = updatedPositionCopy;

        console.log(updatedPositionCopy, 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("进入右侧盒子区域");

                // 如果之前已在右侧区域，需要移除值，并更新绑定点ID
                const index = valueArray.findIndex(
                  (item) => item.pointId === point.pointId
                );
                if (index !== -1) {
                  valueArray.splice(index, 1); // 从 valueArray 中删除该点
                }
                this.value = JSON.stringify(valueArray, null, 4);

                // 删除绑定点
                this.bindingPointIds = this.bindingPointIds.filter(
                  (id) => id !== point.pointId
                );

                // 将该点加入解绑点ID
                this.unbindPointIds.push(point.pointId);

                // 将点重新添加到 rightPoints
                this.rightPoints.push(point);
              } 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.push(updatedPointData);
                  this.value = JSON.stringify(valueArray, null, 4);
                }

                // 添加到绑定点ID数组
                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
                // );
                // 检查点是否已经存在于 valueArray 中
                const index = valueArray.findIndex(
                  (item) => item.pointId === point.pointId
                );
                if (index === -1) {
                  // 如果点位不存在，则新增
                  valueArray.push(updatedPointData);
                  this.value = JSON.stringify(valueArray, null, 4);
                }

                // 添加到绑定点ID数组
                this.bindingPointIds.push(point.pointId);

                // 从右侧盒子移除点
                this.rightPoints = this.rightPoints.filter(
                  (item) => item.pointId !== point.pointId
                );
                // 如果点不在目标区域，重新添加到 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-start;
  margin-bottom: 20px;
}
</style>
