import { fabric } from "fabric-with-all";

/**
 * 小地图管理器类
 * 实现画布的小地图功能，展示当前视窗位置和内容概览
 */
export class MinimapManager {
  /**
   * 构造函数
   * @param {fabric.Canvas} mainCanvas 主画布实例
   * @param {Object} options 配置选项
   */
  constructor(mainCanvas, options = {}) {
    this.mainCanvas = mainCanvas;
    this.minimapCanvas = null;
    this.minimapCtx = null;
    this.container = null;
    this.minimapSize = options.size || { width: 200, height: 120 };
    this.visible = options.visible !== undefined ? options.visible : true;
    this.isDragging = false;
    this.lastRenderTime = 0;
    this.renderInterval = options.renderInterval || 100; // 增加渲染间隔到100ms，降低频率
    this.initialized = false;
    this.eventHandlers = {};

    // 内容边界，用于确定小地图显示范围
    this.contentBounds = {
      minX: 0,
      minY: 0,
      maxX: 0,
      maxY: 0,
    };

    // 缓存上一次视口大小，用于减少抖动
    this.lastViewportSize = { width: 0, height: 0 };
    // 添加缓存标志，避免频繁重新计算
    this.contentBoundsDirty = true;

    // 预先绑定方法，避免上下文丢失
    this.render = this.render.bind(this);
    this.handleMainCanvasChange = this.handleMainCanvasChange.bind(this);
    this.handleMinimapMouseDown = this.handleMinimapMouseDown.bind(this);
    this.handleMinimapMouseMove = this.handleMinimapMouseMove.bind(this);
    this.handleMinimapMouseUp = this.handleMinimapMouseUp.bind(this);
    this.calculateViewportRect = this.calculateViewportRect.bind(this);
    this.calculateContentBounds = this.calculateContentBounds.bind(this);
    this.moveViewport = this.moveViewport.bind(this);

    // 创建canvas元素
    this._createCanvas();
  }

  /**
   * 创建小地图的canvas元素
   * @private
   */
  _createCanvas() {
    // 创建canvas元素
    this.minimapCanvas = document.createElement("canvas");
    this.minimapCanvas.width = this.minimapSize.width;
    this.minimapCanvas.height = this.minimapSize.height;
    this.minimapCanvas.style.width = "100%";
    this.minimapCanvas.style.height = "100%";
    this.minimapCanvas.style.display = this.visible ? "block" : "none";

    // 获取绘图上下文
    this.minimapCtx = this.minimapCanvas.getContext("2d");
  }

  /**
   * 将小地图挂载到指定的DOM容器中
   * @param {HTMLElement} containerElement 容器DOM元素
   * @returns {MinimapManager} 返回实例自身，支持链式调用
   */
  mount(containerElement) {
    if (!containerElement) {
      console.error("小地图挂载失败：未提供有效的容器元素");
      return this;
    }

    // 保存容器引用
    this.container = containerElement;

    // 清空容器，防止重复挂载
    while (containerElement.firstChild) {
      containerElement.removeChild(containerElement.firstChild);
    }

    // 将canvas添加到容器
    containerElement.appendChild(this.minimapCanvas);

    // 初始化小地图
    if (!this.initialized) {
      // 计算初始内容边界
      this.calculateContentBounds();

      // 添加事件监听器
      this.addEventListeners();

      // 首次渲染
      this.render();

      this.initialized = true;
    }

    return this;
  }

