<!--
绘制图件的组件

add by RYG
-->
<template>
  <!-- <ClientOnly> -->
  <!-- 绘图区域 -->
  <div class="canvas-container" ref="containerRef" @wheel.prevent="" v-bind="$attrs">
    <!-- 水平刻度尺 -->
    <canvas id="ruler-horizontal" ref="hRulerRef" :width="viewSize.width * 2 + 'px'" :height="rulerHeight * 2 + 'px'"
      :style="{
        width: viewSize.width + 'px',
        height: rulerHeight + 'px',
        left: rulerHeight + 'px',
      }" class="ruler horizontal">
    </canvas>
    <!-- 水平刻度指示 -->
    <div ref="rulerHorizontalIndicator" width="1px" :style="{ height: rulerHeight + 'px' }" style="
        position: absolute;
        top: 0px;
        width: 1px;
        background-color: #3e8e41;
        z-index: 99;
        box-sizing: border-box;
      "></div>

    <!-- 垂直刻度尺 -->
    <canvas id="ruler-vertical" ref="vRulerRef" :width="rulerHeight * 2 + 'px'" :height="viewSize.height * 2 + 'px'"
      :style="{
        height: viewSize.height + 'px',
        width: rulerHeight + 'px',
        top: rulerHeight + 'px',
      }" class="ruler vertical">
    </canvas>
    <!-- 垂直刻度指示 -->
    <div width="1px" :style="{ width: rulerHeight + 'px' }" style="
        position: absolute;
        left: 0px;
        height: 1px;
        background-color: #3e8e41;
        z-index: 99;
        box-sizing: border-box;
      "></div>
    <div v-if="rubberVisible" ref="rubberbandDiv" :style="{
      position: 'absolute',
      left: rubberbandRectangle.left + 'px',
      top: rubberbandRectangle.top + 'px',
      width: rubberbandRectangle.width + 'px',
      height: rubberbandRectangle.height + 'px',
    }" style="
        pointer-events: none;
        border: 2px dashed rgb(81, 153, 212);
        cursor: crosshair;
        opacity: 0.5;
        display: inline;
        z-index: 999;
      "></div>
    <canvas ref="canvasRef" @mousedown="canvasMouseDown" @mouseup="canvasMouseUp" @mousemove="canvasMouseMove"
      @wheel="canvasMouseWheel" @contextmenu.prevent="handleWellContextMenu" :style="{ cursor: GetCursor() }"
      class="main-canvas"></canvas>
    <div class="context-menu" :class="{ visible: contextMenu.visible }"
      :style="{ top: contextMenu.y + 'px', left: contextMenu.x + 'px' }" v-if="contextMenu.visible">
      <div class="menu-item" @click="handleMenuAction('edit')">
        <el-icon>
          <Edit />
        </el-icon>编辑
      </div>
      <!-- <hr class="divider" /> -->
      <div class="menu-item" @click="handleMenuAction('wellGroupClone')">
        <el-icon>
          <CopyDocument />
        </el-icon>应用井组参数到其它井组
      </div>
      <div class="menu-item" @click="handleMenuAction('wellGroupData')">
        <el-icon>
          <View />
        </el-icon>井组数据
      </div>
    </div>
    <img v-if="imgVisible" ref="image" :style="{
      position: 'absolute',
      left: imgPosition.x + 'px',
      top: imgPosition.y + 'px',
    }" style="pointer-events: none; z-index: 8" />
  </div>
  <LoadingDialog v-model="loading" ref="loadingRef" :timeout="10000" message="正在加载图件……" @timeout="onTimeout" />
  <WellGroupDataHandle :showDialog="showDialog" v-model="showDialog" class="wellGroupData" />

  <WellGroupEditDialog v-model="editVisible" ref="editRef" :parentToken="currentToken" v-if="wellGroupData"
    :wellGroupData="wellGroupData" />
</template>

<script setup>
import { ref, onMounted, onUnmounted, watch } from "vue";
import { emitter } from "~/utils/eventBus";
import { canvasToolType, MouseIcons, SelectHandle } from "~/enums/common.enum";
import { generateGUID } from "~/utils/common";
import { Edit, CopyDocument, View } from "@element-plus/icons-vue";
import { COMMAND, EMIT_COMMAND } from '~/utils/commandTypes'
import { LRUCache } from 'lru-cache';
import { useWebSocket } from '@/composables/useWebSocket'

const { $toastMessage } = useNuxtApp();
const config = useRuntimeConfig();

const EXPIRE_TIME = 5 * 60 * 1000;// 5 分钟

const cache = new LRUCache({
  max: 1000,      // 最多 1000 个条目
  ttl: EXPIRE_TIME // 5 分钟过期
});

const loading = ref(false);
const loadingRef = ref(null);

const props = defineProps({
  autoResize: {
    type: Boolean,
    default: true, // 是否自动调整画布大小
  },
  // 页面的 图件存储的 token 的 key
  tokenKey: {
    type: String,
    default: 'drawerToken'
  }
});

const currentTabTokenKey = computed(() => props.tokenKey);

const editVisible = ref(false);
const editRef = ref(null);
const cmdIds = ref([]);

// 接收到的消息中的token
const receivedToken = ref('');

const currentToken = ref(computed(() => receivedToken.value || localStorage.getItem(currentTabTokenKey.value)));

const { onMessage, status, messages, send } = useWebSocket();


// 标尺间隔
let ruler_metrics = [
  1,
  2,
  5,
  10,
  25,
  50,
  100,
  250,
  500,
  1000,
  2500,
  5000,
  10000,
  25000,
  50000,
  100000,
];

// 水平标尺的起止值
const hRulerSize = reactive({ startX: 0, endX: 0 });
// 垂直标尺的起止值
const vRulerSize = reactive({ startY: 0, endY: 0 });

