import { CompositeCommand } from "../../commands/Command.js";
import { PerformanceManager } from "./PerformanceManager.js";

/**
 * 简化版命令管理器
 * 基于经典撤销/重做模式，支持命令队列
 * 使用复合命令替代事务处理
 */
export class CommandManager {
  constructor(options = {}) {
	this.canvas = options.canvas;
    this.undoStack = [];
    this.redoStack = [];
    this.maxHistorySize = options.maxHistorySize || 50;
    this.executing = false;

    // 命令执行队列
    this.commandQueue = [];
    this.processing = false;

    // 可选的性能管理器
    this.performanceManager = options.performanceManager || null;

    // 状态变化回调
    this.onStateChange = null;
  }

  // 兼容旧的executeCommand方法
  async executeCommand(command) {
    return this.execute(command);
  }

  /**
   * 执行命令并添加到撤销栈
   */
  async execute(command) {
    if (!command || typeof command.execute !== "function") {
      throw new Error("无效的命令对象");
    }

    return this._executeDirectly(command);
  }

  /**
   * 直接执行命令（绕过事务检查）
   * @private
   */
  async _executeDirectly(command) {
    // 返回Promise，等待命令执行完成
    return new Promise((resolve, reject) => {
      // 将命令添加到队列
      this.commandQueue.push({
        type: "execute",
        command,
        resolve,
        reject,
      });

      // 开始处理队列
      this._processQueue();
    });
  }

  /**
   * 撤销最后一个命令
   */
  async undo() {
    return new Promise((resolve, reject) => {
      // 检查是否可以撤销
      if (this.undoStack.length === 0) {
        console.warn("无法撤销：撤销栈为空");
        resolve(null);
        return;
      }

      // 将撤销操作添加到队列
      this.commandQueue.push({
        type: "undo",
        resolve,
        reject,
      });

      // 开始处理队列
      this._processQueue();
    });
  }

  /**
   * 重做最后一个撤销的命令
   */
  async redo() {
    return new Promise((resolve, reject) => {
      // 检查是否可以重做
      if (this.redoStack.length === 0) {
        console.warn("无法重做：重做栈为空");
        resolve(null);
        return;
      }

      // 将重做操作添加到队列
      this.commandQueue.push({
        type: "redo",
        resolve,
        reject,
      });

      // 开始处理队列
      this._processQueue();
    });
  }

  /**
   * 处理命令队列
   * @private
   */
  async _processQueue() {
    // 如果正在处理或队列为空，直接返回
    if (this.processing || this.commandQueue.length === 0) {
      return;
    }

    this.processing = true;

    try {
      while (this.commandQueue.length > 0) {
        const task = this.commandQueue.shift();

        try {
          let result = null;

          switch (task.type) {
            case "execute":
              result = await this._executeCommandInternal(task.command);
              break;
            case "undo":
              result = await this._undoInternal();
              break;
            case "redo":
              result = await this._redoInternal();
              break;
            default:
              throw new Error(`未知的任务类型: ${task.type}`);
          }

          task.resolve(result);
        } catch (error) {
          task.reject(error);
        }
      }
    } finally {
      this.processing = false;
    }
  }

  /**
   * 内部执行命令方法
   * @private
   */
  async _executeCommandInternal(command) {
    this.executing = true;
    const startTime = performance.now();

    try {
      console.log(`🔄 执行命令: ${command.constructor.name}`);

      // 执行命令
      const result = await this._executeCommand(command);

      // 只有可撤销的命令才加入撤销栈
      if (command.undoable !== false) {
        this.undoStack.push(command);
        this.redoStack = []; // 清空重做栈

        // 限制历史记录大小
        this._trimHistory();
      }

      // 记录性能
      const duration = performance.now() - startTime;
      this._recordPerformance("execute", command.constructor.name, duration);

      // 通知状态变化
      this._notifyStateChange();

      console.log(`✅ 命令执行成功: ${command.constructor.name}`);
      return result;
    } catch (error) {
      console.error(`❌ 命令执行失败: ${command.constructor.name}`, error);
      throw error;
    } finally {
      this.executing = false;
    }
  }

  /**
   * 内部撤销方法
   * @private
   */
  async _undoInternal() {
    if (this.undoStack.length === 0) {
      console.warn("无法撤销：撤销栈为空");
      return null;
    }

    this.executing = true;
    const startTime = performance.now();

    try {
      this.canvas?.discardActiveObject();
      const command = this.undoStack.pop();
      console.log(`↩️ 撤销命令: ${command.constructor.name}`);

      const result = await this._undoCommand(command);

      this.redoStack.push(command);

      // 记录性能
      const duration = performance.now() - startTime;
      this._recordPerformance("undo", command.constructor.name, duration);

      // 通知状态变化
      this._notifyStateChange();

      console.log(`✅ 命令撤销成功: ${command.constructor.name}`);
      return result;
    } catch (error) {
      console.error(`❌ 命令撤销失败`, error);
      throw error;
    } finally {
      this.executing = false;
    }
  }