  /**
   * 添加事件监听器
   */
  addEventListeners() {
    if (!this.mainCanvas || !this.minimapCanvas) return;

    // 监听主画布变化事件
    this.mainCanvas.on("after:render", this.handleMainCanvasChange);
    // 仅在缩放时重新计算内容边界，避免频繁计算
    this.mainCanvas.on("zoom:change", () => {
      this.contentBoundsDirty = true;
      this.handleMainCanvasChange();
    });
    // 仅当对象添加、删除或修改时重新计算内容边界
    this.mainCanvas.on("object:added", () => {
      this.contentBoundsDirty = true;
      this.handleMainCanvasChange();
    });
    this.mainCanvas.on("object:removed", () => {
      this.contentBoundsDirty = true;
      this.handleMainCanvasChange();
    });
    this.mainCanvas.on("object:modified", () => {
      this.contentBoundsDirty = true;
      this.handleMainCanvasChange();
    });

    // 移动、缩放、旋转操作时使用更强的节流，不重新计算内容边界
    this.mainCanvas.on("object:moving", this.handleMainCanvasChange);
    this.mainCanvas.on("object:scaling", this.handleMainCanvasChange);
    this.mainCanvas.on("object:rotating", this.handleMainCanvasChange);

    // 小地图交互事件 - 鼠标
    this.eventHandlers.mousedown = this.handleMinimapMouseDown;
    this.eventHandlers.mousemove = this.handleMinimapMouseMove;
    this.eventHandlers.mouseup = this.handleMinimapMouseUp;
    // 移除mouseout事件处理，允许拖动操作持续到鼠标释放

    this.minimapCanvas.addEventListener("mousedown", this.eventHandlers.mousedown);
    document.addEventListener("mousemove", this.eventHandlers.mousemove);
    document.addEventListener("mouseup", this.eventHandlers.mouseup);
    // 移除mouseout事件监听

    // 小地图交互事件 - 触摸
    this.eventHandlers.touchstart = (e) => {
      e.preventDefault();
      const touch = e.touches[0];
      this.handleMinimapMouseDown({
        clientX: touch.clientX,
        clientY: touch.clientY,
        preventDefault: () => {},
      });
    };

    this.eventHandlers.touchmove = (e) => {
      e.preventDefault();
      if (this.isDragging) {
        const touch = e.touches[0];
        this.handleMinimapMouseMove({
          clientX: touch.clientX,
          clientY: touch.clientY,
          preventDefault: () => {},
        });
      }
    };

    this.eventHandlers.touchend = this.handleMinimapMouseUp;

    this.minimapCanvas.addEventListener("touchstart", this.eventHandlers.touchstart);
    document.addEventListener("touchmove", this.eventHandlers.touchmove, {
      passive: false,
    });
    document.addEventListener("touchend", this.eventHandlers.touchend);
  }

  /**
   * 移除事件监听器
   */
  removeEventListeners() {
    if (!this.mainCanvas || !this.minimapCanvas) return;

    // 移除画布事件监听
    this.mainCanvas.off("after:render", this.handleMainCanvasChange);
    this.mainCanvas.off("zoom:change", this.handleMainCanvasChange);
    this.mainCanvas.off("object:added", this.handleMainCanvasChange);
    this.mainCanvas.off("object:removed", this.handleMainCanvasChange);
    this.mainCanvas.off("object:modified", this.handleMainCanvasChange);
    this.mainCanvas.off("object:moving", this.handleMainCanvasChange);
    this.mainCanvas.off("object:scaling", this.handleMainCanvasChange);
    this.mainCanvas.off("object:rotating", this.handleMainCanvasChange);

    // 移除鼠标事件监听
    this.minimapCanvas.removeEventListener("mousedown", this.eventHandlers.mousedown);
    document.removeEventListener("mousemove", this.eventHandlers.mousemove);
    document.removeEventListener("mouseup", this.eventHandlers.mouseup);

    // 移除触摸事件监听
    this.minimapCanvas.removeEventListener("touchstart", this.eventHandlers.touchstart);
    document.removeEventListener("touchmove", this.eventHandlers.touchmove);
    document.removeEventListener("touchend", this.eventHandlers.touchend);
  }

  /**
   * 处理主画布变化事件
   * 使用节流限制渲染频率
   */
  handleMainCanvasChange() {
    const now = Date.now();
    if (now - this.lastRenderTime > this.renderInterval) {
      this.lastRenderTime = now;

      // 只在内容边界标记为脏时才重新计算
      if (this.contentBoundsDirty) {
        this.calculateContentBounds();
        this.contentBoundsDirty = false;
      }

      this.render();
    }
  }