// 水平标尺的范围
const xRange = computed(() => hRulerSize.endX - hRulerSize.startX);
// 垂直标尺的范围
const yRange = computed(() => vRulerSize.startY - vRulerSize.endY - 35);

// 水平主刻度
const hMainStep = computed(() =>
  calculateInterval(hRulerSize.endX, hRulerSize.startX, viewSize.width, false)
);
// 水平中刻度
const hMiddleStep = computed(() => hMainStep.value / 2);
// 水平最小刻度
const hMinStep = computed(() => hMainStep.value / 10);
// 水平刻度取整数值
const hRulerStart = computed(
  () => Math.floor(hRulerSize.startX / hMainStep.value) * hMainStep.value
);
const hRulerEnd = computed(
  () => Math.round(hRulerSize.endX / hMainStep.value) * hMainStep.value
);

// 垂直主刻度
const vMainStep = computed(() =>
  calculateInterval(vRulerSize.startY, vRulerSize.endY, viewSize.height, true)
);
// 垂直中刻度
const vMiddleStep = computed(() => vMainStep.value / 2);
// 垂直最小刻度
const vMinStep = computed(() => vMainStep.value / 10);
// 垂直刻度取整数值
const vRulerStart = computed(
  () => Math.round(vRulerSize.startY / vMainStep.value) * vMainStep.value
);
const vRulerEnd = computed(
  () => Math.floor(vRulerSize.endY / vMainStep.value) * vMainStep.value
);

const imgPath = ref(""); // 图片路径
const imgVisible = ref(false);
let imgData = null;
const queryDrawRuler = ref(false);

const imgPosition = reactive({ x: 0, y: 0 });
const viewSize = reactive({ width: 1024, height: 768 });


// 选中的图件元素ID
let selectedElementId = "";
// 选中的图件元素
let selectedElement = null;

const wellGroupData = ref(null);

// 右键菜单状态
const contextMenu = ref({
  visible: false,
  x: 0,
  y: 0,
});

// const dragImageVisible = ref(false);

// 标尺高度/宽度
let rulerHeight = 20;

const mouseStartX = ref(0);
const mouseStartY = ref(0);

const mouseHorizontal = ref(0);
const mouseVertical = ref(0);

let imgX = 0;
let imgY = 0;

let lastX;
let lastY;
const isDragFirst = ref(true);

const mouseDown = ref(false);
// 橡皮筋选框
const rubberVisible = ref(false);
const rubberbandDiv = ref(null);
const rubberbandRectangle = reactive({ left: 10, top: 10, width: 100, height: 100 });

/* 选择轮廓图 */
const initialRect = reactive({ left: 0, top: 0, width: 0, height: 0 });

const pressedKeyCode = ref(null);

const drawerToolType = ref(canvasToolType.Default);
const handleIndex = ref(-1);
// 缩放比例
const scale = ref(1);

// const store = useBtnClickStore();
const containerRef = ref(null);
const canvasRef = ref(null);
const hRulerRef = ref(null);
const vRulerRef = ref(null);
const image = ref(null);
const dpr = ref(1); // 设备像素比
let frameId = 0;

const showDialog = ref(false);

const dataDir = config.public.dataDir;

const emit = defineEmits(["resize", "init", "openFile", "editWellGroup"]);

const isView = ref(false);

let mainCtx = null;

const unsubscribe = onMessage((data) => {
  try {
    if (!data) return; // 如果没有新消息，直接返回
    // console.log("收到消息:", data);
    const json = JSON.parse(data);
    const evtType = json.type;
    if (evtType !== COMMAND.SELECT_HANDLE) {
      // console.log("接收到DrawServer的消息：", json)
      // console.log("判断:", json.cmdID, currentTabTokenKey.value);
    }
    if (json.cmdID && json.cmdID !== currentTabTokenKey.value) {
      return;
    }
    const msgId = `${evtType}-${json.dateTime}`;
    if (cache.has(msgId) && (evtType !== COMMAND.SELECT_HANDLE && evtType !== COMMAND.DRAG_ELEMENT)) {
      return;
    }
    cache.set(msgId, true);

    // 只有第一次打开文件时才存储token
    if (Object.hasOwn(json, "drawerToken") && json.drawerToken && evtType === COMMAND.NEW_TOKEN) {
      receivedToken.value = json.drawerToken;
      localStorage.setItem(currentTabTokenKey.value, json.drawerToken);
      return;
    }
    switch (evtType) {
      case COMMAND.REDRAW:
        refreshImg(json);
        break;
      case COMMAND.OPEN_ERROR:
        localStorage.removeItem(currentTabTokenKey.value);
        closeLoading();
        break;
      case COMMAND.SELECT_HANDLE:
        if (json.data !== -2) {
          handleIndex.value = json.data;
        }
        break;
      case COMMAND.DRAG_ELEMENT:
        let imgContent = json.data;
        if (!imgContent && imgContent.Data) {
          return;
        }

        imgVisible.value = true;
        Object.assign(imgPosition, {
          x: imgContent.ImgLeft + rulerHeight,
          y: imgContent.ImgTop + rulerHeight
        });
        Object.assign(initialRect, { left: imgPosition.x, top: imgPosition.y, width: imgContent.ImgWidth, height: imgContent.ImgHeight });
        console.log("initialRect:", initialRect, imgPosition)
        // imgPath.value = imgContent.Data + "?_=" + Math.random();
        // let imgTmp = image.value;
        // imgTmp.src = `${config.public.imgUrl}/${imgPath.value}`;
        // imgX = json.data.ImgLeft;
        // imgY = json.data.ImgTop;

        nextTick(() => {
          let imgTmp = image.value;
          imgTmp.src = `${config.public.imgUrl}/${imgContent.Data}`;
          // console.log("图件地址：", imgTmp.src);
        });
        break;

      case COMMAND.ELEMENT_PROPERTY:
        // console.log("当前KEY：", currentTabTokenKey.value, "\t cmdID", json.cmdID)
        if (currentTabTokenKey.value !== json.cmdID) {
          return;
        }
        let wellGroupProp = json.data;
        wellGroupData.value = json.data;
        selectedElement = wellGroupProp.ElementData;
        selectedElementId = wellGroupProp.ElementID;
        if (selectedElement) {
          emitter.emit(EMIT_COMMAND.WELL_GROUP_DATA, {
            propData: selectedElement,
            id: selectedElementId,
          });
        }
        break;

      case COMMAND.WELL_GROUP_DATA:
        // console.log("井组数据：", json.data);
        break;

      case COMMAND.MAP_RANGE_REAL:
        if (queryDrawRuler.value) {
          let imgRect = json.data;
          hRulerSize.startX = Math.round(imgRect.left);
          hRulerSize.endX = Math.round(imgRect.right);

          vRulerSize.startY = Math.round(imgRect.top);
          vRulerSize.endY = Math.round(imgRect.bottom);

          // console.log("标尺属性：", hRulerSize, vRulerSize);

          drawRulers();
          queryDrawRuler.value = false;
        }
        closeLoading();
        break;
      case "center":
        break;
      case COMMAND.SAVE:
        if (json.data) {
          $toastMessage.success("保存成功!");
          doRedraw();
        } else {
          $toastMessage.error("保存失败!");
        }
        break;
      case COMMAND.MERGE_FILE:
        loading.value = true;
        doRedraw();
        break;
    }
  } finally {
  }
});

