import { findObjectById } from "../utils/helper";
import { Command } from "./Command";
import { fabric } from "fabric-with-all";

/**
 * 创建背景图层命令
 */
export class CreateBackgroundLayerCommand extends Command {
  constructor(options) {
    super({
      name: "创建背景图层",
      saveState: true,
    });
    this.canvas = options.canvas;
    this.layers = options.layers;
    this.backgroundLayer = options.backgroundLayer;
    this.canvasManager = options.canvasManager;
    this.historyManager = options.historyManager;

    this.beforeLayers = [...this.layers.value]; // 备份原图层列表
  }

  execute() {
    // 检查是否已经存在背景图层
    const existingBgLayer = this.layers.value.find((layer) => layer.isBackground);
    if (existingBgLayer) {
      console.warn("已存在背景层，不重复创建");
      return existingBgLayer.id;
    }

    // 创建背景矩形对象
    const bgObject = this._createBackgroundObject();

    // 将背景对象添加到图层中
    this.backgroundLayer.fabricObject = bgObject.toObject(["id", "layerId", "type"]);

    // 添加图层到最底部
    this.layers.value.push(this.backgroundLayer);

    // 添加到画布
    this.canvas.add(bgObject);

    // 渲染画布
    this.canvas.renderAll();

    return this.backgroundLayer.id;
  }

  undo() {
    // 从图层列表中删除背景图层
    const bgLayerIndex = this.layers.value.findIndex((layer) => layer.isBackground);
    if (bgLayerIndex !== -1) {
      this.layers.value.splice(bgLayerIndex, 1);
    }

    // 从画布中移除背景对象
    if (this.backgroundLayer.fabricObject) {
      this.canvas.remove(this.backgroundLayer.fabricObject);
    }

    // 渲染画布
    this.canvas.renderAll();
  }

  /**
   * 创建背景矩形对象
   * @returns {Object} fabric.js 矩形对象
   * @private
   */
  _createBackgroundObject() {
    // 计算画布尺寸
    const canvasWidth = this.canvas.width;
    const canvasHeight = this.canvas.height;

    // 确保背景色为白色，如果没有设置或者是透明的话
    const backgroundColor =
      this.backgroundLayer.backgroundColor && this.backgroundLayer.backgroundColor !== "transparent"
        ? this.backgroundLayer.backgroundColor
        : "#ffffff";

    const rect = new fabric.Rect({
      left: canvasWidth / 2,
      top: canvasHeight / 2,
      width: this.backgroundLayer.canvasWidth,
      height: this.backgroundLayer.canvasHeight,
      fill: backgroundColor,
      selectable: false,
      evented: false,
      hoverCursor: "default",
      id: `bg_object_${this.backgroundLayer.id}`,
      layerId: this.backgroundLayer.id,
      layerName: this.backgroundLayer.name,
      originX: "center",
      originY: "center",
      isBackground: true, // 标记为背景对象
    });

    return rect;
  }

  getInfo() {
    return {
      name: this.name,
      layerId: this.backgroundLayer.id,
      layerName: this.backgroundLayer.name,
      width: this.backgroundLayer.canvasWidth,
      height: this.backgroundLayer.canvasHeight,
      backgroundColor: this.backgroundLayer.backgroundColor,
    };
  }
}

/**
 * 更新背景属性命令（如背景颜色）
 */
export class UpdateBackgroundCommand extends Command {
  constructor(options) {
    super({
      name: "更新背景属性",
      saveState: true,
    });
    this.canvas = options.canvas;
    this.layers = options.layers;
    this.canvasManager = options.canvasManager;
    this.backgroundColorValue = options.backgroundColorValue; // 使用.value获取实际值
    this.backgroundColor = options.backgroundColor; //
    this.historyManager = options.historyManager;
    this.oldColor = options.oldColor; // 旧颜色，用于撤销

    // 查找背景图层
    this.bgLayer = this.layers.value.find((layer) => layer.isBackground);
    this.oldBackgroundColor = this.oldColor;
    this.backgroundObject = findObjectById(this.canvas, this.bgLayer.fabricObject.id).object;
  }

  execute() {
    if (!this.bgLayer) {
      console.error("未找到背景图层");
      return false;
    }

    // 更新背景图层属性
    this.bgLayer.backgroundColor = this.backgroundColor;

    // 更新背景对象属性
    if (this.backgroundObject) {
      // const { object } = findObjectById(this.canvas, this.backgroundObject.id);
      this.backgroundObject.set("fill", this.backgroundColor);
      this.canvas.renderAll();
    }
    this.backgroundColorValue.value = this.backgroundColor; // 设置背景颜色

    // 生成缩略图
    this.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(this.bgLayer.id);
    return true;
  }

