<template>
  <div>
    <div class="tool-box" style="display: flex;justify-content: space-between;align-items: center;">
      <div>
        <p style="margin: 0;font-size: 13px;color: #FF6969;">点击绘制按钮开始绘制(黑边框内不可绘制,需在图片内绘制)，单击鼠标左键即是当前点绘制完成可绘制下一个点， 双击鼠标左键即本次绘制完成。</p>
      </div>
      <div>
        <el-button
          size="mini"
          :type="isDrawing ? 'warning' : 'primary'"
          @click="startDraw"
          >绘制区域</el-button
        >

        <el-button
          size="mini"
          type="danger"
          :disabled="isDrawing"
          @click="clearAll"
          >全部清除</el-button
        >
        <el-button
          size="mini"
          type="success"
          :disabled="isDrawing"
          @click="savePoints"
          >保存</el-button
        >
      </div>
    </div>
    <div class="canvas-wrap">
      <canvas id="imgCanvas" ref="canvaxbox"></canvas>
      <!--用来和鼠标进行交互操作的canvas-->
      <canvas
        id="drawCanvas"
        ref="canvas"
        :style="{ cursor: isDrawing ? 'crosshair' : 'default' }"
      >
      </canvas>
      <!--存储已生成的点线，避免被清空-->
      <canvas id="saveCanvas" ref="canvasSave"></canvas>
    </div>
  </div>
</template>
<script>
// import mqttHandle from "../../../utils/mqttHandler.js"
import mqtt from 'mqtt';
import { MqttClient } from 'mqtt'
// 状态变量
 // const client = mqtt.connect('ws://13.229.167.76:1884/mqtt')
 var client = MqttClient||null
