/**
 * @file AutoMove.ts
 * @description 思维导图画布自动移动管理类
 * @usage 用于处理画布在鼠标接近边缘时的自动移动效果
 */



/**
 * @class AutoMove
 * @description 画布自动移动控制类
 * @pattern 单例模式 - 每个画布实例对应一个自动移动实例
 * @example
 * ```ts
 * const autoMove = new AutoMove(mindMap)
 * autoMove.onMove(x, y)
 * ```
 */
class AutoMove {
  private mindMap: any
  private autoMoveTimer: number | null

  /**
   * @constructor
   * @param mindMap - 思维导图实例
   */
  constructor(mindMap: any) {
    this.mindMap = mindMap
    this.autoMoveTimer = null
  }

  /**
   * @method onMove
   * @description 处理鼠标移动事件,检测是否需要自动移动画布
   * @param x - 鼠标X坐标
   * @param y - 鼠标Y坐标  
   * @param callback - 移动回调函数
   * @param handle - 边缘处理函数
   * @throws 无异常抛出
   */
  onMove(
    x: number,
    y: number,
    callback: () => void = () => { },
    handle: (direction: string, step: number) => void = () => { }
  ): void {
    callback()
    // 获取移动配置参数
    const step = this.mindMap.opt.selectTranslateStep
    const limit = this.mindMap.opt.selectTranslateLimit
    let count = 0

    // 检测四个方向的边缘,触发相应的画布移动
    if (x <= this.mindMap.elRect.left + limit) {
      handle('left', step)
      this.mindMap.view.translateX(step)
      count++
    }
    if (x >= this.mindMap.elRect.right - limit) {
      handle('right', step)
      this.mindMap.view.translateX(-step)
      count++
    }
    if (y <= this.mindMap.elRect.top + limit) {
      handle('top', step)
      this.mindMap.view.translateY(step)
      count++
    }
    if (y >= this.mindMap.elRect.bottom - limit) {
      handle('bottom', step)
      this.mindMap.view.translateY(-step)
      count++
    }

    // 如果触发了边缘移动,则启动自动移动
    if (count > 0) {
      this.startAutoMove(x, y, callback, handle)
    }
  }

  /**
   * @method startAutoMove
   * @description 启动自动移动定时器
   * @param x - 鼠标X坐标
   * @param y - 鼠标Y坐标
   * @param callback - 移动回调函数
   * @param handle - 边缘处理函数
   */
  private startAutoMove(
    x: number,
    y: number,
    callback: () => void,
    handle: (direction: string, step: number) => void
  ): void {
    this.autoMoveTimer = window.setTimeout(() => {
      this.onMove(x, y, callback, handle)
    }, 20)
  }

  /**
   * @method clearAutoMoveTimer
   * @description 清除自动移动定时器
   */
  clearAutoMoveTimer(): void {
    if (this.autoMoveTimer) {
      clearTimeout(this.autoMoveTimer)
    }
  }
}

export default AutoMove