/**
 * 液化实时更新器
 * 负责高效地更新液化效果到画布上，避免频繁创建fabric对象导致的性能问题
 */
export class LiquifyRealTimeUpdater {
  constructor(canvas, options = {}) {
    this.canvas = canvas;
    this.targetObject = null;
    this.isUpdating = false;
    this.updateQueue = [];
    this.lastUpdateTime = 0;
    this.currImage = options.currImage || { value: null };

    // 配置选项
    this.config = {
      throttleTime: options.throttleTime || 16, // 60fps
      maxQueueSize: options.maxQueueSize || 5,
      useDirectUpdate: options.useDirectUpdate !== false, // 默认启用直接更新
      imageQuality: options.imageQuality || 1.0, // 图像质量 (0.1-1.0)
      skipRenderDuringDrag: options.skipRenderDuringDrag || false, // 拖拽时跳过渲染
    };

    // 临时canvas用于快速渲染
    this.tempCanvas = document.createElement("canvas");
    this.tempCtx = this.tempCanvas.getContext("2d");

    // 高质量canvas用于最终输出
    this.highQualityCanvas = document.createElement("canvas");
    this.highQualityCtx = this.highQualityCanvas.getContext("2d");

    // 当前缓存的图像数据
    this.cachedDataURL = null;
    this.pendingImageData = null;
    this.renderingScheduled = false;

    // 优化Canvas画布渲染设置
    this.canvas.renderOnAddRemove = false; // 禁用自动渲染
    this.canvas.skipOffscreen = true; // 跳过离屏元素渲染
  }

  /**
   * 设置目标对象
   * @param {Object} fabricObject fabric图像对象
   */
  setTargetObject(fabricObject) {
    this.targetObject = fabricObject;
    if (fabricObject && fabricObject._element) {
      // 设置临时canvas尺寸
      this.tempCanvas.width = fabricObject.width;
      this.tempCanvas.height = fabricObject.height;

      // 设置高质量canvas尺寸
      this.highQualityCanvas.width = fabricObject.width;
      this.highQualityCanvas.height = fabricObject.height;

      // 配置高质量渲染上下文
      this.highQualityCtx.imageSmoothingEnabled = true;
      this.highQualityCtx.imageSmoothingQuality = "high";

      // 配置临时canvas上下文（快速渲染）
      this.tempCtx.imageSmoothingEnabled = false; // 快速模式关闭平滑
    }
  }

  /**
   * 实时更新图像数据到画布
   * @param {ImageData} imageData 新的图像数据
   * @param {Boolean} isDrawing 是否正在绘制（拖拽过程中）
   * @returns {Promise} 更新完成的Promise
   */
  async updateImage(imageData, isDrawing = false) {
    if (!this.targetObject || !imageData) {
      return;
    }

    // 节流控制
    const now = Date.now();
    if (now - this.lastUpdateTime < this.config.throttleTime && isDrawing) {
      // 在绘制过程中进行节流，缓存最新的图像数据
      this.pendingImageData = imageData;
      return;
    }

    this.lastUpdateTime = now;

    if (isDrawing && this.config.useDirectUpdate) {
      // 拖拽过程中使用快速更新（降低质量以提高性能）
      this._fastUpdate(imageData);
    } else {
      // 拖拽结束后使用完整更新（最高质量）
      await this._fullUpdate(imageData);
    }
  }

  /**
   * 智能图像质量更新
   * 根据图像尺寸和设备性能动态调整质量
   * @param {ImageData} imageData 图像数据
   * @param {Boolean} isDrawing 是否正在绘制
   * @private
   */
  _getOptimalQuality(imageData, isDrawing) {
    const pixelCount = imageData.width * imageData.height;

    if (isDrawing) {
      // 拖拽时根据图像大小调整质量
      if (pixelCount > 1000000) {
        // 大于1M像素
        return 0.7;
      } else if (pixelCount > 500000) {
        // 大于500K像素
        return 0.8;
      } else {
        return 0.9;
      }
    } else {
      // 拖拽结束时始终使用最高质量
      return 1.0;
    }
  }