  /**
   * 计算画布内容的边界范围
   * 包括所有可见对象和画布本身
   */
  calculateContentBounds() {
    if (!this.mainCanvas) return;

    const objects = this.mainCanvas.getObjects();

    // 初始化为画布尺寸
    let minX = 0;
    let minY = 0;
    let maxX = this.mainCanvas.getWidth();
    let maxY = this.mainCanvas.getHeight();

    // 如果有对象，则计算所有对象的边界
    if (objects.length > 0) {
      // 重置为极值
      minX = Infinity;
      minY = Infinity;
      maxX = -Infinity;
      maxY = -Infinity;

      // 考虑所有可见对象的边界
      objects.forEach((obj) => {
        if (!obj.visible) return;

        const rect = obj.getBoundingRect(true, true);
        minX = Math.min(minX, rect.left);
        minY = Math.min(minY, rect.top);
        maxX = Math.max(maxX, rect.left + rect.width);
        maxY = Math.max(maxY, rect.top + rect.height);
      });

      // 确保边界至少包含画布尺寸
      minX = Math.min(minX, 0);
      minY = Math.min(minY, 0);
      maxX = Math.max(maxX, this.mainCanvas.getWidth());
      maxY = Math.max(maxY, this.mainCanvas.getHeight());
    }

    // 添加边距
    const padding = Math.max(this.mainCanvas.getWidth(), this.mainCanvas.getHeight()) * 0.1;
    this.contentBounds = {
      minX: minX - padding,
      minY: minY - padding,
      maxX: maxX + padding,
      maxY: maxY + padding,
    };
  }

  /**
   * 处理小地图鼠标按下事件
   */
  handleMinimapMouseDown(e) {
    if (!this.visible || !this.minimapCanvas) return;

    e.preventDefault();

    const rect = this.minimapCanvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    // 检查点击是否在视口矩形内
    const vpRect = this.calculateViewportRect();

    // 在视口矩形内点击开始拖拽，否则直接跳转到点击位置
    if (
      x >= vpRect.x &&
      x <= vpRect.x + vpRect.width &&
      y >= vpRect.y &&
      y <= vpRect.y + vpRect.height
    ) {
      this.isDragging = true;
      this.dragStart = { x, y };
      this.dragStartViewport = { ...vpRect };

      // 缓存当前视口大小，确保拖动过程中大小不变
      this.lastViewportSize = {
        width: vpRect.width,
        height: vpRect.height,
      };
    } else {
      // 直接移动视口中心到点击位置
      this.moveViewport(x, y, true);
    }
  }

  /**
   * 处理小地图鼠标移动事件
   */
  handleMinimapMouseMove(e) {
    if (!this.isDragging || !this.visible) return;

    e.preventDefault();

    const rect = this.minimapCanvas.getBoundingClientRect();
    const x = e.clientX - rect.left;
    const y = e.clientY - rect.top;

    const deltaX = x - this.dragStart.x;
    const deltaY = y - this.dragStart.y;

    // 更新拖拽起始位置
    this.dragStart = { x, y };

    // 移动画布视口
    this.moveViewport(this.dragStartViewport.x + deltaX, this.dragStartViewport.y + deltaY, false);

    // 更新拖拽起始视口位置
    this.dragStartViewport = this.calculateViewportRect();

    // 立即渲染小地图，提升拖动流畅度
    this.render();
  }

  /**
   * 处理小地图鼠标抬起事件
   */
  handleMinimapMouseUp() {
    this.isDragging = false;
  }

  /**
   * 移动主画布视口到指定位置
   */
  moveViewport(x, y, isCentered) {
    if (!this.mainCanvas) return;

    // 获取主画布的当前视图信息
    const vpt = this.mainCanvas.viewportTransform;
    const zoom = this.mainCanvas.getZoom();

    // 计算内容边界在小地图上的比例
    const contentWidth = this.contentBounds.maxX - this.contentBounds.minX;
    const contentHeight = this.contentBounds.maxY - this.contentBounds.minY;

    const scaleX = this.minimapSize.width / contentWidth;
    const scaleY = this.minimapSize.height / contentHeight;

    // 计算视口在小地图上的宽高
    let viewportWidth, viewportHeight;
    if (this.isDragging && this.lastViewportSize.width > 0) {
      viewportWidth = this.lastViewportSize.width;
      viewportHeight = this.lastViewportSize.height;
    } else {
      viewportWidth = Math.round((this.mainCanvas.getWidth() / zoom) * scaleX);
      viewportHeight = Math.round((this.mainCanvas.getHeight() / zoom) * scaleY);
    }

    // 添加边界限制，确保视口不会超出小地图
    x = Math.max(0, Math.min(x, this.minimapSize.width - viewportWidth));
    y = Math.max(0, Math.min(y, this.minimapSize.height - viewportHeight));

    // 将小地图坐标转换为主画布坐标
    let targetX = x / scaleX + this.contentBounds.minX;
    let targetY = y / scaleY + this.contentBounds.minY;

    if (isCentered) {
      // 如果是直接点击，则将点击位置设为视口中心
      targetX -= this.mainCanvas.getWidth() / zoom / 2;
      targetY -= this.mainCanvas.getHeight() / zoom / 2;
    }

    // 设置主画布的位置
    this.mainCanvas.setViewportTransform([
      vpt[0],
      vpt[1],
      vpt[2],
      vpt[3],
      -targetX * zoom,
      -targetY * zoom,
    ]);

    // 触发主画布重新渲染
    this.mainCanvas.renderAll();
  }

