/**
 * 键盘管理器
 * 负责处理编辑器中的键盘事件和快捷键
 * 支持PC、Mac和iPad三端适配
 */
export class KeyboardManager {
  /**
   * 创建键盘管理器
   * @param {Object} options 配置选项
   * @param {Object} options.toolManager 工具管理器实例
   * @param {Object} options.commandManager 命令管理器实例
   * @param {Object} options.layerManager 图层管理器实例
   * @param {Object} options.canvasManager 画布管理器实例
   * @param {Function} options.pasteText 粘贴文本回调函数
   * @param {Function} options.pasteImage 粘贴图片回调函数
   * @param {Ref<Boolean>} options.isRedGreenMode 是否为红绿模式
   * @param {HTMLElement} options.container 容器元素，用于添加事件监听
   */
  constructor(options = {}) {
    this.toolManager = options.toolManager;
    this.commandManager = options.commandManager;
    this.layerManager = options.layerManager;
    this.canvasManager = options.canvasManager;
    this.container = options.container || document;
	this.pasteText = options.pasteText || (() => {});
	this.pasteImage = options.pasteImage || (() => {});
	this.isRedGreenMode = options.isRedGreenMode;

    // 检测平台类型
    this.platform = this.detectPlatform();
    this.isTouchDevice = this.detectTouchDevice();

    // 快捷键的平台特定键名
    this.modifierKeys = {
      ctrl: this.platform === "mac" ? "meta" : "ctrl",
      cmdOrCtrl: this.platform === "mac" ? "meta" : "ctrl",
      alt: "alt",
      shift: "shift",
      option: "alt", // Mac 特有，等同于 alt
      cmd: "meta", // Mac 特有，等同于 Command
    };

    // 快捷键显示的平台特定符号
    this.keySymbols = {
      ctrl: this.platform === "mac" ? "⌃" : "Ctrl",
      meta: this.platform === "mac" ? "⌘" : "Win",
      alt: this.platform === "mac" ? "⌥" : "Alt",
      shift: this.platform === "mac" ? "⇧" : "Shift",
      escape: "Esc",
      space: "空格",
    };

    // 快捷键映射表 - 可通过配置进行扩展
    this.shortcuts = this.initShortcuts();

    // 触摸相关状态
    this.touchState = {
      pinchStartDistance: 0,
      pinchStartBrushSize: 0,
      touchStartX: 0,
      touchStartY: 0,
      isTwoFingerTouch: false,
    };

    // 临时工具状态
    this.tempToolState = {
      active: false,
      originalTool: null,
    };

    // 事件绑定
    this._handleKeyDown = this.handleKeyDown.bind(this);
    this._handleKeyUp = this.handleKeyUp.bind(this);
	this._handlePaste = this.handlePaste.bind(this);
    this._handleTouchStart = this.handleTouchStart.bind(this);
    this._handleTouchMove = this.handleTouchMove.bind(this);
    this._handleTouchEnd = this.handleTouchEnd.bind(this);

    // 已注册的自定义事件处理程序
    this.customHandlers = {};
  }

  /**
   * 检测当前平台
   * @returns {'mac'|'windows'|'ios'|'android'|'other'} 平台类型
   */
  detectPlatform() {
    const userAgent = navigator.userAgent.toLowerCase();

    if (userAgent.indexOf("mac") !== -1) return "mac";
    if (userAgent.indexOf("win") !== -1) return "windows";
    if (/(iphone|ipad|ipod)/.test(userAgent)) return "ios";
    if (userAgent.indexOf("android") !== -1) return "android";

    return "other";
  }

  /**
   * 检测是否为触摸设备
   * @returns {boolean} 是否为触摸设备
   */
  detectTouchDevice() {
    return (
      "ontouchstart" in window || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0
    );
  }