const doRedraw = () => {
  sendCmd(COMMAND.REDRAW, { width: viewSize.width, height: viewSize.height });
}

const handleWellContextMenu = (e) => {
  // 阻止默认的右键菜单
  // event.preventDefault();

  if (selectedElementId === "") {
    console.warn("没有选中任何井组");
    return;
  }

  contextMenu.value = {
    visible: true,
    x: e.offsetX,
    y: e.offsetY,
  };


  // 阻止事件冒泡，避免触发 mouseup 事件
  // event.stopPropagation();
};

// 关闭右键菜单
const closeContextMenu = () => {
  contextMenu.value = {
    visible: false,
    x: 0,
    y: 0,
  };
};

const handleMenuAction = (action) => {
  switch (action) {
    // 应用井组参数
    case "wellGroupClone":
      sendCmd(COMMAND.WELL_GROUP_CLONE, { elementID: selectedElementId });
      break;
    case "wellGroupData":

      showDialog.value = true;
      break;
    // 取消操作
    case "cancel":
      break;
    // 编辑操作
    case "edit":
      editVisible.value = true;
      // 修改为左右对比模式
      // emit("editWellGroup", currentToken.value, wellGroupData.value);
      break;
    default:
      console.warn("未知操作:", action);
  }
  // 隐藏右键菜单
  closeContextMenu();
};

// 鼠标按下
const canvasMouseDown = (event) => {
  if (event.button !== 0) {
    return;
  }
  mouseDown.value = true;
  lastX = event.offsetX;
  lastY = event.offsetY;
  mouseStartX.value = event.offsetX;
  mouseStartY.value = event.offsetY;
  const rect = canvasRef.value.getBoundingClientRect();
  console.log("鼠标按下：", drawerToolType.value, handleIndex.value);
  switch (drawerToolType.value) {
    case canvasToolType.ViewPan:
      isDragFirst.value = true;
      imgVisible.value = true;

      Object.assign(imgPosition, { x: 0, y: 0 });
      mouseStartX.value = event.clientX - rect.left;
      mouseStartY.value = event.clientY - rect.top;
      break;
    case canvasToolType.ViewWindow:
      event.preventDefault();
      rubberVisible.value = true;

      mouseStartX.value = event.clientX - rect.left;
      mouseStartY.value = event.clientY - rect.top;
      rubberbandRectangle.left = mouseStartX.value;
      rubberbandRectangle.top = mouseStartY.value;
      rubberbandRectangle.width = 1;
      rubberbandRectangle.height = 1;
      break;
    case canvasToolType.Select:
      imgVisible.value = true;
      // mouseStartX.value = event.clientX - rect.left;
      // mouseStartY.value = event.clientY - rect.top;
      console.log("canvasToolType.Select:", mouseStartX.value, mouseStartY.value, event.offsetX, event.offsetY);
      if (handleIndex.value >= 0 && handleIndex.value <= 9) {
        // console.log("SELECT_DRAG_START", event.offsetX, event.offsetY);
        // 发送拖动开始消息
        sendCmd(COMMAND.SELECT_DRAG_START, { x: event.offsetX, y: event.offsetY });
      }
      // imgVisible.value = true;
      // mouseStartX.value = event.clientX - rect.left;
      // mouseStartY.value = event.clientY - rect.top;
      // sendCmd(COMMAND.SELECT_MOUSE_DOWN, { x: mouseStartX.value, y: mouseStartY.value });
      break;
  }

  closeContextMenu();
};

