<template>
  <div>
    <div>
      <div class="draw-tool">
        <div class="tool-group">
          <div
            @click="!isCapturing && handleCaptureVideoImg()"
            :class="{ 'loading-state': isCapturing }"
          >
            <i class="el-icon-camera-solid" style="font-size: 26px"></i>
            <br />
            <span>获取抓图</span>
            <div v-if="isCapturing" class="capture-loading">
              <i class="el-icon-loading"></i>
            </div>
          </div>
          <div @click="isTranslate = false">
            <!-- <el-icon :size="26">
              <Close />
            </el-icon> -->
            <svg-icon icon-class="polygon" style="font-size: 26px" />
            <br />
            <span>多边形</span>
          </div>
          <div @click="handleResetDraw">
            <!-- <el-icon :size="26">
              <Refresh />
            </el-icon> -->
            <svg-icon
              icon-class="goback"
              style="font-size: 26px; color: '#606266'"
            />
            <br />
            <span>撤销</span>
          </div>
          <div @click="handleDrawClean">
            <!-- <el-icon :size="26">
              <Delete />
            </el-icon> -->
            <i class="el-icon-brush" style="font-size: 26px"></i>
            <br />
            <span>清空</span>
          </div>
          <el-upload
            :action="serviceUrl + '/common/upload'"
            :limit="1"
            :headers="headers"
            :show-file-list="false"
            :before-upload="beforeUpload"
            :on-success="handleUploadSuccess"
          >
            <div class="upload-btn">
              <i class="el-icon-picture" style="font-size: 26px"></i>
              <br />
              <span>上传图片</span>
            </div>
          </el-upload>
        </div>
      </div>
      <div id="DrawWrap">
        <canvas id="DrawCompoent" @click="handleClickCanvas"></canvas>
      </div>
    </div>
  </div>
</template>