  /**
   * 初始化快捷键配置
   * @returns {Object} 快捷键配置
   */
  initShortcuts() {
    const cmdOrCtrl = this.modifierKeys.cmdOrCtrl;

    // 基本快捷键映射，将在构建时根据平台类型自动调整
    return {
      // 撤销/重做
      [`${cmdOrCtrl}+z`]: { action: "undo", description: "撤销" },
      [`${cmdOrCtrl}+shift+z`]: { action: "redo", description: "重做" },
      [`${cmdOrCtrl}+y`]: { action: "redo", description: "重做" },

      // 复制/粘贴
      [`${cmdOrCtrl}+c`]: { action: "copy", description: "复制" },
      [`${cmdOrCtrl}+v`]: { action: "paste", description: "粘贴", noStop: true },
      [`${cmdOrCtrl}+x`]: { action: "cut", description: "剪切" },

      // 删除
      delete: { action: "delete", description: "删除" },
      backspace: { action: "delete", description: "删除" },
      up: { action: "up", description: "上" },
      down: { action: "down", description: "下" },
      left: { action: "left", description: "左" },
      right: { action: "right", description: "右" },

      // 选择
      [`${cmdOrCtrl}+a`]: { action: "selectAll", description: "全选" },
      escape: { action: "clearSelection", description: "取消选择" },

      // 保存
      [`${cmdOrCtrl}+s`]: { action: "save", description: "保存" },

      // 工具切换 (这些会由工具管理器处理)
      v: { action: "selectTool", param: "select", description: "选择工具" },
      b: { action: "selectTool", param: "draw", description: "画笔工具" },
      e: { action: "selectTool", param: "eraser", description: "橡皮擦" },
      i: { action: "selectTool", param: "eyedropper", description: "吸色工具" },
      h: { action: "selectTool", param: "pan", description: "移动画布" },
      l: { action: "selectTool", param: "lasso", description: "套索工具" },
      m: {
        action: "selectTool",
        param: "area_custom",
        description: "自由选区工具",
      },
      w: { action: "selectTool", param: "wave", description: "波浪工具" },
      j: { action: "selectTool", param: "liquify", description: "液化工具" },

      // 数值调整
      "shift+[": {
        action: "decreaseTextureScale",
        description: "减小材质图片大小",
      },
      "shift+]": {
        action: "increaseTextureScale",
        description: "增大材质图片大小",
      },
      "[": { action: "decreaseBrushSize", param: 1, description: "减小画笔" },
      "]": { action: "increaseBrushSize", param: 1, description: "增大画笔" },

      ",": {
        action: "decreaseBrushOpacity",
        param: 0.01,
        description: "减小透明度",
      },
      ".": {
        action: "increaseBrushOpacity",
        param: 0.01,
        description: "增大透明度",
      },

      // 空格 - 临时切换到手型工具
      space: {
        action: "toggleTempTool",
        param: "pan",
        description: "临时切换到手形工具",
      },

      // 图层操作
      [`${cmdOrCtrl}+shift+n`]: { action: "newLayer", description: "新建图层" },
      [`${cmdOrCtrl}+g`]: { action: "groupLayers", description: "组合图层" },
      [`${cmdOrCtrl}+o`]: {
        action: "addImageToNewLayer",
        description: "上传图片到新图层",
      },
      [`${cmdOrCtrl}+shift+g`]: {
        action: "ungroupLayers",
        description: "取消组合",
      },
      [`${cmdOrCtrl}+j`]: { action: "mergeLayers", description: "合并图层" },

      // iPad特有的快捷键(当无法使用键盘时)
      ...(this.platform === "ios" && {
        two_finger_tap: {
          action: "contextMenu",
          description: "显示上下文菜单",
        },
        three_finger_swipe_left: { action: "undo", description: "撤销" },
        three_finger_swipe_right: { action: "redo", description: "重做" },
      }),
    };
  }