// 鼠标按键抬起
const canvasMouseUp = (event) => {
  if (event.button !== 0) {
    return;
  }

  const rect = canvasRef.value.getBoundingClientRect();
  let endX = 0;
  let endY = 0;

  console.log("鼠标抬起：", drawerToolType.value, handleIndex.value);

  switch (drawerToolType.value) {
    case canvasToolType.ViewPan:
      endX = event.clientX - rect.left;
      endY = event.clientY - rect.top;
      // 必须释放，否则图件显示不出来
      cancelAnimationFrame(frameId);
      sendCmd(COMMAND.VIEW_PAN, {
        startX: mouseStartX.value,
        startY: mouseStartY.value,
        endX: endX,
        endY: endY,
        width: viewSize.width,
        height: viewSize.height,
      });
      break;
    case canvasToolType.ViewWindow:
      rubberVisible.value = false;
      endX = event.clientX - rect.left;
      endY = event.clientY - rect.top;
      sendCmd(COMMAND.VIEW_WINDOW, {
        startX: mouseStartX.value,
        startY: mouseStartY.value,
        endX: endX,
        endY: endY,
        width: viewSize.width,
        height: viewSize.height,
      });
      break;
    case canvasToolType.Select:
      endX = event.offsetX;
      endY = event.offsetY;

      console.log("endX=", endX);
      console.log("endY=", endY);
      console.log("lastX=", lastX);
      console.log("lastY=", lastY);
      console.log("mouseStartX=", mouseStartX.value);
      console.log("mouseStartY=", mouseStartY.value);
      // 拖动结束
      if (handleIndex.value === SelectHandle.Body) {
        imgVisible.value = false;
        sendCmd(COMMAND.SELECT_TRANSFORM_ELEMENTS, {
          handle: handleIndex.value,
          startX: mouseStartX.value,
          startY: mouseStartY.value,
          endX: endX,
          endY: endY
        });
      }
      // 变形处理
      else if (handleIndex.value >= 0 && handleIndex.value < 8) {
        imgVisible.value = false;
        sendCmd(COMMAND.SELECT_TRANSFORM_ELEMENTS, {
          handle: handleIndex.value,
          startX: mouseStartX.value,
          startY: mouseStartY.value,
          endX: endX,
          endY: endY
        });
      }
      else if (handleIndex.value === SelectHandle.Nothing) {
        rubberVisible.value = false;
        sendCmd(COMMAND.SELECT_REGION, {
          startX: lastX,
          startY: lastY,
          endX: endX,
          endY: endY,
          isAdd: false
        });
        sendCmd(COMMAND.SELECT_MOUSE_UP, { x: lastX, y: lastY, keyCode: pressedKeyCode.value });
      }
      else {
        sendCmd(COMMAND.SELECT_MOUSE_UP, { x: lastX, y: lastY, keyCode: pressedKeyCode.value });
      }
      // endX = event.offsetX;
      // endY = event.offsetY;
      // if (handleIndex.value == 5) {
      //   sendCmd(COMMAND.DRAG_ELEMENT, { x: endX, y: endY });
      // } else {
      //   // 图元选择

      // }
      break;
  }

  mouseDown.value = false;
};

// 鼠标移动
const canvasMouseMove = (event) => {
  mouseHorizontal.value = event.offsetX + rulerHeight;
  mouseVertical.value = event.offsetY + rulerHeight;
  if (!mouseDown.value) {
    if (drawerToolType.value === canvasToolType.Select) {
      sendCmd(COMMAND.MOUSE_MOVE, {
        x: event.offsetX - rulerHeight,
        y: event.offsetY - rulerHeight,
        handleIndex: handleIndex.value,
      });
      // console.log("位置：", event.offsetX, event.offsetY, handleIndex.value, mouseStartX.value, mouseStartY.value);
    }
    return;
  }
  // console.log("鼠标移动：", drawerToolType.value, handleIndex.value);

  const rect = canvasRef.value.getBoundingClientRect();
  let dragStartX = 0;
  let dragStartY = 0;
  switch (drawerToolType.value) {
    case canvasToolType.ViewPan:
      let offsetX = event.offsetX - lastX;
      let offsetY = event.offsetY - lastY;

      if (isDragFirst.value) {
        isDragFirst.value = false;
        const dataURL = canvasRef.value.toDataURL("image/png");
        image.value.src = dataURL;
        Object.assign(imgPosition, {
          x: imgPosition.x + offsetX,
          y: imgPosition.y + offsetY,
        });
        // draw();
      } else {
        Object.assign(imgPosition, {
          x: imgPosition.x + offsetX,
          y: imgPosition.y + offsetY,
        });
        // draw();
      }
      lastX = event.offsetX;
      lastY = event.offsetY;
      break;
    case canvasToolType.ViewWindow:
      let endX = event.clientX - rect.left;
      let endY = event.clientY - rect.top;
      dragStartX = mouseStartX.value;
      dragStartY = mouseStartY.value;
      if (endX < dragStartX) {
        dragStartX = endX;
        endX = mouseStartX.value;
      }

      if (endY < dragStartY) {
        dragStartY = endY;
        endY = mouseStartY.value;
      }
      rubberbandRectangle.left = dragStartX;
      rubberbandRectangle.top = dragStartY;
      rubberbandRectangle.width = endX - dragStartX;
      rubberbandRectangle.height = endY - dragStartY;

      event.preventDefault();
      break;
    case canvasToolType.Select:
      let currentX = event.offsetX;
      let currentY = event.offsetY;
      event.preventDefault();
      let imgTmp = image.value;
      switch (handleIndex.value) {
        case SelectHandle.Nothing:
          dragStartX = lastX;
          dragStartY = lastY;

          // 确保坐标按左上->右下排列
          var left = Math.min(dragStartX, currentX);
          var top = Math.min(dragStartY, currentY);
          var right = Math.max(dragStartX, currentX);
          var bottom = Math.max(dragStartY, currentY);

          var rbWidth = right - left;
          var rbHeight = bottom - top;
          if (rbWidth > 0 || rbHeight > 0) {
            if (!rubberVisible.value) {
              rubberVisible.value = true;
            }

            rubberbandRectangle.left = left;
            rubberbandRectangle.top = top;
            rubberbandRectangle.width = rbWidth;
            rubberbandRectangle.height = rbHeight;
          }
          else {
            rubberVisible.value = false;
          }
          break;
        case SelectHandle.Right:
          if (imgTmp && imgVisible.value) {
            imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
            imgTmp.style.width = `${initialRect.width + (currentX - mouseStartX.value)}px`;
            imgTmp.style.height = `${initialRect.height}px`;
          }
          break;
        case SelectHandle.Left:
          if (imgTmp && imgVisible.value) {
            imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
            imgTmp.style.width = `${initialRect.width - (currentX - mouseStartX.value)}px`;
            imgTmp.style.height = `${initialRect.height}px`;

            imgPosition.x = initialRect.left + (currentX - mouseStartX.value);
          }
          break;
        case SelectHandle.Bottom:
          if (imgTmp && imgVisible.value) {
            imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
            imgTmp.style.width = `${initialRect.width}px`;
            imgTmp.style.height = `${initialRect.height + (currentY - mouseStartY.value)}px`;
          }
          break;
        case SelectHandle.Top:
          if (imgTmp && imgVisible.value) {
            imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
            imgTmp.style.width = `${initialRect.width}px`;
            imgTmp.style.height = `${initialRect.height - (currentY - mouseStartY.value)}px`;

            imgPosition.y = initialRect.top + (currentY - mouseStartY.value);
          }
          break;
        case SelectHandle.BottomRight:
          if (imgTmp && imgVisible.value) {
            imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
            imgTmp.style.width = `${initialRect.width + (currentX - mouseStartX.value)}px`;
            imgTmp.style.height = `${initialRect.height + (currentY - mouseStartY.value)}px`;
          }
          break;
        case SelectHandle.BottomLeft:
          if (imgTmp && imgVisible.value) {
            imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
            imgTmp.style.width = `${initialRect.width - (currentX - mouseStartX.value)}px`;
            imgTmp.style.height = `${initialRect.height + (currentY - mouseStartY.value)}px`;

            imgPosition.x = initialRect.left + (currentX - mouseStartX.value);
          }
          break;
        case SelectHandle.TopRight:
          if (imgTmp && imgVisible.value) {
            imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
            imgTmp.style.width = `${initialRect.width + (currentX - mouseStartX.value)}px`;
            imgTmp.style.height = `${initialRect.height - (currentY - mouseStartY.value)}px`;

            // imgPosition.x = initialRect.left + (currentX - mouseStartX.value);
            imgPosition.y = initialRect.top + (currentY - mouseStartY.value);

            console.log("位置:", initialRect, currentX, currentY, mouseStartX.value, mouseStartY.value, imgPosition);
          }
          break;
        case SelectHandle.TopLeft:
          if (imgTmp && imgVisible.value) {
            imgTmp.style.objectFit = 'fill'; // 允许拉伸填充
            imgTmp.style.width = `${initialRect.width - (currentX - mouseStartX.value)}px`;
            imgTmp.style.height = `${initialRect.height - (currentY - mouseStartY.value)}px`;

            imgPosition.x = initialRect.left + (currentX - mouseStartX.value);
            imgPosition.y = initialRect.top + (currentY - mouseStartY.value);
          }
          break;
        case SelectHandle.Body:
          // 拖动
          let offsetX = event.offsetX - lastX;
          let offsetY = event.offsetY - lastY;
          if (Math.abs(offsetX) > 0 || Math.abs(offsetY) > 0) {
            Object.assign(imgPosition, { x: imgPosition.x + offsetX, y: imgPosition.y + offsetY });
            lastX = event.offsetX;
            lastY = event.offsetY;
          }
          break;
        // console.log("拖动:", moveX, moveY);
        // Object.assign(imgPosition, {
        //   x: imgX + moveX,
        //   y: imgY + moveY
        // })

        // lastX = event.offsetX;
        // lastY = event.offsetY;
        // break;
      }
  };
};

