import { onMounted, onUnmounted, Ref, nextTick } from "vue";
import { SetupContext } from "@vue/runtime-core";
import {
  cutOutBoxBorder,
  movePositionType,
  zoomCutOutBoxReturnType,
  drawCutOutBoxReturnType,
  positionInfoType
} from "@/module/type/ComponentType";
import { drawMasking } from "@/module/split-methods/DrawMasking";
import html2canvas from "html2canvas";
import PlugInParameters from "@/module/main-entrance/PlugInParameters";
import { fixedData, nonNegativeData } from "@/module/common-methords/FixedData";
import { zoomCutOutBoxPosition } from "@/module/common-methords/ZoomCutOutBoxPosition";
import { saveBorderArrInfo } from "@/module/common-methords/SaveBorderArrInfo";
import { drawCutOutBox } from "@/module/split-methods/DrawCutOutBox";
import InitData from "@/module/main-entrance/InitData";
import { calculateToolLocation } from "@/module/split-methods/CalculateToolLocation";
import { drawRectangle } from "@/module/split-methods/DrawRectangle";
import { drawCircle } from "@/module/split-methods/DrawCircle";
import { drawLineArrow } from "@/module/split-methods/DrawLineArrow";
import { drawPencil, initPencil } from "@/module/split-methods/DrawPencil";
import { drawText } from "@/module/split-methods/DrawText";
import { saveCanvasToImage } from "@/module/common-methords/SaveCanvasToImage";
import { saveCanvasToBase64 } from "@/module/common-methords/SaveCanvasToBase64";
import { drawMosaic } from "@/module/split-methods/DrawMosaic";
import { calculateOptionIcoPosition } from "@/module/split-methods/CalculateOptionIcoPosition";
import { setSelectedClassName } from "@/module/common-methords/SetSelectedClassName";
import adapter from "webrtc-adapter";
import { getDrawBoundaryStatus } from "@/module/split-methods/BoundaryJudgment";

export default class EventMonitoring {
  // 当前实例的响应式data数据
  private readonly data: InitData;
  private emit: ((event: string, ...args: any[]) => void) | undefined;

  // 截图区域canvas容器
  private screenShortController: Ref<HTMLCanvasElement | null>;
  // 截图工具栏dom
  private toolController: Ref<HTMLDivElement | null>;
  // 截图图片存放容器
  private screenShortImageController: HTMLCanvasElement | null;
  // 截图区域画布
  private screenShortCanvas: CanvasRenderingContext2D | undefined;
  // 文本区域dom
  private textInputController: Ref<HTMLDivElement | null> | undefined;
  // 截图工具栏画笔选项dom
  private optionController: Ref<HTMLDivElement | null> | undefined;
  private optionIcoController: Ref<HTMLDivElement | null> | undefined;
  // video容器用于存放屏幕MediaStream流
  private readonly videoController: HTMLVideoElement;
  // 图形位置参数
  private drawGraphPosition: positionInfoType = {
    startX: 0,
    startY: 0,
    width: 0,
    height: 0
  };
  // 临时图形位置参数
  private tempGraphPosition: positionInfoType = {
    startX: 0,
    startY: 0,
    width: 0,
    height: 0
  };
  // 裁剪框边框节点坐标事件
  private cutOutBoxBorderArr: Array<cutOutBoxBorder> = [];
  // 裁剪框顶点边框直径大小
  private borderSize = 10;
  // 当前操作的边框节点
  private borderOption: number | null = null;

  // 点击裁剪框时的鼠标坐标
  private movePosition: movePositionType = {
    moveStartX: 0,
    moveStartY: 0
  };

  // 裁剪框修剪状态
  private draggingTrim = false;
  // 裁剪框拖拽状态
  private dragging = false;

  // 鼠标点击状态
  private clickFlag = false;
  // 鼠标拖动状态
  private dragFlag = false;
  // 单击截取屏启用状态
  private clickCutFullScreen = false;
  // 全屏截取状态
  private getFullScreenStatus = false;
  // 上一个裁剪框坐标信息
  private drawGraphPrevX = 0;
  private drawGraphPrevY = 0;

  // 当前点击的工具栏条目
  private toolName = "";
  private fontSize = 17;
  // 撤销点击次数
  private undoClickNum = 0;
  // 最大可撤销次数
  private maxUndoNum = 15;
  // 马赛克涂抹区域大小
  private degreeOfBlur = 5;
  private history: Array<Record<string, any>> = [];
  // 文本输入框位置
  private textInputPosition: { mouseX: number; mouseY: number } = {
    mouseX: 0,
    mouseY: 0
  };