export default {
  data() {
    return {
      imgUrl: "",
      isDrawing: false, // 是否正在绘制
      ratio: 1,
      imgWidth: 3020,
      imgHeight: 1080,
      wrapWidth: 600,
      wrapHeight: 300,
      canvasWidth: 600,
      canvasHeight: 300,
      drawingPoints: [],
      drawedPoints: [],
      imgCanvas: null,
      imgCtx: null,
      drawCanvas: null,
      drawCtx: null,
      saveCanvas: null,
      saveCtx: null,
      submitData: [
        // {"polygon":{"x1":0,"y1":0,"x2":1920,"y2":0,"x3":1920,"y3":1080,"x4":0,"y4":1080}},
        // {
        //   polygon: {
        //     x1: 700,
        //     y1: 273,
        //     x2: 975,
        //     y2: 278,
        //     x3: 1107,
        //     y3: 368,
        //     x4: 718,
        //     y4: 354,
        //   },
        // },
        // {
        //   polygon: {
        //     x1: 49,
        //     y1: 32,
        //     x2: 183,
        //     y2: 35,
        //     x3: 181,
        //     y3: 100,
        //     x4: 55,
        //     y4: 97,
        //   },
        // },
        // {
        //   polygon: {
        //     x1: 433,
        //     y1: 250,
        //     x2: 706,
        //     y2: 253,
        //     x3: 707,
        //     y3: 392,
        //     x4: 435,
        //     y4: 393,
        //   },
        // },
        // {
        //   polygon: {
        //     x1: 45,
        //     y1: 539,
        //     x2: 193,
        //     y2: 538,
        //     x3: 192,
        //     y3: 622,
        //     x4: 41,
        //     y4: 623,
        //     x5: 42,
        //     y5: 623,
        //   },
        // },
      ],
      connectionStatus:'',
      isConnected:false,
      connecting:false,
      messages:[{ type: 'sent' , content: '', timestamp: '' }],
      messageToSend:[],
      mqttConfig:{
      	url: 'ws://13.229.167.76:1884/mqtt',
      	topic: 'detection/rect'
      },
      mqttThemeName:{
      	url: 'ws://13.229.167.76:1884/mqtt',
      	topic: 'detection/rect'
      },
      // [
      //   {"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354}}
      // ]
    };
  },
  created() {

    console.log(JSON.parse(this.$route.query.src))
  },
  mounted() {
    this.$nextTick(() => {
      this.initCanvas();
      this.getImage();
    });
    // this.toggleConnection()
    // this.mqttzz()
    // setTimeout(() => {
    // }, 500);
  },
  methods: {
    // 创mqtt最终版
    mqttzz(){
      // 创建一个连接到MQTT broker的客户端实例
         // 连接成功后，订阅一个主题
         client.on('connect', function () {
           client.subscribe('detection/rect', function (err) {
             if (!err) {
               console.log('成功订阅 detection/rect 主题！')
             }
           })
         })

         // 监听订阅主题上的消息
         client.on('message', function (topic, message) {
           // 处理接收到的消息
           console.log('收到主题 ' + topic + ' 的消息: ' + message.toString())
         })
    },
    initCanvas() {
      // 初始化canvas画布

      let canvasWrap = document.getElementsByClassName("canvas-wrap");
      this.wrapWidth = canvasWrap[0].clientWidth;
      this.wrapHeight = canvasWrap[0].clientHeight;

      this.imgCanvas = document.getElementById("imgCanvas");
      this.imgCtx = this.imgCanvas.getContext("2d");

      // 绘制canvas
      this.drawCanvas = document.getElementById("drawCanvas");
      this.drawCtx = this.drawCanvas.getContext("2d");

      // 保存绘制区域 saveCanvas
      this.saveCanvas = document.getElementById("saveCanvas");
      this.saveCtx = this.saveCanvas.getContext("2d");
      // this.initImgCanvas()
    },
    initImgCanvas() {
      // 计算宽高比
      let ww = this.wrapWidth; // 画布宽度
      let wh = this.wrapHeight; // 画布高度
      let iw = this.imgWidth; // 图片宽度
      let ih = this.imgHeight; // 图片高度

      if (iw / ih < ww / wh) {
        // 以高为主
        this.ratio = ih / wh;
        this.canvasHeight = wh;
        this.canvasWidth = (wh * iw) / ih;
      } else {
        // 以宽为主
        this.ratio = iw / ww;
        this.canvasWidth = ww;
        this.canvasHeight = (ww * ih) / iw;
      }
      // 初始化画布大小
      this.imgCanvas.width = this.canvasWidth;
      this.imgCanvas.height = this.canvasHeight;
      this.drawCanvas.width = this.canvasWidth;
      this.drawCanvas.height = this.canvasHeight;
      this.saveCanvas.width = this.canvasWidth;
      this.saveCanvas.height = this.canvasHeight;

      // 图片加载绘制
      let img = document.createElement("img");
      img.src = this.imgUrl;
      img.onload = () => {
        console.log("图片已加载");
        this.imgCtx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight);
        this.renderDatas(); // 渲染原有数据
      };
    },
    startDraw() {
      // 绘制区域
      if (this.isDrawing) return;
      this.isDrawing = true;
      // 绘制逻辑
      this.drawCanvas.addEventListener("click", this.drawImageClickFn);
      this.drawCanvas.addEventListener("dblclick", this.drawImageDblClickFn);
      this.drawCanvas.addEventListener("mousemove", this.drawImageMoveFn);
    },
    clearAll() {
      // 清空所有绘制区域
      this.saveCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
      this.drawedPoints = [];
    },
    getImage() {
      // 这里请求接口 ...

      // this.imgUrl = "https://w.wallhaven.cc/full/6d/wallhaven-6d5k6x.jpg";
      // this.imgWidth = 1920;
      // this.imgHeight = 1080;
      this.imgUrl =JSON.parse(this.$route.query.src)
      this.imgWidth = 660;
      this.imgHeight = 380;
      this.imgUrl && this.initImgCanvas();
    },
    drawImageClickFn(e) {
      let drawCtx = this.drawCtx;
      if (e.offsetX || e.layerX) {
        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
        let lastPoint = this.drawingPoints[this.drawingPoints.length - 1] || [];
        if (lastPoint[0] !== pointX || lastPoint[1] !== pointY) {
          this.drawingPoints.push([pointX, pointY]);
        }
      }
    },
    drawImageMoveFn(e) {
      let drawCtx = this.drawCtx;
      if (e.offsetX || e.layerX) {
        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
        // 绘制
        drawCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);

        // 绘制点
        drawCtx.fillStyle = "blue";
        this.drawingPoints.forEach((item, i) => {
          drawCtx.beginPath();
          drawCtx.arc(...item, 6, 0, 180);
          drawCtx.fill(); //填充
        });

        // 绘制动态区域
        drawCtx.save();
        drawCtx.beginPath();
        this.drawingPoints.forEach((item, i) => {
          drawCtx.lineTo(...item);
        });
        drawCtx.lineTo(pointX, pointY);
        drawCtx.lineWidth = "3";
        drawCtx.strokeStyle = "blue";
        drawCtx.fillStyle = "rgba(255, 0, 0, 0.3)";
        drawCtx.stroke();
        drawCtx.fill(); //填充
        drawCtx.restore();
      }
    },
    drawImageDblClickFn(e) {
      let drawCtx = this.drawCtx;
      let saveCtx = this.saveCtx;
      if (e.offsetX || e.layerX) {
        let pointX = e.offsetX == undefined ? e.layerX : e.offsetX;
        let pointY = e.offsetY == undefined ? e.layerY : e.offsetY;
        let lastPoint = this.drawingPoints[this.drawingPoints.length - 1] || [];
        if (lastPoint[0] !== pointX || lastPoint[1] !== pointY) {
          this.drawingPoints.push([pointX, pointY]);
        }
      }
      // 清空绘制图层
      drawCtx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
      // 绘制区域至保存图层
      this.drawSaveArea(this.drawingPoints);

      this.drawedPoints.push(this.drawingPoints);
      this.drawingPoints = [];
      this.isDrawing = false;

      // 绘制结束逻辑
      this.drawCanvas.removeEventListener("click", this.drawImageClickFn);
      this.drawCanvas.removeEventListener("dblclick", this.drawImageDblClickFn);
      this.drawCanvas.removeEventListener("mousemove", this.drawImageMoveFn);
    },
    drawSaveArea(points) {
      // console.log(points, "points");
      if (points.length === 0) return;
      this.saveCtx.save();
      this.saveCtx.beginPath();
      points.forEach((item, i) => {
        this.saveCtx.lineTo(...item);
      });
      this.saveCtx.closePath();
      this.saveCtx.lineWidth = "2";
      this.saveCtx.fillStyle = "rgba(255,0, 255, 0.3)";
      this.saveCtx.strokeStyle = "red";
      this.saveCtx.stroke();
      this.saveCtx.fill(); //填充
      this.saveCtx.restore();
    },

    savePoints() {
      // 将画布坐标数据转换成提交数据
      let objectPoints = [];
      // "object": [{"polygon": {"x1":700,"y1":273,"x2":975,"y2":278,"x3":1107,"y3":368,"x4":718,"y4":354} }]
      objectPoints = this.drawedPoints.map((area) => {
        let polygon = {};
        area.forEach((point, i) => {
          polygon[`x${i + 1}`] = Math.round(point[0] * this.ratio);
          polygon[`y${i + 1}`] = Math.round(point[1] * this.ratio);
        });
        // console.log(polygon)
        return {
          polygon: polygon,
        };
      });
      this.submitData = objectPoints;
      console.log("最终提交数据", objectPoints);
      this.messageToSend = this.submitData
      // this.sendMessage()
      // this.$router.go(-1)
    },
    toggleConnection(){
      if (this.isConnected) {
        // 断开连接
        client.end()
        this.isConnected= false
        this.connectionStatus = 'Disconnected'
        return
      }

      // 建立连接
      this.connecting = true
      try {
        client= mqtt.connect(this.mqttConfig.url, {
          clientId: 'mqttjs_' + Math.random().toString(16).substr(2, 8),
          keepalive: 60,
          clean: true,
          connectTimeout: 4000,
          reconnectPeriod: 1000
        })
        client.on('connect', () => {
          this.isConnected = true
          this.connectionStatus= 'Connected'
          this.connecting = false
          console.log(3)
          // 订阅主题
          client.subscribe(this.mqttConfig.topic, (err) => {
            if (err) {
              console.error('Subscribe error:', err)
            }else{
               console.log('成功订阅 detection/rect 主题！')
            }

          })
        })
        client.on('message', (topic, message) => {
          // 接受信息
          console.log(topic,message)
          this.messages.unshift({
            type: 'received',
            content: message.toString(),
            timestamp: new Date().toLocaleTimeString()
          })
        })
        client.on('error', (err) => {
          console.error('MQTT Error:', err)
          this.connectionStatus= 'Error'
          this.connecting = false
        })
      } catch (error) {
        console.error('Connection error:', error)
        this.connectionStatus= 'Error'
        this.connecting = false
      }
    },
    sendMessage(){
      if (!client || !this.messageToSend) return
      this.messageToSend = JSON.stringify(this.messageToSend)
      console.log(this.messageToSend)
      client.publish(this.mqttConfig.topic, this.messageToSend)
      this.messages.unshift({
        type: 'sent',
        content: this.messageToSend,
        timestamp: new Date().toLocaleTimeString()
      })
      this.messageToSend = []
    },
    renderDatas() {

      // 将提交数据数据转换成画布坐标
      this.drawedPoints = this.submitData.map((item) => {
        let polygon = item.polygon;
        let points = [];
        for (let i = 1; i < Object.keys(polygon).length / 2 + 1; i++) {
          if (!isNaN(polygon[`x${i}`]) && !isNaN(polygon[`y${i}`])) {
            points.push([
              polygon[`x${i}`] / this.ratio,
              polygon[`y${i}`] / this.ratio,
            ]);
          }
        }
        this.drawSaveArea(points);
        return points;
      });
    },
  },
};
</script>
<style lang="scss" scoped>
.tool-box {
  width: 98%;
  height: 40px;
  padding: 5px 30px;
  margin: 20px auto 0;
  box-sizing: border-box;
  text-align: right;
}
.canvas-wrap {
  // width: 80vw;
  // height: 45vw;
  width:88%;
  height: 33.75vw;
  margin: 0px auto;
  background-color: #000; //#fff;
  border: 3px;
  border-color: #333;
  position: relative;
}
#imgCanvas,
#drawCanvas,
#saveCanvas {
  background: rgba(255, 0, 255, 0);
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
}
#drawCanvas {
  z-index: 2;
}
</style>