  /**
   * 快速更新 - 直接修改现有对象的图像源
   * @param {ImageData} imageData 图像数据
   * @private
   */
  _fastUpdate(imageData) {
    if (!this.targetObject || !this.targetObject._element) {
      return;
    }

    try {
      // 将ImageData渲染到临时canvas（快速模式）
      this.tempCtx.putImageData(imageData, 0, 0);

      // 获取智能质量设置
      const quality = this._getOptimalQuality(imageData, true);

      // 直接更新fabric对象的图像源（使用PNG格式保持质量）
      const targetElement = this.targetObject._element;

      // 方案1: 直接设置src属性（最高性能）
      const dataURL = this.tempCanvas.toDataURL("image/png", quality);

      if (targetElement.src !== dataURL) {
        targetElement.src = dataURL;

        // 关键优化：直接设置fabric对象为脏状态，但不立即渲染
        // this.targetObject.dirty = false; // 标记为不需要立即渲染
        // this.canvas.renderOnAddRemove = true; // 恢复自动渲染
        // this.renderingScheduled = false; // 重置渲染调度状态
        this?.scheduleRender?.(); // 调度一次渲染
        // 使用requestAnimationFrame进行批量渲染优化
        // if (!this.renderingScheduled && !this.config.skipRenderDuringDrag) {
        //   this.renderingScheduled = true;
        //   requestIdleCallback(() => {
        //     this.canvas.renderAll();
        //     this.renderingScheduled = false;
        //   });
        // }
      } else {
        console.warn("=================快速更新液化效果时，图像数据未变化，跳过更新");
      }
    } catch (error) {
      console.error("快速更新液化效果失败:", error);
    }
  }

  getImageData(imageData) {
    // 使用高质量canvas进行最终渲染
    this.highQualityCtx.putImageData(imageData, 0, 0);

    // 生成高质量DataURL（PNG格式，最大质量）
    const dataURL = this.highQualityCanvas.toDataURL("image/png", 1.0);
    return dataURL;
  }

  /**
   * 完整更新 - 创建新的fabric对象
   * @param {ImageData} imageData 图像数据
   * @private
   */
  async _fullUpdate(imageData) {
    return new Promise((resolve, reject) => {
      // 临时禁用画布自动渲染
      const oldRenderOnAddRemove = this.canvas.renderOnAddRemove;
      try {
        // 使用高质量canvas进行最终渲染
        this.highQualityCtx.putImageData(imageData, 0, 0);

        // 生成高质量DataURL（PNG格式，最大质量）
        const dataURL = this.highQualityCanvas.toDataURL("image/png", 1.0);

        // 如果DataURL没有变化，跳过更新
        if (this.cachedDataURL === dataURL) {
          resolve();
          return;
        }

        this.cachedDataURL = dataURL;

        // 创建新的fabric图像对象，保持最高质量
        fabric.Image.fromURL(
          dataURL,
          (newImg) => {
            try {
              if (!this.targetObject) {
                console.warn("目标对象为空，跳过更新");
                resolve();
                return;
              }

              // 保存原对象信息用于智能查找
              const originalObjId = this.targetObject.id;
              const originalObjLayerId = this.targetObject.layerId;

              // 保留原对象的所有变换属性
              const originalObj = this.targetObject;
              newImg.set({
                left: originalObj.left,
                top: originalObj.top,
                scaleX: originalObj.scaleX,
                scaleY: originalObj.scaleY,
                angle: originalObj.angle,
                flipX: originalObj.flipX,
                flipY: originalObj.flipY,
                opacity: originalObj.opacity,
                originX: originalObj.originX,
                originY: originalObj.originY,
                id: originalObj.id,
                name: originalObj.name,
                layerId: originalObj.layerId,
                selected: false,
                evented: originalObj.evented,
              });
              this.canvas.renderOnAddRemove = false;

              // 智能查找和替换canvas上的对象
              const allObjects = this.canvas.getObjects();
              let targetIndex = allObjects.indexOf(originalObj);

              // 如果直接查找失败，尝试通过ID查找
              if (targetIndex === -1 && originalObjId) {
                targetIndex = allObjects.findIndex((obj) => obj.id === originalObjId);
                if (targetIndex !== -1) {
                  console.log(`通过ID找到目标对象: ${originalObjId}`);
                  // 更新目标对象引用
                  this.targetObject = allObjects[targetIndex];
                }
              }

              // 如果通过ID查找仍然失败，尝试通过图层ID查找
              if (targetIndex === -1 && originalObjLayerId) {
                targetIndex = allObjects.findIndex((obj) => obj.layerId === originalObjLayerId);
                if (targetIndex !== -1) {
                  console.log(`通过图层ID找到目标对象: ${originalObjLayerId}`);
                  // 更新目标对象引用
                  this.targetObject = allObjects[targetIndex];
                }
              }

              if (targetIndex !== -1) {
                // 找到目标对象，执行替换
                this.canvas.remove(this.targetObject);
                this.canvas.insertAt(newImg, targetIndex);

                // 恢复自动渲染设置
                this.canvas.renderOnAddRemove = oldRenderOnAddRemove;

                // 更新目标对象引用
                this.targetObject = newImg;

                // 一次性重新渲染画布
                this.canvas.renderAll();

                console.log(`✅ 液化对象更新成功，位置: ${targetIndex}`);
                resolve(newImg);
              } else {
                // 如果在画布中找不到对象，可能对象已被移除或引用已更新
                console.warn("在画布中找不到目标对象，可能已被其他操作移除或替换");

                // 恢复自动渲染设置
                this.canvas.renderOnAddRemove = oldRenderOnAddRemove;

                // 尝试添加新对象到画布末尾
                this.canvas.add(newImg);
                this.targetObject = newImg;
                this.canvas.renderAll();

                console.log("🔄 已将新对象添加到画布末尾");
                resolve(newImg);
              }
            } catch (error) {
              // 恢复自动渲染设置
              this.canvas.renderOnAddRemove = oldRenderOnAddRemove;
              console.error("更新fabric对象时出错:", error);
              reject(error);
            }
          },
          { crossOrigin: "anonymous" }
        ); // 确保跨域支持
      } catch (error) {
        console.error("完整更新过程出错:", error);
        reject(error);
      }
    });
  }