  constructor(props: Record<string, any>, context: SetupContext<any>) {
    // 实例化响应式data
    this.data = new InitData();
    // 获取截图区域canvas容器
    this.screenShortController = this.data.getScreenShortController();
    this.toolController = this.data.getToolController();
    this.textInputController = this.data.getTextInputController();
    this.optionController = this.data.getOptionController();
    this.optionIcoController = this.data.getOptionIcoController();
    this.videoController = document.createElement("video");
    this.videoController.autoplay = true;
    this.screenShortImageController = document.createElement("canvas");
    // 设置实例与属性
    this.data.setPropsData(context.emit);

    onMounted(() => {
      this.emit = this.data.getEmit();
      const plugInParameters = new PlugInParameters();
      // 单击截屏启用状态
      this.clickCutFullScreen = plugInParameters.getClickCutFullScreenStatus();
      // 设置需要隐藏的工具栏图标
      this.data.setHiddenToolIco(plugInParameters.getHiddenToolIco());
      // 设置截图区域canvas宽高
      this.data.setScreenShortInfo(window.innerWidth, window.innerHeight);
      if (this.screenShortImageController == null) return;
      // 设置截图图片存放容器宽高
      this.screenShortImageController.width = window.innerWidth;
      this.screenShortImageController.height = window.innerHeight;
      if (plugInParameters.getWebRtcStatus()) {
        // 设置为屏幕宽高
        this.data.setScreenShortInfo(window.screen.width, window.screen.height);
        // 设置为屏幕宽高
        this.screenShortImageController.width = window.screen.width;
        this.screenShortImageController.height = window.screen.height;
      }
      // 获取截图区域画canvas容器画布
      const context = this.screenShortController.value?.getContext("2d");
      if (context == null) return;
      if (!plugInParameters.getWebRtcStatus()) {
        console.log("#######################  test patch package 截屏 #######################");
        console.log("#######################  html2canvas截屏 #######################")
        // html2canvas截屏
        html2canvas(document.body, {useCORS: true, allowTaint: true}).then(canvas => {
          // 装载截图的dom为null则退出
          if (this.screenShortController.value == null) return;
          // 调整截屏容器层级
          this.screenShortController.value.style.zIndex =
            plugInParameters.getLevel() + "";
          // 调整截图工具栏层级
          if (this.toolController.value == null) return;
          this.toolController.value.style.zIndex = `${plugInParameters.getLevel() +
            1}`;

          // 存放html2canvas截取的内容
          this.screenShortImageController = canvas;
          // 存储屏幕截图
          this.data.setScreenShortImageController(canvas);

          // 赋值截图区域canvas画布
          this.screenShortCanvas = context;
          // 绘制蒙层
          drawMasking(context);

          // 添加监听
          this.screenShortController.value?.addEventListener(
            "mousedown",
            this.mouseDownEvent
          );
          this.screenShortController.value?.addEventListener(
            "mousemove",
            this.mouseMoveEvent
          );
          this.screenShortController.value?.addEventListener(
            "mouseup",
            this.mouseUpEvent
          );
        });
        return;
      }
      // 开始捕捉屏幕
      this.startCapture().then(() => {
        setTimeout(() => {
          // 装载截图的dom为null则退出
          if (this.screenShortController.value == null) return;
          if (this.screenShortImageController == null) return;
          const imageContext = this.screenShortImageController.getContext("2d");
          if (imageContext == null) return;
          // 将获取到的屏幕截图绘制到图片容器里
          imageContext.drawImage(
            this.videoController,
            0,
            0,
            this.screenShortImageController.width,
            this.screenShortImageController.height
          );
          // 存储屏幕截图
          this.data.setScreenShortImageController(
            this.screenShortImageController
          );

          // 赋值截图区域canvas画布
          this.screenShortCanvas = context;
          // 绘制蒙层
          drawMasking(context);

          // 添加监听
          this.screenShortController.value?.addEventListener(
            "mousedown",
            this.mouseDownEvent
          );
          this.screenShortController.value?.addEventListener(
            "mousemove",
            this.mouseMoveEvent
          );
          this.screenShortController.value?.addEventListener(
            "mouseup",
            this.mouseUpEvent
          );
          // 停止捕捉屏幕
          this.stopCapture();
          // 调整截屏容器层级
          this.screenShortController.value.style.zIndex =
            plugInParameters.getLevel() + "";
          // 调整截图工具栏层级
          if (this.toolController.value == null) return;
          this.toolController.value.style.zIndex = `${plugInParameters.getLevel() +
            1}`;
        }, 500);
      });
    });

    onUnmounted(() => {
      // 初始化initData中的数据
      this.data.setInitStatus(true);
    });
  }