<script>
import { getToken } from "@/utils/auth";
import { getVideoAnalysisTaskScreenshot } from "@/api/business/videoanalysistasks.js";
export default {
  components: {},
  props: {
    val: {
      type: String,
      required: true,
      default: "",
    },

    callback: {
      type: Function,
      required: true,
    },
    cameraId: {
      type: String,
      required: true,
      default: "",
    },
  },
  data() {
    return {
      serviceUrl: process.env.VUE_APP_BASE_API,
      imgURL: "",
      nodeStr: "",
      node: [],
      canvasBoxConf: {
        width: 200,
        height: 200,
        el: null,
      },
      isTranslate: false,
      fileList: [],
      canvasContext: null,
      headers: {
        Authorization: "Bearer " + getToken(),
      },
      isCapturing: false, // 新增加载状态
    };
  },
  created() {
    this.handleCaptureVideoImg();
  },
  methods: {
    parseCoordinates(str) {
      const regex = /\((\d+),(\d+)\)/g;
      const coordinates = [];
      let match;
      while ((match = regex.exec(str)) !== null) {
        coordinates.push({
          x: parseInt(match[1], 10),
          y: parseInt(match[2], 10),
        });
      }
      return coordinates;
    },
    autoComputePercentage() {
      const _w = 1920;
      const _h = 1080;
      let _str = "";
      const { width, height } = this.canvasBoxConf;
      this.node.forEach((info) => {
        _str += `(${((info.x / width) * _w).toFixed(0)},${(
          (info.y / height) *
          _h
        ).toFixed(0)}),`;
      });
      return _str.slice(0, -1);
    },
    beforeUpload(file) {
      const isImage = ["image/jpeg", "image/png", "image/jpg"].includes(
        file.type
      );
      if (!isImage) {
        this.$modal.msgError("仅支持JPEG/JPG/PNG格式");
        return false;
      }
      return true;
    },
    handleUploadSuccess(res) {
      if (res.code === 200) {
        this.updateImageSource(res.url);
      }
    },
    handleCaptureVideoImg() {
      this.isCapturing = true; // 开始加载
      this.$nextTick(() => {
        getVideoAnalysisTaskScreenshot(this.cameraId)
          .then((res) => {
            if (res.code === 200) {
              // 创建新的Image对象并等待加载
              this.$modal.msgSuccess("截图抓取成功");
              this.updateImageSource("data:image/jpg;base64," + res.data);
            }
          })
          .finally(() => {
            this.isCapturing = false; // 无论成功失败都关闭加载
          });
      });
    },
    updateImageSource(url) {
      const newImg = new Image();
      newImg.src = url;

      newImg.onload = () => {
        // 图片加载完成后再更新imgURL并绘制
        this.imgURL = newImg.src;
        this.$nextTick(() => {
          this.initCanvasImg(() => {
            this.drawCanvas();
          });
        });
      };

      // 处理加载错误的情况
      newImg.onerror = () => {
        console.error("图片加载失败");
        this.$modal.msgError("图片加载失败");
      };
    },
    handleClickCanvas(e) {
      if (this.isTranslate) return;

      // 获取canvas元素
      const canvas = e.target;
      const rect = canvas.getBoundingClientRect();

      // 计算缩放比例
      const scaleX = canvas.width / rect.width;
      const scaleY = canvas.height / rect.height;

      // 计算精确坐标
      const offsetX = (e.clientX - rect.left) * scaleX;
      const offsetY = (e.clientY - rect.top) * scaleY;

      // 多边形闭合判断
      if (this.node.length > 2) {
        const first = this.node[0];
        const last = this.node[this.node.length - 1];
        if (first.x === last.x && first.y === last.y) {
          this.$modal.msgWarning("多边形已闭合,不可继续绘制");
          return;
        }
      }
      // 更新节点列表
      this.node.push({ x: offsetX, y: offsetY });
      // 绘制画布
      this.drawCanvas();

      // 回调坐标计算
      this.callback(this.autoComputePercentage());
      // this.callback(this.autoComputePercentage());
    },
    updateNodeList(e) {
      const { offsetX, offsetY } = e;
      const curNode = { x: offsetX, y: offsetY };
      if (this.node.length > 2) {
        const lastNode = this.node[0];
        if (
          Math.abs(offsetX - lastNode.x) < 15 &&
          Math.abs(offsetY - lastNode.y) < 15
        ) {
          this.node.push(lastNode);
          return;
        }
      }
      this.node.push(curNode);
    },
    drawCanvas() {
      const ctx = this.canvasContext;
      // 添加空数组检查
      if (this.node.length === 0) return;

      const drawLine = (prev, next) => {
        ctx.beginPath();
        ctx.moveTo(prev.x, prev.y);
        ctx.lineTo(next.x, next.y);
        ctx.strokeStyle = "red";
        ctx.lineWidth = 5;
        ctx.stroke();
      };

      // 添加初始值参数
      this.node.reduce((prev, next) => {
        drawLine(prev, next);
        return next;
      }, this.node[0]); // 使用数组第一个元素作为初始值
    },
    initCanvasImg(callback) {
      const ctx = this.canvasContext;
      // 先清空画布
      ctx.clearRect(0, 0, this.canvasBoxConf.width, this.canvasBoxConf.height);

      const img = new Image();
      img.crossOrigin = "anonymous"; // 添加跨域属性
      img.src = this.imgURL;

      img.onload = () => {
        // 重新设置canvas尺寸
        ctx.canvas.width = img.naturalWidth;
        ctx.canvas.height = img.naturalHeight;

        ctx.drawImage(img, 0, 0, ctx.canvas.width, ctx.canvas.height);
        if (callback) callback();
      };
    },
    handleDrawClean() {
      if (this.node.length === 0) {
        this.$modal.msgWarning("当前画布为空");
        return;
      }
      this.canvasContext.clearRect(
        0,
        0,
        this.canvasBoxConf.width,
        this.canvasBoxConf.height
      );
      this.initCanvasImg();
      this.node = [];
    },
    handleResetDraw() {
      if (this.node.length === 0) {
        this.$modal.msgWarning("无可撤销内容");
        return;
      }
      this.node.pop();
      this.initCanvasImg(() => this.drawCanvas());
    },
  },
  mounted() {
    const canvas = document.getElementById("DrawCompoent");
    const canvasWrap = document.getElementById("DrawWrap");

    // 获取容器实际显示尺寸
    const rect = canvasWrap.getBoundingClientRect();
    const dpr = window.devicePixelRatio || 1;

    // 设置canvas物理像素尺寸
    canvas.width = Math.floor(rect.width * dpr);
    canvas.height = Math.floor(rect.height * dpr);

    // 设置CSS显示尺寸
    canvas.style.width = rect.width + "px";
    canvas.style.height = rect.height + "px";

    // 初始化坐标系
    const ctx = canvas.getContext("2d");
    ctx.scale(dpr, dpr);

    // 保存canvas配置
    this.canvasContext = ctx;
    this.canvasBoxConf = {
      width: rect.width,
      height: rect.height,
      el: canvas,
      dpr: dpr,
    };
    // this.fempegVideoInit();
    this.nodeStr = this.val;

    if (this.nodeStr) {
      this.node = this.parseCoordinates(this.nodeStr).map((item) => ({
        x: ((item.x / 1920) * this.canvasBoxConf.width).toFixed(0),
        y: ((item.y / 1080) * this.canvasBoxConf.height).toFixed(0),
      }));
    }
    this.initCanvasImg(() => this.drawCanvas());
  },
};
</script>

<style lang="scss" scoped>
#canvas-4 {
  position: fixed;
  top: -10000px;
}

#canvas-4 > canvas {
  width: 600px;
  height: 350px;
}

.draw-tool {
  height: 70px;
  margin: 20px 0;
  display: flex;
  padding-top: 5px;
  justify-content: space-between;
  background: #f8f8f9;
  border-radius: 10px;

  .tool-group {
    display: flex;
    * {
      user-select: none; // 禁止文字选中
      -webkit-user-select: none;
      -moz-user-select: none;
      -ms-user-select: none;
    }
    > div {
      width: 80px;
      text-align: center;
      cursor: pointer;
      padding: 8px;
      font-size: 14px;
      &:hover {
        background: #f0f7ff;
      }
    }
    .upload-btn {
      width: 80px;
      text-align: center;
      cursor: pointer;
      font-size: 14px;
      &:hover {
        background: #f0f7ff;
      }
    }
  }
}

#DrawCompoent {
  height: 100%;
  width: 100%;
  background-color: #f8f8f9;
}

#DrawWrap {
  height: 300px;
  position: relative;
  transition: all 0.2s;
}
.loading-state {
  position: relative;
  cursor: wait !important;
  opacity: 0.7;
}

.capture-loading {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 20px;
  color: #409eff;
}
</style>