  /**
   * 处理粘贴事件
   * @param {ClipboardEvent} event 粘贴事件
   */
  handlePaste(event) {
    event.preventDefault(); // 阻止默认粘贴行为
    if(this.isRedGreenMode.value) return;
	const text = event.clipboardData?.getData("text/plain") || "";
	if(/^aida_copy_canvas_layer/.test(text)) return;
	const items = event.clipboardData?.items || [];
		console.log(this);
	for (const item of items) {
        if (item.type.indexOf("text/plain") !== -1) {
            item.getAsString((text) => {
				this.pasteText(text);
            });
        } else if (item.type.indexOf("image") !== -1) {
            const blob = item.getAsFile();
			this.pasteImage(blob);
        }
    }
  }

  /**
   * 初始化并开始监听键盘事件
   */
  init() {
    // 添加键盘事件监听
    this.container.addEventListener("keydown", this._handleKeyDown);
    this.container.addEventListener("keyup", this._handleKeyUp);
    this.container.addEventListener("paste", this._handlePaste);

    // 如果是触摸设备，添加触摸事件监听
    if (this.isTouchDevice) {
      this.container.addEventListener("touchstart", this._handleTouchStart);
      this.container.addEventListener("touchmove", this._handleTouchMove);
      this.container.addEventListener("touchend", this._handleTouchEnd);
      this.container.addEventListener("touchcancel", this._handleTouchEnd);
    }

    console.log(`键盘管理器已初始化，平台: ${this.platform}, 触摸设备: ${this.isTouchDevice}`);
  }

  /**
   * hide模式下，关闭快捷键
   */
  removeEvents() {
    // 移除键盘事件监听
    this.container.removeEventListener("keydown", this._handleKeyDown);
    this.container.removeEventListener("keyup", this._handleKeyUp);
    this.container.removeEventListener("paste", this._handlePaste);

    // 如果是触摸设备，移除触摸事件监听
    if (this.isTouchDevice) {
      this.container.removeEventListener("touchstart", this._handleTouchStart);
      this.container.removeEventListener("touchmove", this._handleTouchMove);
      this.container.removeEventListener("touchend", this._handleTouchEnd);
      this.container.removeEventListener("touchcancel", this._handleTouchEnd);
    }
  }



  /**
   * 处理键盘按下事件
   * @param {KeyboardEvent} event 键盘事件
   */
  handleKeyDown(event) {
    // 如果当前焦点在输入框内，不处理大部分快捷键
    if (this.isInputActive() && !["Escape", "Tab"].includes(event.key)) {
      return;
    }

    // 构建快捷键标识符
    const shortcutKey = this.buildShortcutKey(event);

    // 查找并执行快捷键动作
    const shortcut = this.shortcuts[shortcutKey];
    if (shortcut) {
      // 阻止默认行为，例如浏览器的保存对话框等
      if (shortcutKey.includes(`${this.modifierKeys.cmdOrCtrl}+`) && !shortcut.noStop) {
        event.preventDefault();
      }

      this.executeAction(shortcut.action, shortcut.param, event);
      return;
    }

    // 工具快捷键处理
    if (this.toolManager && !event.ctrlKey && !event.metaKey && !event.altKey) {
      this.toolManager.handleKeyboardShortcut(event);
    }
  }

  /**
   * 处理键盘释放事件
   * @param {KeyboardEvent} event 键盘事件
   */
  handleKeyUp(event) {
    // 当空格键释放时，如果是临时工具，切回原始工具
    if (event.key === " " && this.tempToolState.active) {
      this.restoreTempTool();
    }

    // 调用自定义处理程序
    const key = event.key.toLowerCase();
    if (this.customHandlers[key] && typeof this.customHandlers[key].onKeyUp === "function") {
      this.customHandlers[key].onKeyUp(event);
    }
  }