  // 开始捕捉屏幕
  private startCapture = async () => {
    let captureStream = null;

    try {
      // eslint-disable-next-line @typescript-eslint/ban-ts-ignore
      // @ts-ignore
      // 捕获屏幕
      captureStream = await navigator.mediaDevices.getDisplayMedia();
      // 将MediaStream输出至video标签
      this.videoController.srcObject = captureStream;
    } catch (err) {
      // 销毁组件
      this.resetComponent();
      throw "浏览器不支持webrtc或者用户未授权, 浏览器名称" +
        adapter.browserDetails.browser +
        "，浏览器版本号" +
        adapter.browserDetails.version +
        err;
    }
    return captureStream;
  };

  // 停止捕捉屏幕
  private stopCapture = () => {
    const srcObject = this.videoController.srcObject;
    if (srcObject && "getTracks" in srcObject) {
      const tracks = srcObject.getTracks();
      tracks.forEach(track => track.stop());
      this.videoController.srcObject = null;
    }
  };

  // 鼠标按下事件
  private mouseDownEvent = (event: MouseEvent) => {
    // 当前操作的是撤销
    if (this.toolName == "undo") return;
    this.dragging = true;
    this.clickFlag = true;
    const mouseX = nonNegativeData(event.offsetX);
    const mouseY = nonNegativeData(event.offsetY);

    // 如果当前操作的是截图工具栏
    if (this.data.getToolClickStatus().value) {
      // 记录当前鼠标开始坐标
      this.drawGraphPosition.startX = mouseX;
      this.drawGraphPosition.startY = mouseY;
    }
    // 当前操作的是画笔
    if (this.toolName == "brush" && this.screenShortCanvas) {
      // 初始化画笔
      initPencil(this.screenShortCanvas, mouseX, mouseY);
    }
    // 当前操作的文本
    if (
      this.toolName == "text" &&
      this.textInputController?.value &&
      this.screenShortController?.value &&
      this.screenShortCanvas
    ) {
      // 修改鼠标样式
      this.screenShortController.value.style.cursor = "text";
      // 显示文本输入区域
      this.data.setTextStatus(true);
      // 判断输入框位置是否变化
      if (
        this.textInputPosition.mouseX != 0 &&
        this.textInputPosition.mouseY != 0 &&
        this.textInputPosition.mouseX != mouseX &&
        this.textInputPosition.mouseY != mouseY
      ) {
        drawText(
          this.textInputController.value?.innerText,
          this.textInputPosition.mouseX,
          this.textInputPosition.mouseY,
          this.data.getSelectedColor().value,
          this.fontSize,
          this.screenShortCanvas
        );
        // 清空文本输入区域的内容
        this.textInputController.value.innerHTML = "";
        // 保存绘制记录
        this.addHistory();
      }
      // 计算文本框显示位置
      const textMouseX = mouseX - 15;
      const textMouseY = mouseY - 15;
      // 修改文本区域位置
      this.textInputController.value.style.left = textMouseX + "px";
      this.textInputController.value.style.top = textMouseY + "px";
      setTimeout(() => {
        // 获取焦点
        if (this.textInputController?.value) {
          this.textInputController.value.focus();
          // 记录当前输入框位置
          this.textInputPosition = { mouseX: mouseX, mouseY: mouseY };
        }
      });
    }

    // 如果操作的是裁剪框
    if (this.borderOption) {
      // 设置为拖动状态
      this.draggingTrim = true;
      // 记录移动时的起始点坐标
      this.movePosition.moveStartX = mouseX;
      this.movePosition.moveStartY = mouseY;
    } else {
      // 保存当前裁剪框的坐标
      this.drawGraphPrevX = this.drawGraphPosition.startX;
      this.drawGraphPrevY = this.drawGraphPosition.startY;
      // 绘制裁剪框,记录当前鼠标开始坐标
      this.drawGraphPosition.startX = mouseX;
      this.drawGraphPosition.startY = mouseY;
    }
  };