const draw = () => {
  if (!mainCtx) return;
  mainCtx.clearRect(0, 0, viewSize.width, viewSize.height);
  frameId = requestAnimationFrame(draw);
};

const canvasMouseWheel = (event) => {
  scale.value = scale.value + 1;
};

const refreshImg = (data) => {
  // console.log("refreshImg：", data);
  imgPath.value = data.data + "?_=" + Math.random();
  redrawCanvas(imgPath.value);
  closeLoading();
  if (currentTabTokenKey.value !== data.cmdID) {
    return;
  }
  emitter.emit(EMIT_COMMAND.REFRESH_LAYER);
}

// 绘制图片
const redrawCanvas = async (data) => {
  if (data.length === 0) return;

  try {
    const response = await fetch(`${config.public.imgUrl}/${data}`, {
      cache: "no-store",
    });
    if (!response.ok) {
      $toastMessage.error("Network response was not ok");
      return;
    }
    const { pixelWidth, pixelHeight } = getDrawingAreaSize();
    viewSize.width = pixelWidth;
    viewSize.height = pixelHeight;

    const blob = await response.blob();
    imgData = await createImageBitmap(blob);

    if (!mainCtx) {
      return;
    }
    mainCtx.clearRect(0, 0, viewSize.width, viewSize.height - rulerHeight);
    mainCtx.drawImage(imgData, rulerHeight, rulerHeight);
    imgVisible.value = false;
    queryDrawRuler.value = true;
    sendCmd(COMMAND.QUERY_RANGE_SCREEN_TO_REAL, {
      startX: rulerHeight,
      endX: viewSize.width,
      startY: rulerHeight,
      endY: viewSize.height,
    });
  } catch (error) {
    console.error("Failed to load the image:", error);
  }
};

// 默认
const toolDefault = () => {
  drawerToolType.value = canvasToolType.Default;
};

const toolViewMove = () => {
  drawerToolType.value = canvasToolType.ViewPan;
};

const toolViewWindow = () => {
  drawerToolType.value = canvasToolType.ViewWindow;
};

const toolSelect = () => {
  drawerToolType.value = canvasToolType.Select;
  toolSwitch(drawerToolType.value);
};

// 工具切换
const toolSwitch = (newToolType) => {
  sendCmd(COMMAND.SWITCH_TOOL_TYPE, { toolType: newToolType });
}

// 放大
const drawZoomIn = () => {
  sendCmd(COMMAND.ZOOM_IN, { width: viewSize.width, height: viewSize.height });
};