  undo() {
    if (!this.bgLayer) {
      return false;
    }

    // 恢复背景图层属性
    this.bgLayer.backgroundColor = this.oldBackgroundColor;

    // 恢复背景对象属性
    if (this.backgroundObject) {
      // const { object } = findObjectById(this.canvas, this.backgroundObject.id);
      this.backgroundObject.set("fill", this.oldBackgroundColor);
      this.canvas.renderAll();
    }
    this.backgroundColorValue.value = this.oldBackgroundColor; // 恢复背景颜色

    // 生成缩略图
    this.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(this.bgLayer.id);
    // 如果有旧颜色，恢复到旧颜色
    return true;
  }

  getInfo() {
    return {
      name: this.name,
      layerId: this.bgLayer?.id,
      oldColor: this.oldBackgroundColor,
      newColor: this.backgroundColor,
    };
  }
}

/**
 * 调整画布和背景大小命令
 */
export class BackgroundSizeCommand extends Command {
  constructor(options) {
    super({
      name: "调整背景大小",
      saveState: true,
    });
    this.canvas = options.canvas;
    this.layers = options.layers;
    this.canvasManager = options.canvasManager;
    this.newWidth = options.newWidth;
    this.newHeight = options.newHeight;
    this.historyManager = options.historyManager;
    this.isRedGreenMode = options.isRedGreenMode;

    this.bgLayer = this.layers.value.find((layer) => layer.isBackground);

    // 记录原尺寸
    this.backgroundObject = findObjectById(this.canvas, this.bgLayer.fabricObject.id).object;

    this.oldWidth = this.backgroundObject.width;
    this.oldHeight = this.backgroundObject.height;

    // 查找背景图层
    this.bgLayer = this.layers.value.find((layer) => layer.isBackground);
  }

  execute() {
    // 调整画布大小
    // this.canvas.setWidth(this.newWidth);
    // this.canvas.setHeight(this.newHeight);

    console.log(
      `调整画布大小：${this.oldWidth}x${this.oldHeight} -> ${this.newWidth}x${this.newHeight}`
    );

    // 如果使用 CanvasManager，通知它画布大小变化
    // if (
    //   this.canvasManager &&
    //   typeof this.canvasManager.updateCanvasSize === "function"
    // ) {
    //   this.canvasManager.updateCanvasSize(this.newWidth, this.newHeight);
    // }

    // 调整背景对象大小
    if (this.bgLayer && this.backgroundObject) {
      // 保持原有的背景颜色，如果没有设置则使用白色
      const currentFill = this.backgroundObject.fill || this.bgLayer.backgroundColor || "#ffffff";

      this.backgroundObject.set({
        width: this.newWidth,
        height: this.newHeight,
        fill: currentFill, // 保持原有颜色
      });

      // 更新图层记录的尺寸
      this.bgLayer.canvasWidth = this.newWidth;
      this.bgLayer.canvasHeight = this.newHeight;
    }

    // 渲染画布
    this.canvas.renderAll();

    return true;
  }

  undo() {
    // 恢复画布大小
    this.canvas.setWidth(this.oldWidth);
    this.canvas.setHeight(this.oldHeight);

    // 如果使用 CanvasManager，通知它画布大小恢复
    // if (
    //   this.canvasManager &&
    //   typeof this.canvasManager.updateCanvasSize === "function"
    // ) {
    //   this.canvasManager.updateCanvasSize(this.oldWidth, this.oldHeight);
    // }

    // 恢复背景对象大小
    if (this.bgLayer && this.backgroundObject) {
      this.backgroundObject.set({
        width: this.oldWidth,
        height: this.oldHeight,
      });

      // 恢复图层记录的尺寸
      this.bgLayer.canvasWidth = this.oldWidth;
      this.bgLayer.canvasHeight = this.oldHeight;
    }

    // 渲染画布
    this.canvas.renderAll();

    return true;
  }

  getInfo() {
    return {
      name: this.name,
      oldWidth: this.oldWidth,
      oldHeight: this.oldHeight,
      newWidth: this.newWidth,
      newHeight: this.newHeight,
    };
  }
}

/**
 * 调整背景大小并等比缩放所有其他元素的命令
 */