  // 鼠标移动事件
  private mouseMoveEvent = (event: MouseEvent) => {
    if (
      this.screenShortCanvas == null ||
      this.screenShortController.value == null ||
      this.toolName == "undo"
    ) {
      return;
    }

    // 工具栏未选择且鼠标处于按下状态时
    if (!this.data.getToolClickStatus().value && this.dragging) {
      // 修改拖动状态为true;
      this.dragFlag = true;
      // 隐藏截图工具栏
      this.data.setToolStatus(false);
    }
    this.clickFlag = false;
    // 获取当前绘制中的工具位置信息
    const { startX, startY, width, height } = this.drawGraphPosition;
    // 获取当前鼠标坐标
    const currentX = nonNegativeData(event.offsetX);
    const currentY = nonNegativeData(event.offsetY);
    // 绘制中工具的临时宽高
    const tempWidth = currentX - startX;
    const tempHeight = currentY - startY;
    // 工具栏绘制
    if (this.data.getToolClickStatus().value && this.dragging) {
      // 获取裁剪框位置信息
      const cutBoxPosition = this.data.getCutOutBoxPosition();
      // 绘制中工具的起始x、y坐标不能小于裁剪框的起始坐标
      // 绘制中工具的起始x、y坐标不能大于裁剪框的结束标作
      // 当前鼠标的x坐标不能小于裁剪框起始x坐标，不能大于裁剪框的结束坐标
      // 当前鼠标的y坐标不能小于裁剪框起始y坐标，不能大于裁剪框的结束坐标
      if (
        !getDrawBoundaryStatus(startX, startY, cutBoxPosition) ||
        !getDrawBoundaryStatus(currentX, currentY, cutBoxPosition)
      )
        return;
      // 当前操作的不是马赛克则显示最后一次画布绘制时的状态
      if (this.toolName != "mosaicPen") {
        this.showLastHistory();
      }
      switch (this.toolName) {
        case "square":
          drawRectangle(
            startX,
            startY,
            tempWidth,
            tempHeight,
            this.data.getSelectedColor().value,
            this.data.getPenSize().value,
            this.screenShortCanvas,
            this.screenShortController.value as HTMLCanvasElement,
            this.screenShortImageController as HTMLCanvasElement
          );
          break;
        case "round":
          drawCircle(
            this.screenShortCanvas,
            currentX,
            currentY,
            startX,
            startY,
            this.data.getPenSize().value,
            this.data.getSelectedColor().value
          );
          break;
        case "right-top":
          drawLineArrow(
            this.screenShortCanvas,
            startX,
            startY,
            currentX,
            currentY,
            30,
            10,
            this.data.getPenSize().value,
            this.data.getSelectedColor().value
          );
          break;
        case "brush":
          // 画笔绘制
          drawPencil(
            this.screenShortCanvas,
            currentX,
            currentY,
            this.data.getPenSize().value,
            this.data.getSelectedColor().value
          );
          break;
        case "mosaicPen":
          // 绘制马赛克，为了确保鼠标位置在绘制区域中间，所以对x、y坐标进行-10处理
          drawMosaic(
            currentX - 10,
            currentY - 10,
            this.data.getPenSize().value,
            this.degreeOfBlur,
            this.screenShortCanvas
          );
          break;
        default:
          break;
      }
      return;
    }
    // 执行裁剪框操作函数
    this.operatingCutOutBox(
      currentX,
      currentY,
      startX,
      startY,
      width,
      height,
      this.screenShortCanvas
    );
    // 如果鼠标未点击或者当前操作的是裁剪框都return
    if (!this.dragging || this.draggingTrim) return;
    // 绘制裁剪框
    this.tempGraphPosition = drawCutOutBox(
      startX,
      startY,
      tempWidth,
      tempHeight,
      this.screenShortCanvas,
      this.borderSize,
      this.screenShortController.value as HTMLCanvasElement,
      this.screenShortImageController as HTMLCanvasElement
    ) as drawCutOutBoxReturnType;
  };

