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 FillGroupLayerBackgroundCommand extends Command {
  constructor(options) {
    super({ name: "填充组图层背景", saveState: true });
    this.canvas = options.canvas;
    this.layers = options.layers;
    this.canvasManager = options.canvasManager;
	this.layerManager = options.layerManager;
    this.layerId = options.layerId;
    this.fillColor = options.fillColor;
    this.oldFill = null;
    this.oldFillColor = null;
    this.newFill = null;

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

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

    this.group = null;

    this.originalfabricObjects = this._collectOriginalObjects(); // 记录所有的原始对象

    // 计算所有对象的边界
    this.originalInfo = this._getCurrentObjectsBoundingRect();

    this.firstObj = null; // 用于存储组图层的原始对象
  }

  async execute(isUndo = false) {
	const { layer, parent } = findLayerRecursively(
      this.layers.value,
      this.layerId
    );
    this.layer = layer;
    this.parent = parent;
	console.log("==========",layer);
    if (!layer) return false;

	if(!isUndo){
		this.oldFill = layer.fill ?? null;
		this.oldFillColor = layer.fillColor ?? null;
		if(this.oldFill){
			// 移除旧的填充对象
			removeCanvasObjectByObject(this.canvas, this.oldFill);
		}
	}
	const fillColor = isUndo ? this.oldFillColor : this.fillColor;
    // 构建填充对象
    let clippingMaskFabricObject = null;
    if (layer.clippingMask) {
      clippingMaskFabricObject = await restoreFabricObject(
        layer.clippingMask,
        this.canvas
      );
    //   clippingMaskFabricObject.clipPath = null;
      clippingMaskFabricObject.set({ absolutePositioned: true });
      this.newFill = new fabric.Rect({
        width: clippingMaskFabricObject.width,
        height: clippingMaskFabricObject.height,
        left: clippingMaskFabricObject.left || 0,
        top: clippingMaskFabricObject.top || 0,
        fill: 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: fillColor,
          layerId: this.layerId,
          id: this.oldFill?.id || generateId("fill-"),
          selectable: false,
          evented: false,
          originX: "center",
          originY: "center",
        });
      }
    }

    // 判断fabricObjects是否是组对象
    const firstObj = layer.fabricObjects?.[0] || null;
    // 如果没有找到第一个对象，则直接添加到当前画布
    if (!firstObj) {
      if (this?.parent?.clippingMask) {
        clippingMaskFabricObject = await restoreFabricObject(
          this.parent.clippingMask,
          this.canvas
        );
        // clippingMaskFabricObject.clipPath = null;
        clippingMaskFabricObject.set({ absolutePositioned: true });
        this.newFill = new fabric.Rect({
          width: clippingMaskFabricObject.width,
          height: clippingMaskFabricObject.height,
          left: clippingMaskFabricObject.left || 0,
          top: clippingMaskFabricObject.top || 0,
          fill: 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,
        });
      } else {
        this.newFill = new fabric.Rect({
          width: this.canvasManager?.canvasWidth?.value || this.canvas.width,
          height: this.canvasManager?.canvasHeight?.value || this.canvas.height,
          left: this.canvas.width / 2 || 0,
          top: this.canvas.height / 2 || 0,
          fill: fillColor,
          layerId: this.layerId,
          id: this.oldFill?.id || generateId("fill-"),
          selectable: false,
          evented: false,
          originX: "center",
          originY: "center",
        });
      }
      this.newFill.clipPath = clippingMaskFabricObject; // 设置填充的遮罩
      this.newFill.dirty = true; // 标记为脏，以便重新
      this.canvas.add(this.newFill);
      this.firstObj = this.newFill;
      layer.fabricObjects = [
        this.newFill.toObject(["id", "layerId"]) || this.newFill,
      ];
      layer.fill = this.newFill; // this.newFill.toObject(["id", "layerId"]);
      layer.fillColor = fillColor;
      // 取消激活对象

      this.canvas.discardActiveObject(); // 取消当前活动对象
      // 重新排序
      await this.layerManager?.sortLayersWithTool?.();
      // 更新画布上对象的可选择状态
      await this.layerManager?.updateLayersObjectsInteractivity?.();
      this.canvas.renderAll();

      this.canvasManager.thumbnailManager?.generateLayerThumbnail(
        this.layer.id
      );
      return false;
    }
    const canvasObj = findObjectById(this.canvas, firstObj?.id)?.object;
    if (
      (canvasObj && canvasObj.type === "group") ||
      canvasObj._objects?.length > 0
    ) {
      this.newFill.set({
        left: 0,
        top: 0,
      });
      // 将新填充对象添加到组的最前面
      // canvasObj._objects.unshift(this.newFill);
      canvasObj.insertAt(this.newFill, 0, false);
      // canvasObj.addWithUpdate();
      canvasObj.setCoords();
      canvasObj.setObjectsCoords();
      canvasObj.dirty = true; // 标记为脏对象
      // this.canvas.renderAll();
      // this.group = canvasObj;
    } else if (layer.fabricObjects && layer.fabricObjects.length > 0) {
      // 普通对象，组成新组
      const layerObjects =
        this.canvas
          .getObjects()
          .filter((obj) => obj.layerId === this.layerId) || [];
      // layerObjects?.forEach((obj) => {
      //   obj.clipPath = null;
      //   obj.dirty = true;
      //   obj.setCoords();
      // });
      let insertIndex =
        this.canvas.getObjects()?.findIndex((obj) => obj.id === firstObj?.id) ??
        0;
      insertIndex = insertIndex === -1 ? 0 : insertIndex;
      layerObjects.forEach((obj) => {
        obj.clipPath = null;
      });
      this.group = new fabric.Group([this.newFill, ...layerObjects]);
      this.group.set({
        id: layerObjects[0]?.id || generateId("group-"),
        layerId: this.layer?.id,
        layerName: this.layer?.name,
      });
      // this.group.setCoords();
      // this.group.setObjectsCoords();
      // this.group.dirty = true; // 标记为脏对象
      if (this.parent?.clippingMask) {
        const clipPath = await restoreFabricObject(
          this.parent?.clippingMask,
          this.canvas
        );
        // clipPath.clipPath = null;
        clipPath.set({ absolutePositioned: true });
        this.group.clipPath = clipPath;
      }
      layer.fabricObjects = [
        this.group.toObject(["id", "layerId", "layerName"]) || this.group,
      ];
      // removeCanvasObjectByObject(this.canvas, layerObjects?.[0]);
      insertObjectAtZIndex(this.canvas, this.group, insertIndex, false, true);
    }

    // this.group?.addWithUpdate?.();
    // layer.fabricObjects = [this.group?.toObject?.(["id", "layerId"]) || this.group];
    // this.canvas.renderAll();
    layer.fill = this.newFill; // this.newFill.toObject(["id", "layerId"]);
    layer.fillColor = fillColor;
    // 取消激活对象

    this.canvas.discardActiveObject(); // 取消当前活动对象
    // 重新排序
    await this.layerManager?.sortLayersWithTool?.();
    // 更新画布上对象的可选择状态
    await this.layerManager?.updateLayersObjectsInteractivity?.();
    this.canvas.renderAll();

    this.canvasManager.thumbnailManager?.generateLayerThumbnail(this.layer.id);
    return true;
  }
  async undo() {
    if (!this.originalInfo && this.layer.fill) {
      this.canvas.discardActiveObject();
      this.canvas.remove(this.layer.fill);
      this.canvas.renderAll();
      this.parent && this.canvasManager.thumbnailManager?.generateLayerThumbnail(
        this.parent.id
      );
      this.canvasManager.thumbnailManager?.generateLayerThumbnail(
        this.layer.id
      );
      this.layer.fabricObjects = [];
      return false;
    }

    // 判断fabricObjects是否是组对象
    const firstObj = this.layer.fabricObjects?.[0];
    const canvasObj =
      this.group || findObjectById(this.canvas, firstObj?.id)?.object;

    if (
      (canvasObj && canvasObj.type === "group") ||
      canvasObj?._objects?.length > 0
    ) {
      // 移除新添加的填充对象
    //   if (canvasObj._objects?.[0] === this.newFill) {
      if (/^fill-/.test(canvasObj._objects?.[0]?.id)) {
        canvasObj._objects.shift();
        canvasObj.addWithUpdate();
        canvasObj.setCoords();
        canvasObj.dirty = true;
      }
      this.canvas.renderAll();
    } else if (this.group) {
      // 如果是新建的group，需要拆分还原
      // 先移除新建的group
      this.canvas.remove(this.group);
      // 重新添加原始对象
      this.originalfabricObjects.forEach((obj) => {
        if (!this.canvas.getObjects().includes(obj)) {
          this.canvas.add(obj);
        }
      });
      this.canvas.renderAll();
      this.group = null;
    }
	if(this.oldFill){
		this.layer.fill = this.oldFill;
		this.layer.fillColor = this.oldFillColor;
		return this.execute(true);
	}else{
		this.layer.fill = null;
		this.layer.fillColor = null;
	}

    this.canvas.discardActiveObject(); // 取消当前活动对象
    // 重新排序
    await this.layerManager?.sortLayersWithTool?.();
    // 更新画布上对象的可选择状态
    await this.layerManager?.updateLayersObjectsInteractivity?.();

    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,
    };
  }
}