export class BackgroundSizeWithScaleCommand extends Command {
  constructor(options) {
    super({
      name: "调整背景大小并缩放元素",
      saveState: true,
    });
    this.canvas = options.canvas;
    this.layers = options.layers;
    this.canvasManager = options.canvasManager;
    this.newWidth = options.newWidth;
    this.newHeight = options.newHeight;
    this.historyManager = options.historyManager;

    // 缩放策略：'uniform' | 'fill' | 'fit' | 'stretch'
    this.scaleStrategy = options.scaleStrategy || "uniform";

    // 记录原尺寸
    this.oldWidth = this.canvas.width;
    this.oldHeight = this.canvas.height;

    // 查找背景图层
    this.bgLayer = this.layers.value.find((layer) => layer.isBackground);

    this.backgroundObject = findObjectById(this.canvas, this.bgLayer.fabricObject.id).object;

    // 计算缩放比例
    const scaleXRatio = this.newWidth / this.oldWidth;
    const scaleYRatio = this.newHeight / this.oldHeight;

    // 根据策略计算缩放比例和偏移
    this._calculateScaleAndOffset(scaleXRatio, scaleYRatio);

    // 存储所有非背景对象的原始状态
    this.objectStates = [];
    this._saveOriginalStates();
  }

  /**
   * 保存所有非背景对象的原始状态
   * @private
   */
  _saveOriginalStates() {
    this.canvas.getObjects().forEach((obj) => {
      if (!obj.isBackground) {
        // 检查对象是否已经有原始状态记录
        if (!obj._originalState) {
          // 第一次记录原始状态
          obj._originalState = {
            left: obj.left,
            top: obj.top,
            scaleX: obj.scaleX || 1,
            scaleY: obj.scaleY || 1,
            width: obj.width,
            height: obj.height,
            // 记录基准画布尺寸
            baseCanvasWidth: this.oldWidth,
            baseCanvasHeight: this.oldHeight,
          };
        }

        this.objectStates.push({
          obj: obj,
          // 使用原始状态而不是当前状态
          left: obj._originalState.left,
          top: obj._originalState.top,
          scaleX: obj._originalState.scaleX,
          scaleY: obj._originalState.scaleY,
          width: obj._originalState.width,
          height: obj._originalState.height,
        });
      }
    });
  }

  /**
   * 根据缩放策略计算缩放比例和偏移量
   * @param {number} scaleXRatio X轴缩放比例
   * @param {number} scaleYRatio Y轴缩放比例
   * @private
   */
  _calculateScaleAndOffset(scaleXRatio, scaleYRatio) {
    switch (this.scaleStrategy) {
      case "uniform":
        // 统一缩放：使用平均值，保持相对比例的同时允许适度的形变
        this.uniformScale = Math.sqrt(scaleXRatio * scaleYRatio);
        this.offsetX = (this.newWidth - this.oldWidth * this.uniformScale) / 2;
        this.offsetY = (this.newHeight - this.oldHeight * this.uniformScale) / 2;
        break;

      case "fit":
        // 适应模式：使用较小值，确保所有内容都在画布内，可能有留白
        this.uniformScale = Math.min(scaleXRatio, scaleYRatio);
        this.offsetX = (this.newWidth - this.oldWidth * this.uniformScale) / 2;
        this.offsetY = (this.newHeight - this.oldHeight * this.uniformScale) / 2;
        break;

      case "fill":
        // 填充模式：使用较大值，填满画布，可能有部分内容被裁切
        this.uniformScale = Math.max(scaleXRatio, scaleYRatio);
        this.offsetX = (this.newWidth - this.oldWidth * this.uniformScale) / 2;
        this.offsetY = (this.newHeight - this.oldHeight * this.uniformScale) / 2;
        break;

      case "stretch":
        // 拉伸模式：不保持宽高比，完全适应新尺寸
        this.scaleX = scaleXRatio;
        this.scaleY = scaleYRatio;
        this.offsetX = 0;
        this.offsetY = 0;
        break;

      default:
        // 默认使用uniform模式
        this.uniformScale = Math.sqrt(scaleXRatio * scaleYRatio);
        this.offsetX = (this.newWidth - this.oldWidth * this.uniformScale) / 2;
        this.offsetY = (this.newHeight - this.oldHeight * this.uniformScale) / 2;
    }
  }