  // 鼠标抬起事件
  private mouseUpEvent = () => {
    // 当前操作的是撤销
    if (this.toolName == "undo") return;
    // 绘制结束
    this.dragging = false;
    this.draggingTrim = false;
    if (
      this.screenShortController.value == null ||
      this.screenShortCanvas == null ||
      this.screenShortImageController == null
    ) {
      return;
    }

    // 工具栏未点击且鼠标未拖动且单击截屏状态为false则复原裁剪框位置
    if (
      !this.data.getToolClickStatus().value &&
      !this.dragFlag &&
      !this.clickCutFullScreen
    ) {
      // 复原裁剪框的坐标
      this.drawGraphPosition.startX = this.drawGraphPrevX;
      this.drawGraphPosition.startY = this.drawGraphPrevY;
      return;
    }
    // 调用者尚未拖拽生成选区
    // 鼠标尚未拖动
    // 单击截取屏幕状态为true
    // 则截取整个屏幕
    const cutBoxPosition = this.data.getCutOutBoxPosition();
    if (
      cutBoxPosition.width === 0 &&
      cutBoxPosition.height === 0 &&
      cutBoxPosition.startX === 0 &&
      cutBoxPosition.startY === 0 &&
      !this.dragFlag &&
      this.clickCutFullScreen
    ) {
      this.getFullScreenStatus = true;
      // 设置裁剪框位置为全屏
      this.tempGraphPosition = drawCutOutBox(
        0,
        0,
        this.screenShortController.value.width - this.borderSize / 2,
        this.screenShortController.value.height - this.borderSize / 2,
        this.screenShortCanvas,
        this.borderSize,
        this.screenShortController.value,
        this.screenShortImageController
      ) as drawCutOutBoxReturnType;
    }
    if (this.data.getToolClickStatus().value) {
      // 保存绘制记录
      this.addHistory();
      return;
    }
    // 保存绘制后的图形位置信息
    this.drawGraphPosition = this.tempGraphPosition;
    // 如果工具栏未点击则保存裁剪框位置
    if (!this.data.getToolClickStatus().value) {
      const { startX, startY, width, height } = this.drawGraphPosition;
      this.data.setCutOutBoxPosition(startX, startY, width, height);
    }
    // 保存边框节点信息
    this.cutOutBoxBorderArr = saveBorderArrInfo(
      this.borderSize,
      this.drawGraphPosition
    );
    if (this.screenShortController.value != null) {
      // 修改鼠标状态为拖动
      this.screenShortController.value.style.cursor = "move";
      // 复原拖动状态
      this.dragFlag = false;
      // 显示截图工具栏
      this.data.setToolStatus(true);
      nextTick().then(() => {
        if (this.toolController.value != null) {
          // 计算截图工具栏位置
          const toolLocation = calculateToolLocation(
            this.drawGraphPosition,
            this.toolController.value?.offsetWidth
          );
          // 当前截取的是全屏，则修改工具栏的位置到截图容器最底部，防止超出
          if (this.getFullScreenStatus) {
            toolLocation.mouseY -= 64;
          }
          // 设置截图工具栏位置
          this.data.setToolInfo(toolLocation.mouseX, toolLocation.mouseY);
          // 状态重置
          this.getFullScreenStatus = false;
        }
      });
    }
  };