  /**
   * 处理触摸开始事件
   * @param {TouchEvent} event 触摸事件
   */
  handleTouchStart(event) {
    const touches = event.touches;

    // 存储初始状态以便后续计算
    if (touches.length === 2) {
      // 双指触摸 - 可用于缩放或调整画笔大小
      this.touchState.isTwoFingerTouch = true;
      this.touchState.pinchStartDistance = this.getDistanceBetweenTouches(touches[0], touches[1]);

      // 如果有画笔管理器，记录起始画笔大小
      if (this.toolManager && this.toolManager.brushManager) {
        this.touchState.pinchStartBrushSize = this.toolManager.brushManager.brushSize.value;
      }
    } else if (touches.length === 3) {
      // 三指触摸 - 可用于撤销/重做
      this.touchState.touchStartX = touches[0].clientX;
    }
  }

  /**
   * 处理触摸移动事件
   * @param {TouchEvent} event 触摸事件
   */
  handleTouchMove(event) {
    const touches = event.touches;

    // 阻止默认行为（例如滚动）
    if (touches.length >= 2) {
      event.preventDefault();
    }

    // 双指缩放处理 - 调整画笔大小
    if (touches.length === 2 && this.touchState.isTwoFingerTouch) {
      const currentDistance = this.getDistanceBetweenTouches(touches[0], touches[1]);
      const scale = currentDistance / this.touchState.pinchStartDistance;

      // 调整画笔大小
      if (this.toolManager && this.toolManager.brushManager && scale !== 1) {
        const newSize = this.touchState.pinchStartBrushSize * scale;
        this.toolManager.brushManager.setBrushSize(newSize);
      }
    }
    // 三指滑动处理 - 撤销/重做
    else if (touches.length === 3) {
      const deltaX = touches[0].clientX - this.touchState.touchStartX;

      // 滑动超过50px认为是有效的手势
      if (Math.abs(deltaX) > 50) {
        if (deltaX < 0) {
          // 向左滑动 - 撤销
          this.executeAction("undo");
        } else {
          // 向右滑动 - 重做
          this.executeAction("redo");
        }

        // 更新起始位置，防止连续触发
        this.touchState.touchStartX = touches[0].clientX;
      }
    }
  }

  /**
   * 处理触摸结束事件
   * @param {TouchEvent} event 触摸事件
   */
  handleTouchEnd(event) {
    // 检测双指轻拍 (两个手指几乎同时按下，又几乎同时抬起)
    if (this.touchState.isTwoFingerTouch && event.touches.length === 0) {
      if (new Date().getTime() - this.touchState.touchStartTime < 300) {
        // 双指轻拍 - 可以触发上下文菜单
        this.executeAction("contextMenu");
      }
    }

    // 重置触摸状态
    this.touchState.isTwoFingerTouch = false;
  }

  /**
   * 计算两个触摸点之间的距离
   * @param {Touch} touch1 第一个触摸点
   * @param {Touch} touch2 第二个触摸点
   * @returns {number} 两点间距离
   */
  getDistanceBetweenTouches(touch1, touch2) {
    const dx = touch1.clientX - touch2.clientX;
    const dy = touch1.clientY - touch2.clientY;
    return Math.sqrt(dx * dx + dy * dy);
  }

