import { Command } from "./Command";
import { findLayerRecursively } from "../utils/layerHelper";
import { fabric } from "fabric-with-all";
import {
  findObjectById,
  generateId,
  insertObjectAtZIndex,
  removeCanvasObjectByObject,
} from "../utils/helper";
import { restoreFabricObject } from "../utils/objectHelper";

/**
 * 填充图层背景命令
 */
export class FillLayerBackgroundCommand extends Command {
  constructor(options) {
    super({ name: "填充图层背景", saveState: true });
    this.canvas = options.canvas;
    this.layers = options.layers;
    this.canvasManager = options.canvasManager;
    this.layerId = options.layerId;
    this.fillColor = options.fillColor;
    this.isRetimeUpdate = options.isRetimeUpdate; // 是否实时更新
    this.oldFill = null;
    this.oldFillColor = null;
    this.newFill = null;

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

    this.layer = layer;

    this.group = null;

    this.isGroupLayer = layer.isGroup || !!layer.children?.length || false; // 是否为组图层

    this.originalfabricObjects = this._collectOriginalObjects(); // 记录所有的原始对象
    // 计算所有对象的边界
    this.originalInfo = this._getCurrentObjectsBoundingRect();
  }

  async execute() {
    const layer = this.layer;
    // 只允许填充背景层或普通图层
    // if (!layer.isBackground && !layer.isFixed && !layer.fabricObjects?.length) return false;

    // 记录原填充色
    this.oldFill = layer.fill ?? null;
    this.oldFillColor = layer.oldFillColor ?? null;

    // 更新fabric对象填充
    // 1.如果图层有遮罩则用遮罩  2.如果没有遮罩则汇总当前fabricObjects下的所有对象的边界
    let clippingMaskFabricObject = null;
    if (layer.clippingMask) {
      // 反序列化 clippingMask
      clippingMaskFabricObject = await restoreFabricObject(
        layer.clippingMask,
        this.canvas
      );
    //   clippingMaskFabricObject.clipPath = null;

      clippingMaskFabricObject.set({
        // 设置绝对定位
        // ...getOriginObjectInfo(layer.clippingMask), // 恢复原定位
        absolutePositioned: true,
      });

      this.newFill = new fabric.Rect({
        width: clippingMaskFabricObject.width,
        height: clippingMaskFabricObject.height,
        left: clippingMaskFabricObject.left || 0,
        top: clippingMaskFabricObject.top || 0,
        fill: this.fillColor,
        layerId: this.layerId,
        id: this.oldFill?.id || generateId("fill-"),
        selectable: false,
        evented: false,
        originX: clippingMaskFabricObject.originX || "center",
        originY: clippingMaskFabricObject.originY || "center",
        scaleX: clippingMaskFabricObject.scaleX || 1,
        scaleY: clippingMaskFabricObject.scaleY || 1,
      });

      this.newFill.clipPath = clippingMaskFabricObject; // 设置填充的遮罩
      this.newFill.dirty = true; // 标记为脏，以便重新渲染
      this.newFill.setCoords();
    } else {
      const originalInfo = this.originalInfo;
      if (originalInfo) {
        this.newFill = new fabric.Rect({
          width: originalInfo.width,
          height: originalInfo.height,
          left: originalInfo.left + originalInfo.width / 2 || 0,
          top: originalInfo.top + originalInfo.height / 2 || 0,
          fill: this.fillColor,
          layerId: this.layerId,
          id: this.oldFill?.id || generateId("fill-"),
          selectable: false,
          evented: false,
          originX: "center",
          originY: "center",
        });
      }
    }

    // 判断fabricObjects是否是组，是组则添加填充到最前面，否则创建组
    if (layer.fabricObjects && layer.fabricObjects.length > 0) {
      let insertIndex =
        this.canvas
          .getObjects()
          ?.findIndex((obj) => obj.id === layer.fabricObjects?.[0]?.id) || 0;
      if (this.oldFill) {
        // 如果有旧填充，先获取旧的索引再移除旧填充
        insertIndex =
          this.canvas
            .getObjects()
            ?.findIndex((obj) => obj.id === this.oldFill?.id) || 0;
        removeCanvasObjectByObject(this.canvas, this.oldFill);
      }
      insertIndex = insertIndex == -1 ? 0 : insertIndex;
      // layer.fabricObjects = [this.newFill?.toObject?.(["id", "layerId"]) || this.newFill];
      insertObjectAtZIndex(this.canvas, this.newFill, insertIndex, false); // 插入到画布的指定位置
      // 将新填充对象添加到画布
    } else if (layer.children && layer.children.length > 0) {
      // 如果是组图层，直接添加到组中
      let insertIndex =
        this.canvas
          .getObjects()
          .findIndex(
            (obj) =>
              obj.id ===
              this.originalfabricObjects[this.originalfabricObjects.length - 1]
                ?.id
          ) || 0;

      if (this.oldFill) {
        // 如果有旧填充，先获取旧的索引再移除旧填充
        insertIndex =
          this.canvas
            .getObjects()
            ?.findIndex((obj) => obj.id === this.oldFill?.id) || 0;
        removeCanvasObjectByObject(this.canvas, this.oldFill);
      }
      insertIndex = insertIndex == -1 ? 0 : insertIndex;

      insertObjectAtZIndex(this.canvas, this.newFill, insertIndex, false); // 插入到画布的指定位置
    }

    this.canvas.renderAll();

    // 实时更新的时候不生成缩略图
    if (!this.isRetimeUpdate) {
      layer.fill = this.newFill.toObject(["id", "layerId"]);
      layer.fillColor = this.fillColor;
      this.canvasManager.thumbnailManager?.generateLayerThumbnail(
        this.layer.id
      );

      // 重新排序
      // 使用LayerSort工具重新排列画布对象（如果可用）
      // await this?.canvasManager?.layerManager?.layerSort?.rearrangeObjects?.();
    }
    return true;
  }