  execute() {
    // 调整画布大小
    this.canvas.setWidth(this.newWidth);
    this.canvas.setHeight(this.newHeight);

    // 如果使用 CanvasManager，通知它画布大小变化
    // if (
    //   this.canvasManager &&
    //   typeof this.canvasManager.updateCanvasSize === "function"
    // ) {
    //   this.canvasManager.updateCanvasSize(this.newWidth, this.newHeight);
    // }

    // 调整背景对象大小和位置
    if (this.bgLayer && this.backgroundObject) {
      // 保持原有的背景颜色，如果没有设置则使用白色
      const currentFill = this.backgroundObject.fill || this.bgLayer.backgroundColor || "#ffffff";

      this.backgroundObject.set({
        width: this.newWidth,
        height: this.newHeight,
        left: this.canvas.width / 2,
        top: this.canvas.height / 2,
        fill: currentFill, // 保持原有颜色
      });

      // 更新图层记录的尺寸
      this.bgLayer.canvasWidth = this.newWidth;
      this.bgLayer.canvasHeight = this.newHeight;
    }

    // 计算基于原始画布的缩放比例
    const baseScaleX =
      this.newWidth / this.objectStates[0]?.obj._originalState?.baseCanvasWidth ||
      this.newWidth / this.oldWidth;
    const baseScaleY =
      this.newHeight / this.objectStates[0]?.obj._originalState?.baseCanvasHeight ||
      this.newHeight / this.oldHeight;

    // 根据策略缩放所有非背景对象
    this.objectStates.forEach((state) => {
      const obj = state.obj;

      if (this.scaleStrategy === "stretch") {
        // 拉伸模式：使用不同的X和Y缩放比例
        obj.set({
          left: state.left * baseScaleX,
          top: state.top * baseScaleY,
          scaleX: state.scaleX * baseScaleX,
          scaleY: state.scaleY * baseScaleY,
        });
      } else {
        // 其他模式：计算基于原始状态的统一缩放比例
        const baseUniformScale = Math.sqrt(baseScaleX * baseScaleY);
        const baseOffsetX =
          (this.newWidth -
            (obj._originalState?.baseCanvasWidth || this.oldWidth) * baseUniformScale) /
          2;
        const baseOffsetY =
          (this.newHeight -
            (obj._originalState?.baseCanvasHeight || this.oldHeight) * baseUniformScale) /
          2;

        obj.set({
          left: state.left * baseUniformScale + baseOffsetX,
          top: state.top * baseUniformScale + baseOffsetY,
          scaleX: state.scaleX * baseUniformScale,
          scaleY: state.scaleY * baseUniformScale,
        });
      }

      obj.setCoords();
    });

    // 渲染画布
    this.canvas.renderAll();

    return true;
  }

  undo() {
    // 恢复画布大小
    this.canvas.setWidth(this.oldWidth);
    this.canvas.setHeight(this.oldHeight);

    // 如果使用 CanvasManager，通知它画布大小恢复
    if (this.canvasManager && typeof this.canvasManager.updateCanvasSize === "function") {
      this.canvasManager.updateCanvasSize(this.oldWidth, this.oldHeight);
    }

    // 恢复背景对象大小和位置
    if (this.bgLayer && this.backgroundObject) {
      this.backgroundObject.set({
        width: this.oldWidth,
        height: this.oldHeight,
        left: this.canvas.width / 2,
        top: this.canvas.height / 2,
      });

      // 恢复图层记录的尺寸
      this.bgLayer.canvasWidth = this.oldWidth;
      this.bgLayer.canvasHeight = this.oldHeight;
    }

    // 恢复所有非背景对象的当前状态（而不是原始状态，因为可能有其他操作）
    this.objectStates.forEach((state) => {
      // 计算恢复到之前画布尺寸时的状态
      const obj = state.obj;
      const originalState = obj._originalState;

      if (originalState) {
        const baseScaleX = this.oldWidth / originalState.baseCanvasWidth;
        const baseScaleY = this.oldHeight / originalState.baseCanvasHeight;
        const baseUniformScale = Math.sqrt(baseScaleX * baseScaleY);
        const baseOffsetX = (this.oldWidth - originalState.baseCanvasWidth * baseUniformScale) / 2;
        const baseOffsetY =
          (this.oldHeight - originalState.baseCanvasHeight * baseUniformScale) / 2;

        obj.set({
          left: originalState.left * baseUniformScale + baseOffsetX,
          top: originalState.top * baseUniformScale + baseOffsetY,
          scaleX: originalState.scaleX * baseUniformScale,
          scaleY: originalState.scaleY * baseUniformScale,
        });
      } else {
        // 降级到原来的逻辑
        obj.set({
          left: state.left,
          top: state.top,
          scaleX: state.scaleX,
          scaleY: state.scaleY,
        });
      }

      obj.setCoords();
    });

    // 渲染画布
    this.canvas.renderAll();

    return true;
  }

  getInfo() {
    const info = {
      name: this.name,
      oldWidth: this.oldWidth,
      oldHeight: this.oldHeight,
      newWidth: this.newWidth,
      newHeight: this.newHeight,
      scaleStrategy: this.scaleStrategy,
      objectCount: this.objectStates.length,
    };

    if (this.scaleStrategy === "stretch") {
      info.scaleX = this.scaleX;
      info.scaleY = this.scaleY;
    } else {
      info.uniformScale = this.uniformScale;
      info.offsetX = this.offsetX;
      info.offsetY = this.offsetY;
    }

    return info;
  }
}