  /**
   * 操作裁剪框
   * @param currentX 裁剪框当前x轴坐标
   * @param currentY 裁剪框当前y轴坐标
   * @param startX 鼠标x轴坐标
   * @param startY 鼠标y轴坐标
   * @param width 裁剪框宽度
   * @param height 裁剪框高度
   * @param context 需要进行绘制的canvas画布
   * @private
   */
  private operatingCutOutBox(
    currentX: number,
    currentY: number,
    startX: number,
    startY: number,
    width: number,
    height: number,
    context: CanvasRenderingContext2D
  ) {
    // canvas元素不存在
    if (this.screenShortController.value == null) {
      return;
    }
    // 获取鼠标按下时的坐标
    const { moveStartX, moveStartY } = this.movePosition;

    // 裁剪框边框节点事件存在且裁剪框未进行操作，则对鼠标样式进行修改
    if (this.cutOutBoxBorderArr.length > 0 && !this.draggingTrim) {
      // 标识鼠标是否在裁剪框内
      let flag = false;
      // 判断鼠标位置
      context.beginPath();
      for (let i = 0; i < this.cutOutBoxBorderArr.length; i++) {
        context.rect(
          this.cutOutBoxBorderArr[i].x,
          this.cutOutBoxBorderArr[i].y,
          this.cutOutBoxBorderArr[i].width,
          this.cutOutBoxBorderArr[i].height
        );
        // 当前坐标点处于8个可操作点上，修改鼠标指针样式
        if (context.isPointInPath(currentX, currentY)) {
          switch (this.cutOutBoxBorderArr[i].index) {
            case 1:
              if (this.data.getToolClickStatus().value) {
                this.screenShortController.value.style.cursor = "crosshair";
              } else {
                this.screenShortController.value.style.cursor = "move";
              }
              break;
            case 2:
              // 工具栏被点击则不改变指针样式
              if (this.data.getToolClickStatus().value) break;
              this.screenShortController.value.style.cursor = "ns-resize";
              break;
            case 3:
              // 工具栏被点击则不改变指针样式
              if (this.data.getToolClickStatus().value) break;
              this.screenShortController.value.style.cursor = "ew-resize";
              break;
            case 4:
              // 工具栏被点击则不改变指针样式
              if (this.data.getToolClickStatus().value) break;
              this.screenShortController.value.style.cursor = "nwse-resize";
              break;
            case 5:
              // 工具栏被点击则不改变指针样式
              if (this.data.getToolClickStatus().value) break;
              this.screenShortController.value.style.cursor = "nesw-resize";
              break;
            default:
              break;
          }
          this.borderOption = this.cutOutBoxBorderArr[i].option;
          flag = true;
          break;
        }
      }
      context.closePath();
      if (!flag) {
        // 鼠标移出裁剪框重置鼠标样式
        this.screenShortController.value.style.cursor = "default";
        // 重置当前操作的边框节点为null
        this.borderOption = null;
      }
    }

    // 裁剪框正在被操作
    if (this.draggingTrim) {
      // 当前操作节点为1时则为移动裁剪框
      if (this.borderOption === 1) {
        // 计算要移动的x轴坐标
        const x = fixedData(
          currentX - (moveStartX - startX),
          width,
          this.screenShortController.value.width
        );
        // 计算要移动的y轴坐标
        const y = fixedData(
          currentY - (moveStartY - startY),
          height,
          this.screenShortController.value.height
        );
        // 重新绘制裁剪框
        this.tempGraphPosition = drawCutOutBox(
          x,
          y,
          width,
          height,
          context,
          this.borderSize,
          this.screenShortController.value as HTMLCanvasElement,
          this.screenShortImageController as HTMLCanvasElement
        ) as drawCutOutBoxReturnType;
      } else {
        // 裁剪框其他8个点的拖拽事件
        const {
          tempStartX,
          tempStartY,
          tempWidth,
          tempHeight
        } = zoomCutOutBoxPosition(
          currentX,
          currentY,
          startX,
          startY,
          width,
          height,
          this.borderOption as number
        ) as zoomCutOutBoxReturnType;
        // 绘制裁剪框
        this.tempGraphPosition = drawCutOutBox(
          tempStartX,
          tempStartY,
          tempWidth,
          tempHeight,
          context,
          this.borderSize,
          this.screenShortController.value as HTMLCanvasElement,
          this.screenShortImageController as HTMLCanvasElement
        ) as drawCutOutBoxReturnType;
      }
    }
  }