  /**
   * 内部重做方法
   * @private
   */
  async _redoInternal() {
    if (this.redoStack.length === 0) {
      console.warn("无法重做：重做栈为空");
      return null;
    }

    this.executing = true;
    const startTime = performance.now();

    try {
      this.canvas?.discardActiveObject();
      const command = this.redoStack.pop();
      console.log(`↪️ 重做命令: ${command.constructor.name}`);

      const result = await this._executeCommand(command);

      this.undoStack.push(command);

      // 记录性能
      const duration = performance.now() - startTime;
      this._recordPerformance("redo", command.constructor.name, duration);

      // 通知状态变化
      this._notifyStateChange();

      console.log(`✅ 命令重做成功: ${command.constructor.name}`);
      return result;
    } catch (error) {
      console.error(`❌ 命令重做失败`, error);
      throw error;
    } finally {
      this.executing = false;
    }
  }

  /**
   * 批量执行命令（使用 CompositeCommand）
   * 推荐使用此方法替代原来的事务机制
   */
  async executeBatch(commands, batchName = "批量操作") {
    if (!Array.isArray(commands) || commands.length === 0) {
      throw new Error("命令数组不能为空");
    }

    const compositeCommand = new CompositeCommand(commands, {
      name: batchName,
    });

    return this.execute(compositeCommand);
  }

  /**
   * 清空历史记录
   */
  clear() {
    // 清空队列中的所有任务
    while (this.commandQueue.length > 0) {
      const task = this.commandQueue.shift();
      task.reject(new Error("命令管理器已被清空"));
    }

    this.undoStack = [];
    this.redoStack = [];
    this._notifyStateChange();
    console.log("📝 命令历史已清空");
  }

  /**
   * 获取管理器状态
   */
  getState() {
    return {
      canUndo: this.undoStack.length > 0,
      canRedo: this.redoStack.length > 0,
      undoCount: this.undoStack.length,
      redoCount: this.redoStack.length,
      isExecuting: this.executing,
      isProcessing: this.processing,
      queueLength: this.commandQueue.length,

      lastCommand:
        this.undoStack.length > 0
          ? this.undoStack[this.undoStack.length - 1].constructor.name
          : null,
      nextRedoCommand:
        this.redoStack.length > 0
          ? this.redoStack[this.redoStack.length - 1].constructor.name
          : null,
    };
  }

  /**
   * 获取命令历史信息
   */
  getHistory() {
    return {
      undoHistory: this.undoStack.map((cmd) => ({
        name: cmd.constructor.name,
        info: cmd.getInfo ? cmd.getInfo() : {},
        timestamp: cmd.timestamp,
      })),
      redoHistory: this.redoStack.map((cmd) => ({
        name: cmd.constructor.name,
        info: cmd.getInfo ? cmd.getInfo() : {},
        timestamp: cmd.timestamp,
      })),
    };
  }

  setChangeCallback(callback) {
    if (typeof callback === "function") {
      this.onStateChange = callback;
    } else {
      throw new Error("回调必须是一个函数");
    }
  }

  /**
   * 执行单个命令
   * @private
   */
  async _executeCommand(command) {
    const result = command.execute();
    return this._isPromise(result) ? await result : result;
  }

  /**
   * 撤销单个命令
   * @private
   */
  async _undoCommand(command) {
    if (typeof command.undo !== "function") {
      throw new Error(`命令 ${command.constructor.name} 不支持撤销`);
    }

    const result = command.undo();
    return this._isPromise(result) ? await result : result;
  }

  /**
   * 检查是否为Promise
   * @private
   */
  _isPromise(value) {
    return (
      value &&
      typeof value === "object" &&
      typeof value.then === "function" &&
      typeof value.catch === "function"
    );
  }

  /**
   * 限制历史记录大小
   * @private
   */
  _trimHistory() {
    if (this.undoStack.length > this.maxHistorySize) {
      this.undoStack.shift();
    }
  }

  /**
   * 记录性能数据
   * @private
   */
  _recordPerformance(type, commandName, duration) {
    if (this.performanceManager) {
      if (type === "execute") {
        this.performanceManager.recordExecution(commandName, duration);
      } else if (type === "undo") {
        this.performanceManager.recordUndo(commandName, duration);
      } else if (type === "redo") {
        this.performanceManager.recordRedo(commandName, duration);
      }
    }
  }

  /**
   * 通知状态变化
   * @private
   */
  _notifyStateChange() {
    if (this.onStateChange) {
      try {
        this.onStateChange(this.getState());
      } catch (error) {
        console.error("状态变化回调执行失败:", error);
      }
    }
  }
}

/**
 * 创建命令管理器实例的工厂函数
 */
export function createCommandManager(options = {}) {
  return new CommandManager(options);
}