  /**
   * 执行快捷键对应的动作
   * @param {string} action 动作名称
   * @param {*} param 动作参数
   * @param {Event} event 原始事件
   */
  executeAction(action, param, event) {
    switch (action) {
      case "undo":
        if (this.commandManager) {
          this.commandManager.undo();
        }
        break;

      case "redo":
        if (this.commandManager) {
          this.commandManager.redo();
        }
        break;

      case "copy":
        // 复制逻辑
        console.log("复制当前选中图层");
		if(this.isRedGreenMode.value) return;
        this.layerManager.copyLayer(this.layerManager.activeLayerId.value);
        break;

      case "paste":
        // 粘贴逻辑
        console.log("粘贴");
		if(this.isRedGreenMode.value) return;
        this.layerManager.pasteLayer();
        break;

      case "cut":
        // 剪切逻辑
        console.log("剪切");
		if(this.isRedGreenMode.value) return;
        this.layerManager.cutLayer(this.layerManager.activeLayerId.value);
        break;

      case "delete":
        // 删除逻辑
        console.log("删除");
		if(this.isRedGreenMode.value) return;
        this.layerManager.removeLayer(this.layerManager.activeLayerId.value);
        break;

      case "selectAll":
        // 全选逻辑
        console.log("全选");
		if(this.isRedGreenMode.value) return;
        // 这里需要实现全选逻辑 TODO:  是否在选择模式下才可以全选？
        if (this.layerManager) {
          this.layerManager.selectAll();
        }
        break;

      case "clearSelection":
        // 清除选择逻辑
        console.log("清除选择");
        // 这里需要实现清除选择逻辑
        if (this.layerManager) {
          this.layerManager.clearSelection();
        }
        break;

      case "save":
        // 保存逻辑
        console.log("保存");
        break;

      case "selectTool":
        // 选择工具
        if (this.toolManager && param) {
          this.toolManager.setToolWithCommand(param);
        }
        break;

	  case "up":
	  case "down":
	  case "left":
	  case "right":
        // 方向键逻辑
		this.canvasManager.moveActiveObject(action);
	    break;

      case "increaseBrushSize":
        // 增大画笔尺寸
        if (this.toolManager && this.toolManager.brushManager) {
          const amount = param || 5;
          this.toolManager.brushManager.increaseBrushSize(amount);
        }
        break;

      case "decreaseBrushSize":
        // 减小画笔尺寸
        if (this.toolManager && this.toolManager.brushManager) {
          const amount = param || 5;
          this.toolManager.brushManager.decreaseBrushSize(amount);
        }
        break;

      case "increaseBrushOpacity":
        // 增大画笔透明度
        if (this.toolManager && this.toolManager.brushManager) {
          const amount = param || 0.01;
          this.toolManager.brushManager.increaseBrushOpacity(amount);
        }
        break;

      case "decreaseTextureScale":
        // 减小画笔材质图片大小
        if (this.toolManager && this.toolManager.brushManager) {
          const amount = param || 5;
          this.toolManager.brushManager.decreaseBrushSize(amount);
        }
        break;

      case "increaseTextureScale":
        // 增大画笔材质图片大小
        if (this.toolManager && this.toolManager.brushManager) {
          const amount = param || 0.01;
          this.toolManager.brushManager.increaseTextureScale(amount);
        }
        break;

      case "decreaseBrushOpacity":
        // 减小画笔透明度
        if (this.toolManager && this.toolManager.brushManager) {
          const amount = param || 0.01;
          this.toolManager.brushManager.decreaseBrushOpacity(amount);
        }
        break;

      case "toggleTempTool":
        // 临时切换工具
        if (param && this.toolManager) {
          this.setTempTool(param);
        }
        break;

      case "newLayer":
        // 创建新图层
        if (this.layerManager) {
          this.layerManager.createNewLayer();
        }
        break;

      case "addImageToNewLayer":
        this.toolManager?.openFile?.();
        break;

      case "groupLayers":
        // 组合图层
        if (this.layerManager) {
          this.layerManager.groupSelectedLayers();
        }
        break;

      case "ungroupLayers":
        // 解组图层
        if (this.layerManager) {
          this.layerManager.ungroupSelectedLayer();
        }
        break;

      case "mergeLayers":
        // 合并图层
        if (this.layerManager) {
          this.layerManager.mergeSelectedLayers();
        }
        break;

      case "contextMenu":
        // 上下文菜单（通常由右击或触控设备上的特定手势触发）
        console.log("显示上下文菜单");
        // 这里需要实现显示上下文菜单的逻辑
        break;

      default:
        // 调用自定义注册的动作处理
        if (this.customHandlers[action]) {
          this.customHandlers[action].execute(param, event);
        }
    }
  }

  /**
   * 设置临时工具
   * @param {string} toolId 临时工具ID
   */
  setTempTool(toolId) {
    if (!this.toolManager || this.tempToolState.active) return;

    // 保存当前工具
    this.tempToolState.originalTool = this.toolManager.getCurrentTool();
    this.tempToolState.active = true;

    // 切换到临时工具
    this.toolManager.setTool(toolId);
  }