  /**
   * 计算当前视口在小地图中的位置和大小
   */
  calculateViewportRect() {
    if (!this.mainCanvas) return { x: 0, y: 0, width: 0, height: 0 };

    // 获取主画布的视图变换信息
    const vpt = this.mainCanvas.viewportTransform;
    const zoom = this.mainCanvas.getZoom();

    // 计算内容边界在小地图上的比例
    const contentWidth = this.contentBounds.maxX - this.contentBounds.minX;
    const contentHeight = this.contentBounds.maxY - this.contentBounds.minY;

    const scaleX = this.minimapSize.width / contentWidth;
    const scaleY = this.minimapSize.height / contentHeight;

    // 计算当前视口区域相对于内容边界的位置
    const viewLeft = -vpt[4] / zoom - this.contentBounds.minX;
    const viewTop = -vpt[5] / zoom - this.contentBounds.minY;

    // 转换为小地图上的坐标，使用取整减少精度误差
    const x = Math.round(viewLeft * scaleX);
    const y = Math.round(viewTop * scaleY);

    // 如果正在拖动，则使用缓存的大小避免抖动
    let width, height;
    if (this.isDragging && this.lastViewportSize.width > 0) {
      width = this.lastViewportSize.width;
      height = this.lastViewportSize.height;
    } else {
      width = Math.round((this.mainCanvas.getWidth() / zoom) * scaleX);
      height = Math.round((this.mainCanvas.getHeight() / zoom) * scaleY);

      // 更新缓存的视口大小
      if (!this.isDragging) {
        this.lastViewportSize = { width, height };
      }
    }

    return { x, y, width, height };
  }

  /**
   * 渲染小地图
   * 使用高性能的离屏渲染
   */
  render() {
    if (!this.visible || !this.minimapCanvas || !this.mainCanvas) return;

    try {
      // 清空小地图
      this.minimapCtx.clearRect(0, 0, this.minimapSize.width, this.minimapSize.height);

      // 绘制小地图背景
      this.minimapCtx.fillStyle = this.mainCanvas.backgroundColor || "#f0f0f0";
      this.minimapCtx.fillRect(0, 0, this.minimapSize.width, this.minimapSize.height);

      // 计算内容边界尺寸
      const contentWidth = this.contentBounds.maxX - this.contentBounds.minX;
      const contentHeight = this.contentBounds.maxY - this.contentBounds.minY;

      // 检查是否有内容需要渲染
      const objects = this.mainCanvas.getObjects();
      if (objects.length === 0) {
        // 如果没有对象，只需绘制视口框
        this.drawViewportBox();
        return;
      }

      // 优化离屏渲染尺寸计算
      const maxSize = 1000; // 限制离屏canvas最大尺寸，提高性能
      let offscreenWidth = contentWidth;
      let offscreenHeight = contentHeight;
      let scale = 1;

      if (contentWidth > maxSize || contentHeight > maxSize) {
        scale = Math.min(maxSize / contentWidth, maxSize / contentHeight);
        offscreenWidth *= scale;
        offscreenHeight *= scale;
      }

      const offscreenCanvas = document.createElement("canvas");
      offscreenCanvas.width = offscreenWidth;
      offscreenCanvas.height = offscreenHeight;
      const offCtx = offscreenCanvas.getContext("2d");

      // 创建临时fabric.Canvas用于渲染全内容
      const tempFabricCanvas = new fabric.StaticCanvas();
      tempFabricCanvas.setWidth(offscreenWidth);
      tempFabricCanvas.setHeight(offscreenHeight);
      tempFabricCanvas.backgroundColor = this.mainCanvas.backgroundColor;

      // 复制主画布对象到临时画布
      objects.forEach((obj) => {
        if (!obj.visible) return;

        try {
          // 使用浅克隆，避免深度克隆带来的性能开销
          const clonedObj = fabric.util.object.clone(obj);

          // 调整对象位置和大小，使其相对于内容边界并适应缩放
          clonedObj.set({
            left: (obj.left - this.contentBounds.minX) * scale,
            top: (obj.top - this.contentBounds.minY) * scale,
            scaleX: obj.scaleX * scale,
            scaleY: obj.scaleY * scale,
            // 禁用对象的交互属性，提高性能
            selectable: false,
            evented: false,
            hasControls: false,
            hasBorders: false,
          });

          tempFabricCanvas.add(clonedObj);
        } catch (err) {
          console.warn("无法克隆对象到小地图", err);
        }
      });

      // 渲染临时画布
      tempFabricCanvas.renderAll();

      // 将临时画布内容绘制到离屏canvas
      offCtx.drawImage(tempFabricCanvas.getElement(), 0, 0);

      // 将离屏canvas缩放绘制到小地图
      this.minimapCtx.drawImage(
        offscreenCanvas,
        0,
        0,
        offscreenWidth,
        offscreenHeight,
        0,
        0,
        this.minimapSize.width,
        this.minimapSize.height
      );

      // 释放临时画布资源
      // tempFabricCanvas.dispose();

      // 绘制视口框
      this.drawViewportBox();
    } catch (error) {
      console.error("小地图渲染出错:", error);
    }
  }

