import { LogicalPosition, currentMonitor, getCurrentWindow } from '@tauri-apps/api/window';
import { ref } from 'vue';

// 获取当前窗口实例
const currentWindow = getCurrentWindow();

/** 当前触摸ID */
let activeTouchId: number | null = null;
/** 鼠标初始X坐标 */
let startMouseX = 0;
/** 鼠标初始Y坐标 */
let startMouseY = 0;

/** 触摸初始X坐标 */
let startTouchX = 0;
/** 触摸初始Y坐标 */
let startTouchY = 0;

/** 窗口初始X坐标 */
export const startWindowX = ref(0);
/** 窗口初始Y坐标 */
export const startWindowY = ref(0);

/** 屏幕宽度 */
let screenWidth = 0;
/** 屏幕高度 */
let screenHeight = 0;
/** 窗口宽度 */
let windowWidth = 0;
/** 窗口高度 */
let windowHeight = 0;

/**
 * 窗口吸附动画
 * @param startX - 起始X
 * @param startY - 起始Y
 * @param targetX - 目标X
 * @param targetY - 目标Y
 */
function animateMove(startX: number, startY: number, targetX: number, targetY: number) {
  const duration = 300; // 动画持续时间 ms
  const startTime = performance.now();

  /**
   * 步骤函数 用于移动
   * @param currentTime - 当前时间
   */
  function step(currentTime: number) {
    const elapsed = currentTime - startTime;
    const progress = Math.min(elapsed / duration, 1);

    // easeOutCubic 缓动效果
    const ease = 1 - (1 - progress) ** 3;

    const newX = startX + (targetX - startX) * ease;
    const newY = startY + (targetY - startY) * ease;

    currentWindow.setPosition(new LogicalPosition(newX, newY));

    if (progress < 1) {
      requestAnimationFrame(step);
    }
  }

  requestAnimationFrame(step);
}

/**
 * 自动吸附到屏幕边缘
 */
async function snapToEdge() {
  try {
    const monitor = await currentMonitor();
    if (!monitor) {
      return;
    }

    const factor = await currentWindow.scaleFactor();
    const windowPhysicalPos = await currentWindow.outerPosition();
    const windowLogicalPos = windowPhysicalPos.toLogical(factor);

    const windowPhysicalSize = await currentWindow.outerSize();
    const windowLogicalSize = windowPhysicalSize.toLogical(factor);

    const screenLogicalSize = monitor.size.toLogical(factor);

    const currentX = windowLogicalPos.x;
    const currentY = windowLogicalPos.y;

    const _windowWidth = windowLogicalSize.width;
    const _screenWidth = screenLogicalSize.width;

    // 计算窗口中心点X坐标
    const centerX = currentX + _windowWidth / 2;

    let targetX = 0;
    // 如果中心点在屏幕左半边，吸附到左边；否则吸附到右边
    if (centerX < _screenWidth / 2) {
      targetX = 0;
    } else {
      targetX = _screenWidth - _windowWidth;
    }

    // 执行动画移动到目标位置（Y轴保持不变）
    animateMove(currentX, currentY, targetX, currentY);
  } catch (error) {
    console.error('自动吸附失败:', error);
  }
}

/*******************************     鼠标     ********************************************************/
/*******************************     鼠标     ********************************************************/
/*******************************     鼠标     ********************************************************/
/*******************************     鼠标     ********************************************************/
/**
 * 鼠标移动事件处理函数 - 更新窗口位置
 * @param event - 鼠标事件
 */
function mouseMoveHandler(event: MouseEvent) {
  // 阻止默认行为
  event.preventDefault();

  // 计算位置偏移
  const deltaX = event.screenX - startMouseX;
  const deltaY = event.screenY - startMouseY;

  // 计算新位置
  let newX = startWindowX.value + deltaX;
  let newY = startWindowY.value + deltaY;

  // 边界检查：限制在屏幕范围内
  if (newX < 0) {
    newX = 0;
  }
  if (newX > screenWidth - windowWidth) {
    newX = screenWidth - windowWidth;
  }

  if (newY < 0) {
    newY = 0;
  }
  if (newY > screenHeight - windowHeight) {
    newY = screenHeight - windowHeight;
  }

  // 使用Tauri API直接移动窗口
  currentWindow.setPosition(new LogicalPosition(newX, newY));
}

/**
 * 鼠标释放事件处理函数 - 结束拖动
 * @param event - 鼠标事件
 */
function mouseUpHandler() {
  // 移除事件监听器
  document.removeEventListener('mousemove', mouseMoveHandler);
  document.removeEventListener('mouseup', mouseUpHandler);
  // 触发吸附
  snapToEdge();
}

/**
 * 鼠标按下事件处理函数 - 开始拖动窗口
 * @param event - 鼠标事件
 */