// 缩小
const drawZoomOut = () => {
  sendCmd(COMMAND.ZOOM_OUT, { width: viewSize.width, height: viewSize.height });
};

// 刷新
const drawRefresh = () => {
  // redrawCanvas(imgPath.value);
  sendCmd(COMMAND.REFRESH, { width: viewSize.width, height: viewSize.height });
};

// 居中
const drawCenter = () => {
  sendCmd(COMMAND.CENTER, { width: viewSize.width, height: viewSize.height });
};

// 全部
const viewAll = () => {
  sendCmd(COMMAND.VIEW_ALL, { width: viewSize.width, height: viewSize.height });
};

const GetCursor = () => {
  let iconName = "default";
  // console.log("GetCursor：", drawerToolType.value, handleIndex.value)
  switch (drawerToolType.value) {
    case canvasToolType.Select:
      // if (handleIndex.value == 5) {
      //   iconName = `url('./assets/move.svg') 24 24 auto`;
      // } else {
      //   iconName = MouseIcons.pointerSelect;
      // }
      if (handleIndex.value === SelectHandle.Body || handleIndex.value === SelectHandle.Center) {
        iconName = `url('./assets/move.svg') 24 24 auto`;
      }
      else if (handleIndex.value === SelectHandle.TopLeft || handleIndex.value === SelectHandle.BottomRight) {
        return MouseIcons.resizenw;
      }
      else if (handleIndex.value === SelectHandle.TopRight || handleIndex.value === SelectHandle.BottomLeft) {
        return MouseIcons.resizene;
      }
      else if (handleIndex.value === SelectHandle.Left || handleIndex.value === SelectHandle.Right) {
        return MouseIcons.resizee;
      }
      else if (handleIndex.value === SelectHandle.Top || handleIndex.value === SelectHandle.Bottom) {
        return MouseIcons.resizen;
      }
      else {
        return MouseIcons.pointerSelect;
      }
      break;
    case canvasToolType.ViewPan:
      iconName = MouseIcons.viewPan;
      break;
    case canvasToolType.ViewWindow:
      iconName = MouseIcons.crosshair;
      break;
  }
  return iconName;
};

const showLayers = () => {
  emitter.emit(EMIT_COMMAND.SHOW_LAYERS);
};

// 按键
const handleKeyDown = (event) => {
  pressedKeyCode.value = event.keyCode;
};

const handleKeyUp = (event) => {
  pressedKeyCode.value = null;
};


// 打开文件
const openFile = (fileUrl, token) => {
  if (!fileUrl) return;
  if (!canvasRef.value) return;

  loading.value = true;
  // 获取画布大小
  let rect = getDrawingAreaSize();
  // console.log("当前tokenkey:", currentTabTokenKey.value, token)
  if (token) {
    localStorage.setItem(currentTabTokenKey.value, token);
  }
  // console.log("画布尺寸：", viewSize);
  sendCmd(COMMAND.OPEN_FILE, {
    file: fileUrl,
    token: token,
    width: rect.pixelWidth,
    height: rect.pixelHeight,
  });
};


function save() {
  sendCmd(COMMAND.SAVE_FILE);
}

// 安全获取 devicePixelRatio
const getDevicePixelRatio = () => {
  return (typeof window !== "undefined" && window.devicePixelRatio) || 1;
};

// 设备像素比
const getDrawingAreaSize = () => {
  if (!containerRef.value) return { width: 0, height: 0 };

  const { clientWidth: width, clientHeight: height } = containerRef.value;
  dpr.value = getDevicePixelRatio(); // 获取设备像素比
  return {
    pixelWidth: width * dpr.value, // 实际像素宽度
    pixelHeight: height * dpr.value, // 实际像素高度
  };
};

// 初始化画布大小
const initCanvasSize = () => {
  const canvas = canvasRef.value;

  if (!canvas) return;

  // console.log("Canvas加载完成")

  // 获取容器尺寸
  const { pixelWidth, pixelHeight } = getDrawingAreaSize();
  viewSize.width = pixelWidth;
  viewSize.height = pixelHeight;

  // console.log("initCanvasSize:", viewSize)

  // 设置画布大小
  canvas.width = pixelWidth * dpr.value; // 实际像素宽度
  canvas.height = pixelHeight * dpr.value; // 实际像素高度
  canvas.style.width = `${pixelWidth}px`;
  canvas.style.height = `${pixelHeight}px`;
  // 获取2D上下文
  mainCtx = canvas.getContext("2d");
  if (!mainCtx) {
    return;
  }
  mainCtx.scale(dpr.value, dpr.value); // 缩放上下文以适应设备像素比
  // 关闭图像平滑处理
  mainCtx.imageSmoothingEnabled = false;
  mainCtx.fillStyle = "#FFFFFF";
  mainCtx.fillRect(0, 0, canvas.width, canvas.height);
  let rect = canvas.getBoundingClientRect();

  Object.assign(imgPosition, {
    x: rect.left,
    y: rect.top,
  });
};

// 绘制刻度尺
const drawRulers = () => {
  // 获取容器尺寸
  const { pixelWidth, pixelHeight } = getDrawingAreaSize();
  viewSize.width = pixelWidth;
  viewSize.height = pixelHeight;

  // console.log("窗口尺寸：", viewSize);

  drawHRuler();
  drawVRuler();
};

