import { isArray } from "lodash-es";
import { optimizeCanvasRendering } from "../utils/helper";
import { restoreObjectLayerAssociations } from "../utils/layerUtils";
import { Command } from "./Command";

/**
 * 橡皮擦操作命令
 * 支持橡皮擦操作的撤销和重做
 */
export class EraserCommand extends Command {
  /**
   * 构造函数
   * @param {Object} options 命令选项
   * @param {Object} options.canvas Fabric画布实例
   * @param {Object} options.layerManager 图层管理器
   * @param {Object} options.beforeSnapshot 擦除前的状态快照
   * @param {Object} options.afterSnapshot 擦除后的状态快照
   * @param {Array} options.affectedObjects 擦除影响的对象列表（可选）
   */
  constructor(options) {
    super({
      name: "橡皮擦操作",
      description: `擦除`,
      ...options,
    });

    this.canvas = options.canvas;
    this.layerManager = options.layerManager;
    this.beforeSnapshot = options.beforeSnapshot;
    this.afterSnapshot = options.afterSnapshot;
    this.affectedObjects = options.affectedObjects || [];
    this.fristLoad = true; // 是否是第一次加载
  }

  /**
   * 执行橡皮擦操作
   */
  async execute() {
    if (!this.beforeSnapshot || !this.afterSnapshot) {
      console.warn("缺少状态快照，无法执行橡皮擦命令");
      return false;
    }
    if (!this.fristLoad)
      await this._restoreCanvasState(this.afterSnapshot); // 应用重做的状态
    else await this.layerManager?.updateLayersObjectsInteractivity?.(false);
    this.fristLoad = false; // 标记为非第一次加载
    return true;
  }

  /**
   * 撤销橡皮擦操作
   */
  async undo() {
    if (!this.beforeSnapshot) {
      console.warn("缺少擦除前的状态快照，无法撤销");
      return false;
    }

    // 恢复到擦除前的状态
    await this._restoreCanvasState(this.beforeSnapshot);

    return true;
  }

  /**
   * 恢复画布状态
   * @param {Object} snapshot 状态快照
   * @private
   */
  async _restoreCanvasState(snapshot) {
    // 对比  eraser   erasable  两个属性，如果当前对象的eraser属性和erasable属性不一致，则需要更新对象的eraser属性
    if (!snapshot || !snapshot.objects) return;
    // 优化渲染  -  统一批处理  支持异步回调  防止闪屏
    await optimizeCanvasRendering(this.canvas, async () => {
      return new Promise((resolve) => {
        this.canvas.loadFromJSON(snapshot, async () => {
          // 恢复图层关联
          this._restoreObjectLayerAssociations();
          // 确保所有对象的交互性正确设置
          await this.layerManager?.updateLayersObjectsInteractivity?.(false);
          resolve();
        });
      });
    });
  }

  /**
   * 恢复对象与图层的关联关系
   * @private
   */
  _restoreObjectLayerAssociations() {
    if (!this.layerManager) return;

    const canvasObjects = this.canvas.getObjects();
    restoreObjectLayerAssociations(this.layerManager?.layers?.value, canvasObjects);
  }
}