  /**
   * 裁剪框工具栏点击事件
   * @param toolName
   * @param index
   * @param mouseEvent
   */
  public toolClickEvent = (
    toolName: string,
    index: number,
    mouseEvent: MouseEvent
  ) => {
    // 更新当前点击的工具栏条目
    this.toolName = toolName;
    const screenShortController = this.data.getScreenShortController();
    const ScreenShortImageController = this.data.getScreenShortImageController();
    if (
      screenShortController.value == null ||
      ScreenShortImageController == null
    )
      return;
    // 获取canvas容器
    const screenShortCanvas = screenShortController.value.getContext(
      "2d"
    ) as CanvasRenderingContext2D;
    // 工具栏尚未点击，当前属于首次点击，重新绘制一个无像素点的裁剪框
    if (!this.data.getToolClickStatus().value) {
      // 获取裁剪框位置信息
      const cutBoxPosition = this.data.getCutOutBoxPosition();
      // 开始绘制无像素点裁剪框
      drawCutOutBox(
        cutBoxPosition.startX,
        cutBoxPosition.startY,
        cutBoxPosition.width,
        cutBoxPosition.height,
        screenShortCanvas,
        this.borderSize,
        screenShortController.value,
        ScreenShortImageController,
        false
      );
    }
    this.data.setToolName(toolName);
    // 为当前点击项添加选中时的class名
    setSelectedClassName(mouseEvent, index, false);
    if (toolName != "text") {
      // 显示画笔选择工具栏
      this.data.setOptionStatus(true);
      // 设置画笔选择工具栏三角形角标位置
      this.data.setOptionIcoPosition(calculateOptionIcoPosition(index));
    } else {
      // 隐藏画笔工具栏
      this.data.setOptionStatus(false);
    }
    // 清空文本输入区域的内容并隐藏文本输入框
    if (this.textInputController?.value != null && this.data.getTextStatus()) {
      this.textInputController.value.innerHTML = "";
      this.data.setTextStatus(false);
    }
    // 初始化点击状态
    this.dragging = false;
    this.draggingTrim = false;

    // 保存图片
    if (toolName == "save") {
      this.getCanvasImgData(true);
    }
    // 销毁组件
    if (toolName == "close") {
      this.resetComponent();
    }
    // 确认截图
    if (toolName == "confirm" && this.screenShortCanvas && this.emit) {
      const base64 = this.getCanvasImgData(false);
      this.emit("get-image-data", base64);
    }
    // 撤销
    if (toolName == "undo") {
      // 隐藏画笔选项工具栏
      this.data.setOptionStatus(false);
      this.takeOutHistory();
    }

    // 设置裁剪框工具栏为点击状态
    this.data.setToolClickStatus(true);
  };

  /**
   * 保存当前画布状态
   * @private
   */
  private addHistory() {
    if (
      this.screenShortCanvas != null &&
      this.screenShortController.value != null
    ) {
      // 获取canvas画布与容器
      const context = this.screenShortCanvas;
      const controller = this.screenShortController.value;
      if (this.history.length > this.maxUndoNum) {
        // 删除最早的一条画布记录
        this.history.shift();
      }
      // 保存当前画布状态
      this.history.push({
        data: context.getImageData(0, 0, controller.width, controller.height)
      });
      // 启用撤销按钮
      this.data.setUndoStatus(true);
    }
  }

  /**
   * 显示最新的画布状态
   * @private
   */
  private showLastHistory() {
    if (this.screenShortCanvas != null) {
      const context = this.screenShortCanvas;
      if (this.history.length <= 0) {
        this.addHistory();
      }
      context.putImageData(this.history[this.history.length - 1]["data"], 0, 0);
    }
  }

  /**
   * 取出一条历史记录
   */
  private takeOutHistory() {
    const lastImageData = this.history.pop();
    if (this.screenShortCanvas != null && lastImageData) {
      const context = this.screenShortCanvas;
      if (this.undoClickNum == 0 && this.history.length > 0) {
        // 首次取出需要取两条历史记录
        const firstPopImageData = this.history.pop() as Record<string, any>;
        context.putImageData(firstPopImageData["data"], 0, 0);
      } else {
        context.putImageData(lastImageData["data"], 0, 0);
      }
    }

    this.undoClickNum++;
    // 历史记录已取完，禁用撤回按钮点击
    if (this.history.length <= 0) {
      this.undoClickNum = 0;
      this.data.setUndoStatus(false);
    }
  }

  /**
   * 重置组件
   */
  private resetComponent = () => {
    if (this.emit) {
      // 隐藏截图工具栏
      this.data.setToolStatus(false);
      // 初始化响应式变量
      this.data.setInitStatus(true);
      // 销毁组件
      this.emit("destroy-component", false);
      return;
    }
    throw "组件重置失败";
  };

  /**
   * 将指定区域的canvas转为图片
   * @private
   */
  private getCanvasImgData = (isSave: boolean) => {
    // 获取裁剪区域位置信息
    const { startX, startY, width, height } = this.data.getCutOutBoxPosition();
    let base64 = "";
    // 保存图片,需要减去八个点的大小
    if (this.screenShortCanvas) {
      if (isSave) {
        // 将canvas转为图片
        saveCanvasToImage(
          this.screenShortCanvas,
          startX,
          startY,
          width,
          height
        );
      } else {
        // 将canvas转为base64
        base64 = saveCanvasToBase64(
          this.screenShortCanvas,
          startX,
          startY,
          width,
          height
        );
      }
    }
    // 重置组件
    this.resetComponent();
    return base64;
  };
}