// 水平标尺绘制
const drawHRuler = () => {
  const width = viewSize.width * 2;
  const hRulerCanvas = hRulerRef.value;
  const ctx = hRulerCanvas.getContext("2d");
  ctx.clearRect(0, 0, width, rulerHeight * 2);
  ctx.lineWidth = 1;
  ctx.font = "16px Arial";
  ctx.textAlign = "left";
  ctx.fillStyle = "#333";
  // 计算像素比例
  const pxPerUnit = width / xRange.value;

  // console.log("水平标尺属性：", hRulerStart.value, hRulerEnd.value, hMainStep.value);
  // 主刻度
  for (
    let value = hRulerStart.value;
    value <= hRulerEnd.value;
    value += hMainStep.value
  ) {
    const x = (((value - hRulerStart.value) / xRange.value) * width) / scale.value;
    // console.log("X主刻度：", x);
    ctx.beginPath();
    ctx.moveTo(x, 0);
    ctx.lineTo(x, 20);
    ctx.stroke();
    ctx.fillText(value, x + 5, rulerHeight + 10);
  }

  // 次刻度
  for (
    let value = hRulerStart.value;
    value <= hRulerEnd.value;
    value += hMiddleStep.value
  ) {
    if (value % hMainStep.value === 0) continue;
    const x = ((value - hRulerStart.value) / xRange.value) * width;
    ctx.beginPath();
    ctx.moveTo(x, 0);
    ctx.lineTo(x, 15);
    ctx.stroke();
  }

  // 最小刻度
  for (let value = hRulerStart.value; value <= hRulerEnd.value; value += hMinStep.value) {
    if (value % hMainStep.value === 0 || value % hMiddleStep.value === 0) continue;

    const x = ((value - hRulerStart.value) / xRange.value) * width;
    ctx.beginPath();
    ctx.moveTo(x, 0);
    ctx.lineTo(x, 10);
    ctx.stroke();
  }
};

// 垂直标尺绘制
const drawVRuler = () => {
  const height = viewSize.height * 2;
  const vRulerCanvas = vRulerRef.value;
  const ctx = vRulerCanvas.getContext("2d");
  ctx.clearRect(0, 0, rulerHeight * 2, height);
  ctx.lineWidth = 1;
  ctx.font = "16px Arial";
  ctx.textAlign = "left";
  ctx.fillStyle = "#333";
  // 计算像素比例
  // const pxPerUnit = height / yRange.value;
  // 主刻度
  for (
    let value = vRulerStart.value;
    value >= vRulerEnd.value;
    value -= vMainStep.value
  ) {
    const y = (((vRulerStart.value - value) / yRange.value) * height) / scale.value;
    ctx.beginPath();
    ctx.moveTo(0, y);
    ctx.lineTo(20, y);
    ctx.stroke();

    // 旋转文字
    ctx.save();
    ctx.translate(20, y);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText(value, 10, 10);
    ctx.restore();
  }

  // 次刻度
  for (
    let value = vRulerStart.value;
    value >= vRulerEnd.value;
    value -= vMiddleStep.value
  ) {
    if (value % vMainStep.value === 0) continue;
    const y = ((vRulerStart.value - value) / yRange.value) * height;
    ctx.beginPath();
    ctx.moveTo(0, y);
    ctx.lineTo(15, y);
    ctx.stroke();
  }

  // 最小刻度
  for (let value = vRulerStart.value; value >= vRulerEnd.value; value -= vMinStep.value) {
    if (value % vMainStep.value === 0 || value % vMiddleStep.value === 0) continue;

    const y = ((vRulerStart.value - value) / yRange.value) * height;
    ctx.beginPath();
    ctx.moveTo(0, y);
    ctx.lineTo(10, y);
    ctx.stroke();
  }
};

const calculateInterval = (start, end, length, isV) => {
  const range = Math.abs(end - start);
  // 橫标尺每200像素1个，纵标尺每150像素1个
  let rulerCount = Math.ceil(isV ? length / 200 : length / 150);
  if (rulerCount < 5) {
    rulerCount = rulerCount * 2;
  }
  let magnitude = range / rulerCount;
  let step = 0;

  for (let i = 0; i < ruler_metrics.length; i++) {
    if (magnitude > ruler_metrics[i] && magnitude <= ruler_metrics[i + 1]) {
      step = ruler_metrics[i];
      break;
    }
  }

  // 按比例换算
  let realCount = range / step;
  if (isV) {
    if (realCount >= 15) {
      step = step * 2;
    } else if (realCount <= 5) {
      step = step / 2;
    }
  }

  if (!isV) {
    if (realCount >= 20) {
      step = step * 2;
    } else if (realCount <= 10) {
      step = step / 2;
    }
  }
  return step;
};

const handleResize = debounce(() => {
  if (!canvasRef.value) return;
  redrawCanvas(imgPath.value);
}, 150);

const clearCanvas = () => {
  if (!mainCtx) return;
  mainCtx.clearRect(0, 0, viewSize.width, viewSize.height);
};

function doOpenFile(item) {
  // console.log("执行方法:doOpenFile", item)
  clearCanvas();
  let drawerToken = generateGUID();
  openFile(`${dataDir}/${item}`, drawerToken);
}

// 生命周期钩子
onMounted(() => {
  nextTick(() => {
    image.value = new Image();
    initCanvasSize();
    window.addEventListener("resize", handleResize);
  });

  // 全局监听键盘事件
  window.addEventListener("keydown", handleKeyDown);
  window.addEventListener("keyup", handleKeyUp);

  emitter.on(EMIT_COMMAND.REFRESH_IMG, (data) => {
    refreshImg(data);
  });

  emitter.on(EMIT_COMMAND.EVT_TYPE, (data) => {
    const json = JSON.parse(data.data);

    const cmdId = data.cmdID;

    console.log("接收到 EMIT_COMMAND.EVT_TYPE 的消息：", cmdId, currentTabTokenKey.value, json)
    if (cmdId !== currentTabTokenKey.value) {
      return;
    }
    switch (data.type) {
      // case COMMAND.REDRAW:
      //   refreshImg(json);
      //   break;
      case EMIT_COMMAND.OPEN_FILE:
        clearCanvas();
        let drawerToken = json.drawerToken || generateGUID();
        openFile(`${dataDir}/${json.fileName}`, drawerToken);
        break;

      case "calcRedraw":
        doRedraw();
        break;
      case "viewFile":
        isView.value = true;
        openFile(`${dataDir}/${json.fileUrl}`, json.viewerToken);
        break;
      case EMIT_COMMAND.VIEW_ALL:
        viewAll();
        break;
      case EMIT_COMMAND.CLEAR_CANVAS:
        clearCanvas();
        break;

      // case COMMAND.EDIT_WELL_GROUP:
      //   if (currentToken.value === STORAGE_KEYS.WELL_GROUP_EDIT_TOKEN) {

      //   }
      //   console.log("收到编辑井组回应：", json);
      //   break;
    }

  });

  emitter.on(EMIT_COMMAND.SOURCE_CHANGED, sourceChanged);

  // emitter.on(EMIT_COMMAND.EDIT_REDRAW, (json) => {
  //   console.log("收到编辑井组回应 CanvasRenderer：", json);
  //   refreshImg(json);
  // });
});