export async function handleMouseDown(event: MouseEvent) {
  // 确保只处理左键点击 且 目标元素包含 global-move-windows 类 除非 isAll 为 true
  if (event.button === 0) {
    // 阻止默认行为，防止事件冒泡
    event.preventDefault();
    try {
      // 获取缩放因子、窗口物理位置、窗口物理大小、当前显示器信息
      const [factor, windowPhysicalPosition, windowPhysicalSize, monitor] = await Promise.all([
        currentWindow.scaleFactor(),
        currentWindow.outerPosition(),
        currentWindow.outerSize(),
        currentMonitor(),
      ]);
      // 转换为逻辑像素位置
      const windowPosition = windowPhysicalPosition.toLogical(factor);
      const windowSize = windowPhysicalSize.toLogical(factor);

      // 保存窗口大小
      windowWidth = windowSize.width;
      windowHeight = windowSize.height;

      // 保存屏幕大小
      if (monitor) {
        const screenSize = monitor.size.toLogical(factor);
        screenWidth = screenSize.width;
        screenHeight = screenSize.height;
      }

      // 记录窗口初始位置
      startWindowX.value = windowPosition.x;
      startWindowY.value = windowPosition.y;
      // 记录鼠标初始位置
      startMouseX = event.screenX;
      startMouseY = event.screenY;

      // 添加鼠标移动和释放事件监听器
      document.addEventListener('mousemove', mouseMoveHandler);
      document.addEventListener('mouseup', mouseUpHandler);
    } catch (error: any) {
      console.error('获取窗口位置失败:', error);
    }
  }
}

/*******************************     触摸     ********************************************************/
/*******************************     触摸     ********************************************************/
/*******************************     触摸     ********************************************************/
/*******************************     触摸     ********************************************************/

/**
 * 触摸移动事件处理函数 - 更新窗口位置
 * @param event - 触摸事件
 */
function touchMoveHandler(event: TouchEvent) {
  if (activeTouchId === null) {
    return;
  }

  // 阻止默认行为，避免页面滚动
  event.preventDefault();

  // 找到对应的触摸点，确保是同一个手指（通过触摸ID判断）
  const touch = Array.from(event.touches).find((t) => t.identifier === activeTouchId);

  // 如果找不到匹配的触摸点（手指已经离开或更换了手指），则不执行拖动操作
  if (touch) {
    // 计算位置偏移
    const deltaX = touch.screenX - startTouchX;
    const deltaY = touch.screenY - startTouchY;

    // 计算新位置
    let newX = startWindowX.value + deltaX;
    let newY = startWindowY.value + deltaY;

    // 边界检查：限制在屏幕范围内
    if (newX < 0) {
      newX = 0;
    }
    if (newX > screenWidth - windowWidth) {
      newX = screenWidth - windowWidth;
    }

    if (newY < 0) {
      newY = 0;
    }
    if (newY > screenHeight - windowHeight) {
      newY = screenHeight - windowHeight;
    }

    // 使用Tauri API直接移动窗口
    currentWindow.setPosition(new LogicalPosition(newX, newY));
  }
}

/**
 * 触摸结束事件处理函数 - 结束拖动
 * @param event - 触摸事件
 */
function touchEndHandler(event: TouchEvent) {
  if (activeTouchId === null) {
    return;
  }

  // 检查结束的触摸点是否是我们正在跟踪的触摸点
  const endedTouchId = event.changedTouches[0]?.identifier;
  if (endedTouchId === activeTouchId) {
    activeTouchId = null;

    // 移除事件监听器
    document.removeEventListener('touchmove', touchMoveHandler);
    document.removeEventListener('touchend', touchEndHandler);
    document.removeEventListener('touchcancel', touchEndHandler);

    // 触发吸附
    snapToEdge();
  }
}

/**
 * 触摸开始事件处理函数 - 开始拖动窗口
 * @param event - 触摸事件
 */
export async function handleTouchStart(event: TouchEvent) {
  // 确保只有一个触摸点 且 目标元素包含 global-move-windows 类 除非 isAll 为 true
  if (event.touches.length === 1) {
    // 阻止默认行为，防止页面滚动
    event.preventDefault();

    const touch = event.touches[0]!;

    // 记录触摸点ID，用于后续判断是否是同一个手指
    const touchId = touch.identifier;

    try {
      // 获取缩放因子、窗口物理位置、窗口物理大小、当前显示器信息
      const [factor, windowPhysicalPosition, windowPhysicalSize, monitor] = await Promise.all([
        currentWindow.scaleFactor(),
        currentWindow.outerPosition(),
        currentWindow.outerSize(),
        currentMonitor(),
      ]);
      // 转换为逻辑像素位置
      const windowPosition = windowPhysicalPosition.toLogical(factor);
      const windowSize = windowPhysicalSize.toLogical(factor);

      // 保存窗口大小
      windowWidth = windowSize.width;
      windowHeight = windowSize.height;

      // 保存屏幕大小
      if (monitor) {
        const screenSize = monitor.size.toLogical(factor);
        screenWidth = screenSize.width;
        screenHeight = screenSize.height;
      }

      // 记录窗口初始位置
      startWindowX.value = windowPosition.x;
      startWindowY.value = windowPosition.y;

      // 记录触摸初始位置和ID
      startTouchX = touch.screenX;
      startTouchY = touch.screenY;
      activeTouchId = touchId;

      // 添加触摸移动和结束事件监听器
      document.addEventListener('touchmove', touchMoveHandler);
      document.addEventListener('touchend', touchEndHandler);
      document.addEventListener('touchcancel', touchEndHandler);
    } catch (error: any) {
      console.error('获取窗口位置失败:', error);
      activeTouchId = null;
    }
  }
}