  /**
   * 绘制视口框，从render方法中分离出来提高代码清晰度
   */
  drawViewportBox() {
    // 计算当前视口范围
    const vpRect = this.calculateViewportRect();

    // 视口矩形边框
    this.minimapCtx.strokeStyle = "#ff3333";
    this.minimapCtx.lineWidth = 2;
    this.minimapCtx.strokeRect(vpRect.x, vpRect.y, vpRect.width, vpRect.height);

    // 视口矩形半透明填充
    this.minimapCtx.fillStyle = "rgba(255, 0, 0, 0.1)";
    this.minimapCtx.fillRect(vpRect.x, vpRect.y, vpRect.width, vpRect.height);
  }

  /**
   * 设置小地图可见性
   */
  setVisibility(visible) {
    this.visible = visible;

    // 更新canvas显示状态
    if (this.minimapCanvas) {
      this.minimapCanvas.style.display = visible ? "block" : "none";
    }

    if (visible && this.initialized) {
      this.contentBoundsDirty = true; // 标记需要重新计算内容边界
      this.calculateContentBounds();
      this.render();
    }
  }

  /**
   * 刷新小地图
   * 重新读取大画布数据并渲染
   */
  refresh() {
    this.contentBoundsDirty = true;
    this.calculateContentBounds();
    this.render();
  }

  /**
   * 调整小地图大小
   * @param {Object} size 小地图尺寸，{width, height}
   */
  resize(size) {
    if (!size || !size.width || !size.height) return;

    this.minimapSize = {
      width: size.width,
      height: size.height,
    };

    if (this.minimapCanvas) {
      this.minimapCanvas.width = size.width;
      this.minimapCanvas.height = size.height;
      this.refresh();
    }
  }

  /**
   * 清理资源，释放内存
   */
  dispose() {
    this.removeEventListeners();

    // 从DOM中移除canvas
    if (this.container && this.minimapCanvas && this.minimapCanvas.parentNode === this.container) {
      this.container.removeChild(this.minimapCanvas);
    }

    this.mainCanvas = null;
    this.minimapCanvas = null;
    this.minimapCtx = null;
    this.container = null;
    this.initialized = false;
  }

  /**
   * 更新小地图
   * 使用更高效的渲染策略，减少不必要的重绘
   */
  update() {
    if (!this.enabled || !this.minimapCanvas) return;

    // 使用节流来控制更新频率
    if (this._updateTimeout) {
      clearTimeout(this._updateTimeout);
    }

    this._updateTimeout = setTimeout(() => {
      this._renderMinimap();
    }, 100); // 100ms 的节流，避免频繁渲染
  }