  async undo() {
    // this.group.removeWithUpdate(this.newFill);
    // this.canvas.remove(this.newFill);
    if (this.oldFill) {
      // 如果有旧填充，恢复旧填充
      const { object } = findObjectById(this.canvas, this.oldFill.id);
      if (object) {
        this.newFill.set({
          fill: this.oldFill.fill,
          left: this.oldFill.left,
          top: this.oldFill.top,
          width: this.oldFill.width,
          height: this.oldFill.height,
        });
        this.newFill.setCoords();
      }
    } else {
      // 如果没有旧填充，移除新填充
      removeCanvasObjectByObject(this.canvas, this.layer.fill);
    }
    this.canvas.renderAll();

    this.layer.fillColor = this.oldFillColor;
    this.layer.fill = this.oldFill;
    this.canvasManager.thumbnailManager?.generateLayerThumbnail(this.layer.id);
    return true;
  }

  _collectOriginalObjects() {
    if (this.layer.children && this.layer.children.length > 0) {
      // 如果是组图层，收集所有子图层的fabric对象
      return this.layer.children
        .flatMap((child) => child.fabricObjects || [])
        .map((obj) => {
          return findObjectById(this.canvas.value, obj.id)?.object || obj;
        });
    } else if (
      this.layer.fabricObjects &&
      this.layer.fabricObjects.length > 0
    ) {
      // 如果是普通图层，直接返回其fabric对象
      return this.layer.fabricObjects.map((obj) => {
        return findObjectById(this.canvas.value, obj.id)?.object || obj;
      });
    } else {
      // 如果没有fabric对象，返回空数组
      return [];
    }
  }
  // 获取当前所有对象的边界信息
  _getCurrentObjectsBoundingRect() {
    // this.originalfabricObjects = this._collectOriginalObjects();
    let minLeft = Infinity,
      minTop = Infinity,
      maxRight = -Infinity,
      maxBottom = -Infinity;
    console.log(
      "计算当前所有对象的边界信息:===>",
      this.originalfabricObjects.length
    );
    this.originalfabricObjects?.forEach((obj) => {
      const { object } = findObjectById(this.canvas, obj.id) || {};
      if (object) {
        const rect = object.getBoundingRect({
          absolute: true,
          includeStroke: false,
        });
        minLeft = Math.min(minLeft, rect.left);
        minTop = Math.min(minTop, rect.top);
        maxRight = Math.max(maxRight, rect.left + rect.width);
        maxBottom = Math.max(maxBottom, rect.top + rect.height);
      }
    });
    if (minLeft === Infinity || minTop === Infinity) return null;
    return {
      left: minLeft,
      top: minTop,
      width: maxRight - minLeft,
      height: maxBottom - minTop,
    };
  }
}
