import { findObjectById } from "../utils/helper";
import { findLayerRecursively } from "../utils/layerHelper";
import { restoreFabricObject } from "../utils/objectHelper";
import { Command } from "./Command";
import EventManager from "../utils/event.js";

/**
 * 对象变换命令
 * 轻量级命令，只记录对象的变换属性变化（位置、缩放、旋转）
 * 不保存整个对象或画布状态，只关注变换属性
 */
export class TransformCommand extends Command {
  constructor(options) {
    super({
      name: options.name || "对象变换",
      description: options.description || "移动、缩放或旋转对象",
      saveState: false, // 自己管理状态，避免递归
    });

    this.canvas = options.canvas;
    this.objectId = options.objectId;
    this.initialState = options.initialState || null;
    this.finalState = options.finalState || null;
    this.objectType = options.objectType || "object";
    this.layerManager = options.layerManager;
    this.layers = options.layers || null;
    this.lastSelectLayerId = options.lastSelectLayerId || null; // 最后选择的图层ID

    const targetObject =
      findObjectById(this.canvas, this.objectId)?.object || null;

    const { layer, parent } = findLayerRecursively(
      this.layers.value,
      targetObject?.layerId
    );

    this.layer = layer;
    this.parent = parent;

    this.isSginleObject = parent?.id === this.lastSelectLayerId?.value; // 是否需要记录遮罩的变换位置  如果是组图层且组下只有一个图层有对象 且 用户最后点击的是父图层 则记录遮罩变更
  }

  /**
   * 执行命令
   * 如果是首次执行，记录初始和最终状态
   * 如果是重做，应用最终状态
   */
  async execute() {
    if (!this.finalState) {
      console.warn("没有最终状态可应用");
      return false;
    }

    // 查找目标对象
    const targetObject = this._findObject(this.objectId);
    if (!targetObject) {
      console.warn(`未找到ID为 ${this.objectId} 的对象`);
      return false;
    }

    // 应用最终变换状态
    await this._applyTransform(targetObject, this.finalState);

    setTimeout(() => {
      // 现在图层就是元素本身，直接更新元素的缩略图
      this?.layerManager?.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(
        this.layer.id
      );
      if (this.parent) {
        // 如果有父图层，更新父图层的缩略图
        this?.layerManager?.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(
          this.parent.id
        );
      }
    }, 300);

    // 触发画布更新
    this.canvas.renderAll();
	EventManager.emit("object:modified:execute", targetObject);
    return true;
  }

  /**
   * 撤销命令
   * 应用初始状态
   */
  async undo() {
    if (!this.initialState) {
      console.warn("没有初始状态可恢复");
      return false;
    }

    // 查找目标对象
    const targetObject = this._findObject(this.objectId);
    if (!targetObject) {
      console.warn(`未找到ID为 ${this.objectId} 的对象`);
      return false;
    }

    // 应用初始变换状态
    await this._applyTransform(targetObject, this.initialState);

    setTimeout(() => {
      // 现在图层就是元素本身，直接更新元素的缩略图
      this?.layerManager?.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(
        this.layer.id
      );
      if (this.parent) {
        // 如果有父图层，更新父图层的缩略图
        this?.layerManager?.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(
          this.parent.id
        );
      }
    }, 300);
    // 触发画布更新
    this.canvas.renderAll();
	EventManager.emit("object:modified:undo", targetObject);
    return true;
  }

  /**
   * 查找对象
   * @private
   */
  _findObject(objectId) {
    if (!this.canvas) return null;
    return this.canvas.getObjects().find((obj) => obj.id === objectId);
  }

  /**
   * 应用变换状态到对象
   * @private
   */
  async _applyTransform(object, transformState) {
    if (!object || !transformState) return;
    // 变换遮罩层 - 如果当前图层是组图层，且有遮罩并且组下只有一个图层有对象 则应用遮罩转换
    if (
      this.parent &&
      this.parent?.clippingMask &&
      // this.parent?.children?.length === 1 &&
      this.isSginleObject
    ) {
      // 计算对象的变换位置
      const moveLeft = object.left - transformState.left; // 计算移动的水平距离
      const moveTop = object.top - transformState.top; // 计算移动的垂直距离

      this.parent.clippingMask.left -= moveLeft;
      this.parent.clippingMask.top -= moveTop;
      if (this.parent.selectObject) {
        // 如果有选区 则选区位置也要更新
        this.parent.selectObject.left = this.parent.clippingMask.left;
        this.parent.selectObject.top = this.parent.clippingMask.top;
        const { object } = findObjectById(
          this.canvas,
          this.parent.selectObject?.id
        );
        object?.set({
          left: this.parent.clippingMask.left,
          top: this.parent.clippingMask.top,
        });
        object?.setCoords();
      }

      // 重新创建遮罩对象
      const clippingMaskFabricObject = await restoreFabricObject(
        this.parent.clippingMask,
        this.canvas
      );

      if (clippingMaskFabricObject) {
        // clippingMaskFabricObject.clipPath = null;
        clippingMaskFabricObject.set({
          absolutePositioned: true,
        });

        clippingMaskFabricObject.dirty = true;
        clippingMaskFabricObject.setCoords();

        // const clippingMask = this.parent.clippingMask;
        // object.clipPath = clippingMask;

        object.clipPath = clippingMaskFabricObject;
        object.dirty = true;
      }
    }

    // 应用变换属性，只设置真正变化的值
    Object.entries(transformState).forEach(([key, value]) => {
      object.set(key, value);
    });

    // 确保对象更新
    object.setCoords();
  }

  /**
   * 获取命令信息
   */
  getInfo() {
    return {
      name: this.name,
      description: this.description,
      objectId: this.objectId,
      objectType: this.objectType,
      changedProps: this.finalState ? Object.keys(this.finalState) : [],
    };
  }

  /**
   * 捕获对象的变换状态
   * @static
   */
  static captureTransformState(object) {
    if (!object) return null;

    // 只捕获变换相关的属性
    return {
      left: object.left,
      top: object.top,
      scaleX: object.scaleX,
      scaleY: object.scaleY,
      angle: object.angle,
      flipX: object.flipX,
      flipY: object.flipY,
      skewX: object.skewX,
      skewY: object.skewY,
    };
  }
}