const sourceChanged = () => {
  localStorage.removeItem(currentTabTokenKey.value);
  clearCanvas();
};


onBeforeUnmount(() => {
  // emitter.off(EMIT_COMMAND.BUTTON_CLICK);
  emitter.off(EMIT_COMMAND.EVT_TYPE);
  emitter.off(EMIT_COMMAND.SOURCE_CHANGED);
  emitter.off(EMIT_COMMAND.REFRESH_IMG);
  emitter.off(EMIT_COMMAND.EDIT_GROUP);
  // emitter.off(EMIT_COMMAND.EDIT_REDRAW);

  window.removeEventListener("resize", handleResize);
  // 全局监听键盘事件
  window.removeEventListener("keydown", handleKeyDown);
  window.removeEventListener("keyup", handleKeyUp);
});

onUnmounted(() => {
  unsubscribe();
});


// 加载数据超时处理
const onTimeout = () => {
  $toastMessage.error("加载数据失败，请稍后重试！");
}

// 关闭加载窗口
const closeLoading = () => {
  if (loadingRef.value) {
    loadingRef.value.close();
  } else {
    loading.value = false;
  }
}

const sendCmd = (type, data = {}) => {
  // const cmdid = generateGUID();
  // cmdIds.value.push(cmdid);
  if (type != COMMAND.MOUSE_MOVE) {
    // console.log("发送命令：", type, data);
  }
  send(type, data, currentToken.value, currentTabTokenKey.value);
}

const getCanvasSize = () => {
  if (canvasRef.value) {
    return canvasRef.value.getBoundingClientRect();
    // console.log("getCanvasSize:", canvasRef.value.width, canvasRef.value.height);
    // return getDrawingAreaSize();
  }

  return null;
}

// 防抖函数
function debounce(fn, delay) {
  let timer = null
  return function (...args) {
    if (timer) {
      clearTimeout(timer)
    }
    timer = setTimeout(() => {
      fn.apply(this, args)
    }, delay)
  }
}

defineExpose({
  // width: computed(() => canvasRef.value?.width),
  // height: computed(() => canvasRef.value?.height),
  getCanvasSize,
  // 处理默认按钮点击
  toolDefault,
  // 处理放大按钮点击
  drawZoomIn,
  // 处理缩小按钮点击
  drawZoomOut,
  // 处理刷新按钮点击
  drawRefresh,
  // 处理居中按钮点击
  drawCenter,
  // 处理局部按钮点击
  toolViewWindow,
  // 处理全部按钮点击
  viewAll,
  // 处理移动按钮点击
  toolViewMove,
  // 处理选择按钮点击
  toolSelect,
  // 处理保存按钮点击
  save,
  // 处理图层按钮点击
  showLayers,
  // 打开文件
  doOpenFile
})
</script>

<style scoped>
.canvas-container {
  width: 100%;
  height: 100%;
  /* min-width: 800px;
  min-height: 550px; */
  position: relative;
  border: 0;
  overflow: hidden;
  /* 防止内容溢出 */
  background-color: #fff;
}

.ruler {
  position: absolute;
  z-index: 10;
  /* 标尺置于顶层 */
  background: rgb(245, 245, 245);
}

.horizontal {
  top: 0;
  height: 20px;
  /* 水平标尺高度 */
}

.vertical {
  left: 0;
  width: 20px;
  /* 垂直标尺宽度 */
}

.main-canvas {
  display: block;
  width: 100%;
  height: 100%;
  /* 确保画布是块级元素 */
  background: #fff;
  border: 0;
  /* position: relative; */
  z-index: 1;
  top: 20px;
  /* 避开水平标尺 */
  left: 20px;
  /* 避开垂直标尺 */
  /* width: calc(100vw - 20px);
  height: calc(100vh - 20px); */
  resize: both;
  image-rendering: -webkit-optimize-contrast;
}

/*自定义右键菜单样式*/
.context-menu {
  position: absolute;
  background: white;
  border-radius: 8px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.15);
  z-index: 1000;
  overflow: hidden;
  opacity: 0;
  transform: scale(0.95);
  transition: all 0.2s ease-out;
  min-width: 200px;
}

.context-menu.visible {
  opacity: 1;
  transform: scale(1);
}

.menu-item {
  padding: 8px 15px;
  display: flex;
  align-items: center;
  gap: 12px;
  cursor: pointer;
  transition: all 0.2s;
  border-bottom: 1px solid #f0f4f8;
  font-size: 14px;
}

.menu-item:last-child {
  border-bottom: none;
}

.menu-item:hover {
  background: #f0f7ff;
}

.menu-item .icon {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: #e3f2fd;
  border-radius: 6px;
  color: #3498db;
}

.menu-item.danger {
  color: #e74c3c;
}

.menu-item.danger .icon {
  background: #fdecea;
  color: #e74c3c;
}

/*分隔线样式*/
.divider {
  border: none;
  height: 1px;
  background: #ccc;
  margin: 3px 0;
}

.wellGroupData {
  width: calc(100vw - 100px);
  height: calc(100vh - 100px);
}
</style>