  /**
   * 处理待处理的图像数据
   * 在拖拽结束后调用，处理可能积压的更新
   */
  async processPendingUpdates() {
    if (this.pendingImageData && !this.isUpdating) {
      this.isUpdating = true;
      try {
        await this._fullUpdate(this.pendingImageData);
        this.pendingImageData = null;
      } catch (error) {
        console.error("处理待处理更新失败:", error);
      } finally {
        this.isUpdating = false;
      }
    }
  }

  /**
   * 获取当前目标对象
   * @returns {Object} 当前的fabric对象
   */
  getTargetObject() {
    return this.targetObject;
  }

  /**
   * 强制进行完整更新
   * @param {ImageData} imageData 图像数据
   */
  async forceFullUpdate(imageData) {
    return this._fullUpdate(imageData);
  }

  /**
   * 启用拖拽模式 - 暂停渲染以提高性能
   */
  enableDragMode() {
    this.config.skipRenderDuringDrag = true;
    this.canvas.renderOnAddRemove = false;
    console.log("🚀 启用拖拽优化模式");
  }

  /**
   * 禁用拖拽模式 - 恢复正常渲染
   */
  disableDragMode() {
    this.config.skipRenderDuringDrag = false;
    this.canvas.renderOnAddRemove = true;

    // 执行一次完整渲染
    this.canvas.renderAll();
    console.log("✅ 恢复正常渲染模式");
  }

  /**
   * 设置图像质量
   * @param {Number} quality 质量值 (0.1-1.0)
   */
  setImageQuality(quality) {
    this.config.imageQuality = Math.max(0.1, Math.min(1.0, quality));
  }

  /**
   * 优化的批量渲染方法
   */
  scheduleRender() {
    if (!this.renderingScheduled) {
      this.renderingScheduled = true;
      requestAnimationFrame(() => {
        this.canvas.renderAll();
        this.renderingScheduled = false;
      });
    }
  }

  // /**
  //  * 清理资源
  //  */
  // dispose() {
  //   this.targetObject = null;
  //   this.cachedDataURL = null;
  //   this.pendingImageData = null;
  //   this.updateQueue.length = 0;

  //   // 清理临时canvas
  //   if (this.tempCanvas) {
  //     this.tempCanvas.width = 0;
  //     this.tempCanvas.height = 0;
  //     this.tempCanvas = null;
  //     this.tempCtx = null;
  //   }
  // }

  /**
   * 清理资源
   */
  dispose() {
    // 恢复canvas设置
    this.canvas.renderOnAddRemove = true;

    // 清理缓存
    this.cachedDataURL = null;
    this.pendingImageData = null;

    // 清理canvas
    if (this.tempCanvas) {
      this.tempCanvas.width = 0;
      this.tempCanvas.height = 0;
    }

    if (this.highQualityCanvas) {
      this.highQualityCanvas.width = 0;
      this.highQualityCanvas.height = 0;
    }

    console.log("🧹 液化实时更新器资源已清理");
  }
}