  /**
   * 恢复临时工具切换前的工具
   */
  restoreTempTool() {
    if (!this.toolManager || !this.tempToolState.active) return;

    // 恢复到原始工具
    if (this.tempToolState.originalTool) {
      this.toolManager.setTool(this.tempToolState.originalTool);
    }

    // 重置状态
    this.tempToolState.active = false;
    this.tempToolState.originalTool = null;
  }

  /**
   * 构建快捷键标识符
   * @param {KeyboardEvent} event 键盘事件
   * @returns {string} 快捷键标识符
   */
  buildShortcutKey(event) {
    let shortcutKey = "";

    // 统一处理Mac和PC的修饰键
    if ((this.platform === "mac" && event.metaKey) || (this.platform !== "mac" && event.ctrlKey)) {
      shortcutKey += `${this.modifierKeys.cmdOrCtrl}+`;
    } else if (event.ctrlKey) {
      shortcutKey += "ctrl+";
    }

    if (event.shiftKey) shortcutKey += "shift+";
    if (event.altKey) shortcutKey += "alt+";

    const key = event.key.toLowerCase();
    // 特殊键处理
    switch (key) {
      case " ":
        shortcutKey += "space";
        break;
      case "arrowup":
        shortcutKey += "up";
        break;
      case "arrowdown":
        shortcutKey += "down";
        break;
      case "arrowleft":
        shortcutKey += "left";
        break;
      case "arrowright":
        shortcutKey += "right";
        break;
      default:
        shortcutKey += key;
    }

    return shortcutKey;
  }

  /**
   * 检查当前是否有输入框处于活动状态
   * @returns {boolean} 是否有输入框处于活动状态
   */
  isInputActive() {
    const activeElement = document.activeElement;
    const tagName = activeElement.tagName.toLowerCase();
    return (
      tagName === "input" ||
      tagName === "textarea" ||
      activeElement.getAttribute("contenteditable") === "true"
    );
  }

  /**
   * 获取所有可用的快捷键
   * @returns {Array} 快捷键列表
   */
  getShortcuts() {
    return Object.entries(this.shortcuts).map(([key, value]) => ({
      key,
      displayKey: this.formatShortcutForDisplay(key),
      ...value,
    }));
  }

  /**
   * 格式化快捷键以便显示
   * @param {string} shortcut 快捷键标识符
   * @returns {string} 格式化后的快捷键显示
   */
  formatShortcutForDisplay(shortcut) {
    // 将快捷键格式化为适合当前平台显示的形式
    return shortcut
      .split("+")
      .map((key) => {
        // 将键名转换为显示符号
        return this.keySymbols[key.toLowerCase()] || key.toUpperCase();
      })
      .join("+");
  }

  /**
   * 注册自定义快捷键处理程序
   * @param {string} action 动作名称
   * @param {Object} handler 处理程序对象
   * @param {Function} handler.execute 执行函数
   * @param {Function} handler.onKeyUp 键释放处理函数（可选）
   * @param {string} description 描述
   */
  registerCustomHandler(action, handler, description = "") {
    if (!action || typeof handler.execute !== "function") {
      console.error("无效的自定义处理程序");
      return;
    }

    this.customHandlers[action] = handler;

    // 如果提供了快捷键，添加到快捷键映射
    if (handler.shortcut) {
      this.shortcuts[handler.shortcut] = {
        action,
        description: description || handler.description || action,
      };
    }
  }

  /**
   * 清理资源
   */
  dispose() {
    // 移除事件监听
    this.removeEvents();
    // 清除引用
    this.toolManager = null;
    this.commandManager = null;
    this.layerManager = null;
    this.container = null;
    this.customHandlers = {};
    this.tempToolState = { active: false, originalTool: null };
    this.touchState = {};
  }
}