  /**
   * 渲染小地图
   * 优化渲染性能，只在必要时重绘
   */
  _renderMinimap() {
    if (!this.minimapCanvas || !this.canvas) return;

    const ctx = this.minimapCanvas.getContext("2d");
    const ratio = this.minimapCanvas.width / this.canvas.width;

    // 清除小地图
    ctx.clearRect(0, 0, this.minimapCanvas.width, this.minimapCanvas.height);

    // 使用缓存策略
    if (!this._minimapCache || this._shouldUpdateCache()) {
      // 创建离屏画布作为缓存
      if (!this._offscreenCanvas) {
        this._offscreenCanvas = document.createElement("canvas");
        this._offscreenCanvas.width = this.minimapCanvas.width;
        this._offscreenCanvas.height = this.minimapCanvas.height;
      }

      const offCtx = this._offscreenCanvas.getContext("2d");
      offCtx.clearRect(0, 0, this._offscreenCanvas.width, this._offscreenCanvas.height);

      // 绘制图层内容到离屏画布
      this._renderLayersToMinimap(offCtx, ratio);

      // 保存渲染时间戳
      this._lastCacheUpdate = Date.now();
      this._minimapCache = true;
    }

    // 将缓存的内容渲染到实际小地图画布
    if (this._offscreenCanvas) {
      ctx.drawImage(this._offscreenCanvas, 0, 0);
    }

    // 绘制可视区域指示器
    this._renderViewportIndicator(ctx, ratio);
  }

  /**
   * 检查是否应该更新小地图缓存
   */
  _shouldUpdateCache() {
    // 如果没有缓存或缓存时间超过500ms，则更新
    return !this._lastCacheUpdate || Date.now() - this._lastCacheUpdate > 500;
  }

  /**
   * 渲染图层内容到小地图
   */
  _renderLayersToMinimap(ctx, ratio) {
    // 获取画布上所有可见的图层
    const visibleLayers = [];

    // 安全地访问图层数据，避免 "forEach is not a function" 错误
    if (this.canvas && this.canvas.layers) {
      // 检查 layers 是否是响应式对象 (有 value 属性)
      const layersArray =
        typeof this.canvas.layers.value !== "undefined"
          ? this.canvas.layers.value
          : Array.isArray(this.canvas.layers)
            ? this.canvas.layers
            : [];

      // 过滤出可见图层
      layersArray.forEach((layer) => {
        if (layer.visible) {
          visibleLayers.push(layer);
        }
      });
    }

    // 按照图层顺序渲染到小地图
    for (const layer of visibleLayers) {
      let objectsToRender = [];

      // 根据图层类型获取要渲染的对象
      if (layer.type === "background" && layer.fabricObject) {
        objectsToRender = [layer.fabricObject];
      } else if (layer.fabricObjects && Array.isArray(layer.fabricObjects)) {
        objectsToRender = layer.fabricObjects;
      }

      for (const fabricObj of objectsToRender) {
        if (!fabricObj.visible) continue;

        // 根据对象类型渲染到小地图
        if (fabricObj.type === "image" && fabricObj._element) {
          ctx.globalAlpha = fabricObj.opacity || 1;
          const left = fabricObj.left * ratio;
          const top = fabricObj.top * ratio;
          const width = fabricObj.width * fabricObj.scaleX * ratio;
          const height = fabricObj.height * fabricObj.scaleY * ratio;

          ctx.drawImage(fabricObj._element, left, top, width, height);
        } else if (
          fabricObj.type === "path" ||
          fabricObj.type === "rect" ||
          fabricObj.type === "circle"
        ) {
          // 简单地用颜色块表示其他类型的对象
          ctx.fillStyle = fabricObj.fill || "#888";
          ctx.globalAlpha = fabricObj.opacity || 0.5;

          const left = fabricObj.left * ratio;
          const top = fabricObj.top * ratio;
          const width = (fabricObj.width || 20) * (fabricObj.scaleX || 1) * ratio;
          const height = (fabricObj.height || 20) * (fabricObj.scaleY || 1) * ratio;

          ctx.fillRect(left, top, width, height);
        }
      }
    }

    ctx.globalAlpha = 1;
  }

  /**
   * 渲染视口指示器
   */
  _renderViewportIndicator(ctx, ratio) {
    if (!this.canvas) return;

    const vpt = this.canvas.viewportTransform;
    if (!vpt) return;

    // 计算可视区域在小地图上的位置和大小
    const zoom = this.canvas.getZoom();
    const viewportWidth = this.canvas.width / zoom;
    const viewportHeight = this.canvas.height / zoom;

    const x = (-vpt[4] / zoom) * ratio;
    const y = (-vpt[5] / zoom) * ratio;
    const width = viewportWidth * ratio;
    const height = viewportHeight * ratio;

    // 绘制视口指示器
    ctx.strokeStyle = "#ff0000";
    ctx.lineWidth = 2;
    ctx.strokeRect(x, y, width, height);
  }

  /**
   * 强制完全更新小地图
   */
  forceUpdate() {
    this._minimapCache = false;
    this.update();
  }
}

export default MinimapManager;
