// 栅格化帮助
import { fabric } from "fabric-with-all";
import { SpecialLayerId } from "./layerHelper";
/**
 * 创建栅格化图像 - 重构版本
 * 采用复制原对象+裁剪路径的方式，保持原始质量和准确位置
 * @returns {Promise<fabric.Image|fabric.Group|string>} 栅格化后的图像对象或DataURL
 * @private
 */
export const createRasterizedImage = async ({
  canvas, // 画布对象   必填
  fabricObjects = [], // 要栅格化的对象列表  -  按顺序  必填
  maskObject = null, // 用于裁剪的对象  -  可选
  clipPath = null, // 裁剪路径对象 - 可选，优先级高于maskObject
  trimWhitespace = true, // 是否裁剪空白区域
  trimPadding = 0, // 裁剪边距
  quality = 1.0, // 图像质量
  format = "png", // 图像格式
  scaleFactor = 1, //  高清倍数  - 默认是画布的高清倍数
  isReturenDataURL = false, // 是否返回DataURL而不是fabric.Image对象
  preserveOriginalQuality = true, // 是否保持原始质量（新增）
  selectionManager = null, // 选区管理器，用于获取羽化值等设置
  restoreOpacityInRedGreen, // 是否在红绿图模式下恢复透明度
	isEnhanceImg, // 是否是增强图片
} = {}) => {
  try {
    console.log(`📊 开始栅格化 ${fabricObjects.length} 个对象`);

    // 确保有对象需要栅格化
    if (fabricObjects.length === 0) {
      console.warn("⚠️ 没有对象需要栅格化，返回空图像");
      return null;
    }

    // 处理裁剪对象，优先使用clipPath
    const clippingObject = clipPath || maskObject;
    // 如果保持原始质量且有裁剪对象，使用新的裁剪方法
    if (preserveOriginalQuality && clippingObject) {
      return await createClippedObjects({
        canvas,
        fabricObjects,
        clippingObject,
        isReturenDataURL,
        selectionManager, // 传递选区管理器
				isEnhanceImg, // 是否是增强图片
      });
    }

    // 如果只是简单复制而不需要裁剪，直接克隆对象
    if (!clippingObject) {
      return await createSimpleClone({
        canvas,
        fabricObjects,
        isReturenDataURL,
        quality,
        format,
      });
    }

    // 兼容原有的离屏渲染方法（作为备选方案）
    return await createLegacyRasterization({
      canvas,
      fabricObjects,
      clippingObject,
      scaleFactor,
      quality,
      format,
      isReturenDataURL,
    });
  } catch (error) {
    console.warn("创建栅格化图像失败:", error);
    throw new Error(`栅格化失败: ${error.message}`);
  }
};

/**
 * 创建带裁剪的对象 - 新方法
 * 直接复制原对象并应用裁剪路径，保持原始质量
 */
const createClippedObjects = async ({
  canvas,
  fabricObjects,
  clippingObject,
  isReturenDataURL,
  selectionManager = null, // 新增选区管理器参数
	isEnhanceImg, // 是否是增强图片
}) => {
  try {
    console.log("🎯 使用新的图像遮罩裁剪方法创建对象");

    // 使用优化后的边界计算，确保包含描边区域
    const optimizedBounds = calculateOptimizedBounds(
      clippingObject,
      fabricObjects
    );
    console.log("📐 优化后的选区边界框:", optimizedBounds);

    // 获取羽化值
    let featherAmount = 0;
    if (
      selectionManager &&
      typeof selectionManager.getFeatherAmount === "function"
    ) {
      featherAmount = selectionManager.getFeatherAmount();
      console.log(`🌟 应用羽化效果: ${featherAmount}px`);
    }

    // 方法1：如果只需要返回DataURL，使用画布裁剪方法
    if (isReturenDataURL) {
      return await createClippedDataURLByCanvas({
        canvas,
        fabricObjects,
        clippingObject,
        selectionBounds: optimizedBounds, // 使用优化后的边界框
        featherAmount,
				isEnhanceImg, // 是否是增强图片
      });
    }

    // 方法2：如果需要返回fabric对象，先生成DataURL再转换为fabric对象
    const clippedDataURL = await createClippedDataURLByCanvas({
      canvas,
      fabricObjects,
      clippingObject,
      selectionBounds: optimizedBounds, // 使用优化后的边界框
      featherAmount,
			isEnhanceImg, // 是否是增强图片
    });

    // 将DataURL转换为fabric.Image对象
    const fabricImage = await createFabricImageFromDataURL(clippedDataURL);

    // 使用fabric原生方法恢复到选区的原始大小和位置
    fabricImage.scaleToWidth(optimizedBounds.width);
    fabricImage.scaleToHeight(optimizedBounds.height);

    // 设置到选区的原始位置（中心点）
    fabricImage.set({
      left: optimizedBounds.left + optimizedBounds.width / 2,
      top: optimizedBounds.top + optimizedBounds.height / 2,
      originX: "center",
      originY: "center",
      selectable: true,
      evented: true,
      // hasControls: true,
      // hasBorders: true,
      custom: {
        type: "clipped",
        clippedAt: new Date().toISOString(),
        hasClipping: true,
        preservedQuality: true,
        originalBounds: optimizedBounds, // 保存优化后的边界框
        restoredToOriginalSize: true,
        usedImageMask: true, // 标记使用了图像遮罩
        featherAmount: featherAmount,
        boundaryOptimized: true, // 标记使用了边界优化
      },
    });

    // 更新坐标
    fabricImage.setCoords();

    console.log("✅ 返回裁剪后的fabric对象，已恢复到优化后的原始大小和位置");
    return fabricImage;
  } catch (error) {
    console.warn("创建裁剪对象失败:", error);
    throw error;
  }
};

/**
 * 通过画布裁剪生成DataURL
 * 裁剪掉选区以外的内容，保持和选区大小一致
 */
const createClippedDataURLByCanvas = async ({
  canvas,
  fabricObjects,
  clippingObject,
  selectionBounds,
  featherAmount = 0,
  isEnhanceImg = false, // 是否是增强图片
}) => {
  try {
    console.log("🖼️ 使用图像遮罩裁剪方法生成DataURL");

    // 使用优化后的边界计算，确保包含描边区域
    // const optimizedBounds = calculateOptimizedBounds(
    //   clippingObject,
    //   fabricObjects
    // );
	const optimizedBounds = {
		left: clippingObject.left - clippingObject.width / 2,
		top: clippingObject.top - clippingObject.height / 2,
		width: clippingObject.width,
		height: clippingObject.height,
	}

    // 使用高分辨率以保证质量
    const pixelRatio = window.devicePixelRatio || 1;
		const qualityMultiplier = !!isEnhanceImg ? Math.max(2, pixelRatio) : 1;
		
		console.log("使用高分辨率以保证质量:" + isEnhanceImg, optimizedBounds);

    const canvasWidth = Math.ceil(optimizedBounds.width * qualityMultiplier);
    const canvasHeight = Math.ceil(optimizedBounds.height * qualityMultiplier);

    console.log(
      `📏 优化后画布尺寸: ${canvasWidth}x${canvasHeight} (质量倍数: ${qualityMultiplier})`
    );
    console.log("🎯 边界框对比:", {
      original: selectionBounds,
      optimized: optimizedBounds,
    });

    // 步骤1: 先将路径转换为遮罩图像（支持羽化）
    const maskImageDataURL =
      featherAmount > 0
        ? await createAdvancedMaskImage({
            clippingObject,
            selectionBounds: optimizedBounds, // 使用优化后的边界框
            qualityMultiplier,
            featherAmount,
          })
        : await createMaskImageFromPath({
            clippingObject,
            selectionBounds: optimizedBounds, // 使用优化后的边界框
            qualityMultiplier,
          });

    // 步骤2: 渲染原始内容
    const contentImageDataURL = await renderContentToImage({
      fabricObjects,
      selectionBounds: optimizedBounds, // 使用优化后的边界框
      qualityMultiplier,
    });

    // 步骤3: 使用遮罩合成最终结果
    const clippedDataURL = await applyImageMask({
      contentImageDataURL,
      maskImageDataURL,
      canvasWidth,
      canvasHeight,
    });

    console.log("✅ 图像遮罩裁剪完成，生成DataURL");
    return clippedDataURL;
  } catch (error) {
    console.error("图像遮罩裁剪失败:", error);
    throw error;
  }
};

/**
 * 创建简单克隆对象
 * 当不需要裁剪时，直接克隆原对象
 */
const createSimpleClone = async ({
  canvas,
  fabricObjects,
  isReturenDataURL,
  quality,
  format,
}) => {
  try {
    console.log("📋 创建简单克隆对象");

    const clonedObjects = [];

    // 克隆所有对象
    for (const obj of fabricObjects) {
      const clonedObj = await cloneObjectAsync(obj);

      clonedObj.set({
        selectable: true,
        evented: true,
        hasControls: true,
        hasBorders: true,
        custom: {
          ...clonedObj.custom,
          type: "cloned",
          clonedAt: new Date().toISOString(),
          preservedQuality: true,
        },
      });

      clonedObjects.push(clonedObj);
    }

    // 如果需要返回DataURL，需要渲染
    if (isReturenDataURL) {
      return await renderObjectsToDataURL(clonedObjects, quality, format);
    }

    // 如果只有一个对象，直接返回
    if (clonedObjects.length === 1) {
      return clonedObjects[0];
    }

    // 创建组合
    const group = new fabric.Group(clonedObjects, {
      selectable: true,
      evented: true,
      hasControls: true,
      hasBorders: true,
      custom: {
        type: "clonedGroup",
        clonedAt: new Date().toISOString(),
        objectCount: clonedObjects.length,
        preservedQuality: true,
      },
    });

    return group;
  } catch (error) {
    console.error("创建简单克隆失败:", error);
    throw error;
  }
};

/**
 * 将对象渲染为DataURL
 */
const renderObjectsToDataURL = async (objects, quality, format) => {
  try {
    // 计算对象边界框
    const bounds = calculateBounds(objects);
    if (!bounds.absoluteBounds) {
      throw new Error("无法计算对象边界框");
    }

    // 创建临时画布用于渲染
    const tempCanvas = new fabric.StaticCanvas();
    const { absoluteBounds } = bounds;

    tempCanvas.setDimensions({
      width: Math.ceil(absoluteBounds.width),
      height: Math.ceil(absoluteBounds.height),
    });

    // 调整对象位置并添加到临时画布
    for (const obj of objects) {
      const tempObj = await cloneObjectAsync(obj);
      tempObj.set({
        left: tempObj.left - absoluteBounds.left,
        top: tempObj.top - absoluteBounds.top,
      });
      tempCanvas.add(tempObj);
    }

    // 渲染并获取DataURL
    tempCanvas.renderAll();
    const dataURL = tempCanvas.toDataURL({
      format,
      quality,
    });

    // 清理临时画布
    tempCanvas.dispose();

    return dataURL;
  } catch (error) {
    console.error("渲染对象为DataURL失败:", error);
    throw error;
  }
};

/**
 * 渲染裁剪后的对象为DataURL
 * 专门处理带有裁剪路径的对象渲染（备用方法）
 */
const renderClippedObjectsToDataURL = async (clippedObjects) => {
  try {
    console.log("🖼️ 渲染裁剪对象为DataURL");

    // 计算所有裁剪对象的总边界框
    let totalBounds = null;

    for (const obj of clippedObjects) {
      const objBounds = obj.getBoundingRect(true, true);

      if (!totalBounds) {
        totalBounds = { ...objBounds };
      } else {
        const right = Math.max(
          totalBounds.left + totalBounds.width,
          objBounds.left + objBounds.width
        );
        const bottom = Math.max(
          totalBounds.top + totalBounds.height,
          objBounds.top + objBounds.height
        );

        totalBounds.left = Math.min(totalBounds.left, objBounds.left);
        totalBounds.top = Math.min(totalBounds.top, objBounds.top);
        totalBounds.width = right - totalBounds.left;
        totalBounds.height = bottom - totalBounds.top;
      }
    }

    if (!totalBounds) {
      throw new Error("无法计算对象边界框");
    }

    // 创建临时画布，使用高分辨率
    const tempCanvas = new fabric.StaticCanvas();
    const pixelRatio = window.devicePixelRatio || 1;
    const scaleFactor = Math.max(2, pixelRatio);

    const canvasWidth = Math.ceil(totalBounds.width * scaleFactor);
    const canvasHeight = Math.ceil(totalBounds.height * scaleFactor);

    tempCanvas.setDimensions({
      width: canvasWidth,
      height: canvasHeight,
    });

    // 调整对象位置并添加到临时画布
    for (const obj of clippedObjects) {
      const tempObj = await cloneObjectAsync(obj);

      // 调整位置到画布坐标系
      tempObj.set({
        left: (tempObj.left - totalBounds.left) * scaleFactor,
        top: (tempObj.top - totalBounds.top) * scaleFactor,
        scaleX: (tempObj.scaleX || 1) * scaleFactor,
        scaleY: (tempObj.scaleY || 1) * scaleFactor,
      });

      // 如果有裁剪路径，也需要调整裁剪路径
      if (tempObj.clipPath) {
        tempObj.clipPath.set({
          scaleX: (tempObj.clipPath.scaleX || 1) * scaleFactor,
          scaleY: (tempObj.clipPath.scaleY || 1) * scaleFactor,
        });
      }

      tempCanvas.add(tempObj);
    }

    // 渲染画布
    tempCanvas.renderAll();

    // 获取DataURL
    const dataURL = tempCanvas.toDataURL({
      format: "png",
      quality: 1.0,
      multiplier: 1, // 已经通过尺寸处理了缩放
    });

    // 清理临时画布
    tempCanvas.dispose();

    console.log("✅ 裁剪对象渲染完成");
    return dataURL;
  } catch (error) {
    console.error("渲染裁剪对象失败:", error);
    throw error;
  }
};

/**
 * 兼容的离屏渲染方法（原有逻辑，作为备选）
 */
const createLegacyRasterization = async ({
  canvas,
  fabricObjects,
  clippingObject,
  scaleFactor,
  quality,
  format,
  isReturenDataURL,
	isCropByBg, // 是否根据背景裁剪
	isEnhanceImg, // 是否是增强图片
}) => {
  console.log("⚠️ 使用兼容的离屏渲染方法");

  // 这里保留原有的离屏渲染逻辑作为备选方案
  const currentZoom = canvas.getZoom?.() || 1;
  scaleFactor = Math.max(
    scaleFactor || canvas?.getRetinaScaling?.(),
    currentZoom
  );
  scaleFactor = Math.min(scaleFactor, 3);

  const { absoluteBounds, relativeBounds } = calculateBounds(fabricObjects);

  return await createOffscreenRasterization({
    canvas,
    objects: fabricObjects,
    absoluteBounds,
    relativeBounds,
    scaleFactor,
    clippingObject,
    trimWhitespace: true,
    trimPadding: 1,
    quality,
    format,
    currentZoom,
    isReturenDataURL,
		isCropByBg, // 是否根据背景裁剪
		isEnhanceImg, // 是否是增强图片
  });
};

/**
 * 计算对象的绝对边界框和相对边界框
 * @param {Array} fabricObjects fabric对象数组
 * @returns {Object} 包含绝对边界框和相对边界框的对象
 */
const calculateBounds = (fabricObjects) => {
  if (fabricObjects.length === 0) {
    console.warn("⚠️ 没有对象，无法计算边界框");
    return { absoluteBounds: null, relativeBounds: null };
  }

  let absoluteBounds = null;
  let relativeBounds = null;

  fabricObjects.forEach((obj, index) => {
    // 获取相对边界框（考虑画布缩放和平移）
    const relativeBound = obj.getBoundingRect();
    // 获取绝对边界框（原始大小和位置）
    const absoluteBound = obj.getBoundingRect(true, true);

    console.log(`对象 ${obj.id || index} 边界框比较:`, {
      relative: relativeBound,
      absolute: absoluteBound,
      scaleX: obj.scaleX,
      scaleY: obj.scaleY,
    });

    // 计算绝对边界框的累积范围
    if (!absoluteBounds) {
      absoluteBounds = { ...absoluteBound };
    } else {
      const right = Math.max(
        absoluteBounds.left + absoluteBounds.width,
        absoluteBound.left + absoluteBound.width
      );
      const bottom = Math.max(
        absoluteBounds.top + absoluteBounds.height,
        absoluteBound.top + absoluteBound.height
      );

      absoluteBounds.left = Math.min(absoluteBounds.left, absoluteBound.left);
      absoluteBounds.top = Math.min(absoluteBounds.top, absoluteBound.top);
      absoluteBounds.width = right - absoluteBounds.left;
      absoluteBounds.height = bottom - absoluteBounds.top;
    }

    // 计算相对边界框的累积范围
    if (!relativeBounds) {
      relativeBounds = { ...relativeBound };
    } else {
      const right = Math.max(
        relativeBounds.left + relativeBounds.width,
        relativeBound.left + relativeBound.width
      );
      const bottom = Math.max(
        relativeBounds.top + relativeBounds.height,
        relativeBound.top + relativeBound.height
      );

      relativeBounds.left = Math.min(relativeBounds.left, relativeBound.left);
      relativeBounds.top = Math.min(relativeBounds.top, relativeBound.top);
      relativeBounds.width = right - relativeBounds.left;
      relativeBounds.height = bottom - relativeBounds.top;
    }
  });

  return { absoluteBounds, relativeBounds };
};

/**
 * 创建离屏栅格化渲染
 * @param {Object} options 渲染选项
 * @returns {Promise<fabric.Image>} 栅格化后的图像对象
 */
const createOffscreenRasterization = async ({
  canvas,
  objects,
  absoluteBounds,
  relativeBounds,
  scaleFactor,
  clippingObject,
  trimWhitespace,
  trimPadding,
  quality,
  format,
  currentZoom,
  isReturenDataURL,
	isCropByBg, // 是否根据背景裁剪
	isEnhanceImg, // 是否是增强图片
}) => {
  try {
    // 创建离屏画布，使用绝对尺寸以保证高质量
    const offscreenCanvas = new fabric.StaticCanvas();

    // 如果有裁剪对象，使用裁剪对象的边界框
    let renderBounds = absoluteBounds;
    if (clippingObject) {
      const clippingBounds = clippingObject.getBoundingRect(true, true);
      console.log("🎯 使用裁剪对象边界框:", clippingBounds);
      renderBounds = clippingBounds;
    }

    // 设置离屏画布尺寸，并应用高清倍数
    const canvasWidth = Math.ceil(renderBounds.width);
    const canvasHeight = Math.ceil(renderBounds.height);

    offscreenCanvas.setDimensions({
      width: canvasWidth,
      height: canvasHeight,
    });

    console.log(
      `🎨 离屏画布尺寸: ${canvasWidth}x${canvasHeight}, 缩放: ${scaleFactor}`
    );

    // 克隆对象到离屏画布
    const clonedObjects = [];
    for (const obj of objects) {
      const clonedObj = await cloneObjectAsync(obj);

      // 调整对象位置，相对于渲染边界框的左上角
      clonedObj.set({
        left: clonedObj.left - renderBounds.left,
        top: clonedObj.top - renderBounds.top,
      });

      // 如果有裁剪对象，为每个对象设置裁剪路径
      if (clippingObject) {
        const clippingPath = await cloneObjectAsync(clippingObject);
        clippingPath.set({
          left: clippingPath.left - renderBounds.left,
          top: clippingPath.top - renderBounds.top,
          fill: "",
          stroke: "",
          absolutePositioned: true,
        });
        clonedObj.set({
          clipPath: clippingPath,
        });
      }

      clonedObjects.push(clonedObj);
      offscreenCanvas.add(clonedObj);
    }

    // 渲染离屏画布
    offscreenCanvas.renderAll();

    // 生成图像数据
    const dataURL = offscreenCanvas.toDataURL({
      format,
      quality,
      multiplier: 1, // 已经通过画布尺寸处理了高清倍数
    });

    if (isReturenDataURL) {
      return dataURL; // 如果需要返回DataURL
    }

    // 清理离屏画布
    offscreenCanvas.dispose();

    // 创建fabric.Image对象
    const fabricImage = await createFabricImageFromDataURL(dataURL);

    // 设置图像位置为裁剪区域的位置
    fabricImage.set({
      left: renderBounds.left + renderBounds.width / 2,
      top: renderBounds.top + renderBounds.height / 2,
      originX: "center",
      originY: "center",
    });

    return fabricImage;
  } catch (error) {
    console.error("离屏栅格化失败:", error);
    throw error;
  }
};

/**
 * 异步克隆fabric对象
 * @param {fabric.Object} obj 要克隆的对象
 * @returns {Promise<fabric.Object>} 克隆的对象
 */
const cloneObjectAsync = (obj) => {
  return new Promise((resolve, reject) => {
    obj.clone((cloned) => {
      if (cloned) {
		cloned.set({
			scaleX: obj.scaleX,
			scaleY: obj.scaleY,
			top: obj.top,
			left: obj.left,
			width: obj.width,
			height: obj.height,
			zoomX: obj.zoomX,
			zoomY: obj.zoomY,
		})
        resolve(cloned);
      } else {
        reject(new Error("对象克隆失败"));
      }
    });
  });
};

/**
 * 从DataURL创建fabric.Image对象
 * @param {string} dataURL 图像数据URL
 * @returns {Promise<fabric.Image>} fabric图像对象
 */
const createFabricImageFromDataURL = (dataURL) => {
  return new Promise((resolve, reject) => {
    fabric.Image.fromURL(dataURL, (img) => {
      if (img) {
        resolve(img);
      } else {
        reject(new Error("无法从DataURL创建图像"));
      }
    });
  });
};

/**
 * 计算栅格化图像在当前画布上的正确变换
 * @param {Object} params 计算参数
 * @returns {Object} 变换属性对象
 */
const calculateImageTransform = ({
  absoluteBounds,
  relativeBounds,
  currentZoom,
  scaleFactor,
  imageWidth,
  imageHeight,
}) => {
  // 计算缩放比例：相对尺寸 / 绝对尺寸
  const scaleX = relativeBounds.width / absoluteBounds.width;
  const scaleY = relativeBounds.height / absoluteBounds.height;

  // 由于我们生成的图像是基于绝对尺寸的高清版本，需要考虑scaleFactor
  const finalScaleX = scaleX / scaleFactor;
  const finalScaleY = scaleY / scaleFactor;

  return {
    left: relativeBounds.left + relativeBounds.width / 2, // 设置为中心点
    top: relativeBounds.top + relativeBounds.height / 2, // 设置为中心点
    // scaleX: finalScaleX,
    // scaleY: finalScaleY,
    originX: "center",
    originY: "center",
  };
};

/**
 * 应用遮罩到画布（已弃用，使用clipPath方式）
 * @param {fabric.Canvas} canvas 目标画布
 * @param {fabric.Object} maskObject 遮罩对象
 * @param {Object} bounds 边界框
 */
const applyMaskToCanvas = async (canvas, maskObject, bounds) => {
  // 此方法已被clipPath方式替代
  console.log("⚠️ applyMaskToCanvas已被clipPath方式替代");
};

export const getObjectsBounds = (fabricObjects) => {
  const { absoluteBounds } = calculateBounds(fabricObjects);
  return absoluteBounds;
};

/**
 * 将路径对象转换为遮罩图像
 * @param {Object} clippingObject 裁剪路径对象
 * @param {Object} selectionBounds 选区边界框
 * @param {Number} qualityMultiplier 质量倍数
 * @returns {Promise<String>} 遮罩图像的DataURL
 */
const createMaskImageFromPath = async ({
  clippingObject,
  selectionBounds,
  qualityMultiplier,
}) => {
  try {
    console.log("🎭 创建路径遮罩图像");

    // 创建专门用于渲染遮罩的画布
    const maskCanvas = new fabric.StaticCanvas();

    const canvasWidth = Math.ceil(selectionBounds.width * qualityMultiplier);
    const canvasHeight = Math.ceil(selectionBounds.height * qualityMultiplier);

    maskCanvas.setDimensions({
      width: canvasWidth,
      height: canvasHeight,
    });

    // 克隆路径对象并处理描边转填充
    const maskPath = await createSolidMaskPath(
      clippingObject,
      selectionBounds,
      qualityMultiplier
    );

    // 添加路径到遮罩画布
    maskCanvas.add(maskPath);
    maskCanvas.renderAll();

    // 生成遮罩图像
    const maskDataURL = maskCanvas.toDataURL({
      format: "png",
      quality: 1.0,
      multiplier: 1,
    });

    // 清理遮罩画布
    maskCanvas.dispose();

    console.log("✅ 遮罩图像创建完成");
    return maskDataURL;
  } catch (error) {
    console.error("创建遮罩图像失败:", error);
    throw error;
  }
};

/**
 * 渲染内容对象为图像
 * @param {Array} fabricObjects 要渲染的对象数组
 * @param {Object} selectionBounds 选区边界框
 * @param {Number} qualityMultiplier 质量倍数
 * @returns {Promise<String>} 内容图像的DataURL
 */
const renderContentToImage = async ({
  fabricObjects,
  selectionBounds,
  qualityMultiplier,
}) => {
  try {
    console.log("🖼️ 渲染内容图像");

    // 创建内容渲染画布
    const contentCanvas = new fabric.StaticCanvas();

    const canvasWidth = Math.ceil(selectionBounds.width * qualityMultiplier);
    const canvasHeight = Math.ceil(selectionBounds.height * qualityMultiplier);

    contentCanvas.setDimensions({
      width: canvasWidth,
      height: canvasHeight,
    });

    // 克隆并添加所有需要渲染的对象
    for (let obj of fabricObjects) {
      let clonedObj = await cloneObjectAsync(obj);
      // 调整对象位置：将选区左上角作为新的原点(0,0)
      clonedObj.set({
        left: (clonedObj.left - selectionBounds.left) * qualityMultiplier,
        top: (clonedObj.top - selectionBounds.top) * qualityMultiplier,
        scaleX: (clonedObj.scaleX || 1) * qualityMultiplier,
        scaleY: (clonedObj.scaleY || 1) * qualityMultiplier,
        selectable: false,
        evented: false,
      });

      // 如果有裁剪路径，也需要调整裁剪路径
      if (clonedObj.clipPath && obj.id !== SpecialLayerId.COLOR) {
        clonedObj.clipPath.set({
          left: (clonedObj.clipPath.left - selectionBounds.left) * qualityMultiplier,
          top: (clonedObj.clipPath.top - selectionBounds.top) * qualityMultiplier,
          scaleX: (clonedObj.clipPath.scaleX || 1) * qualityMultiplier,
          scaleY: (clonedObj.clipPath.scaleY || 1) * qualityMultiplier,
        });
        clonedObj.clipPath.setCoords(); // 更新裁剪路径坐标
      }
	//   if(obj.globalCompositeOperation === "multiply"){
	// 	clonedObj.clipPath = null;
	//   }
	console.log("==========", obj.id, obj.layerName);
      contentCanvas.add(clonedObj);
    }

    // 渲染内容画布
    contentCanvas.renderAll();

    // 生成内容图像
    const contentDataURL = contentCanvas.toDataURL({
      format: "png",
      quality: 1.0,
      multiplier: 1,
    });

    // 清理内容画布
    contentCanvas.dispose();

    console.log("✅ 内容图像渲染完成");
    return contentDataURL;
  } catch (error) {
    console.error("渲染内容图像失败:", error);
    throw error;
  }
};

/**
 * 使用遮罩图像对内容图像进行裁剪
 * @param {String} contentImageDataURL 内容图像DataURL
 * @param {String} maskImageDataURL 遮罩图像DataURL
 * @param {Number} canvasWidth 画布宽度
 * @param {Number} canvasHeight 画布高度
 * @returns {Promise<String>} 裁剪后的图像DataURL
 */
const applyImageMask = async ({
  contentImageDataURL,
  maskImageDataURL,
  canvasWidth,
  canvasHeight,
}) => {
  try {
    console.log("🎯 应用图像遮罩");

    return new Promise((resolve, reject) => {
      // 创建用于合成的Canvas元素
      const compositeCanvas = document.createElement("canvas");
      const ctx = compositeCanvas.getContext("2d");

      compositeCanvas.width = canvasWidth;
      compositeCanvas.height = canvasHeight;

      // 加载内容图像
      const contentImg = new Image();
      contentImg.onload = () => {
        // 加载遮罩图像
        const maskImg = new Image();
        maskImg.onload = () => {
          try {
            // 先绘制内容图像
            ctx.drawImage(contentImg, 0, 0, canvasWidth, canvasHeight);

            // 设置合成模式为遮罩模式
            ctx.globalCompositeOperation = "destination-in";

            // 绘制遮罩图像
            ctx.drawImage(maskImg, 0, 0, canvasWidth, canvasHeight);

            // 重置合成模式
            ctx.globalCompositeOperation = "source-over";

            // 获取最终结果
            const resultDataURL = compositeCanvas.toDataURL("image/png", 1.0);

            console.log("✅ 图像遮罩应用完成");
            resolve(resultDataURL);
          } catch (error) {
            console.error("合成图像失败:", error);
            reject(error);
          }
        };

        maskImg.onerror = () => {
          reject(new Error("加载遮罩图像失败"));
        };

        maskImg.src = maskImageDataURL;
      };

      contentImg.onerror = () => {
        reject(new Error("加载内容图像失败"));
      };

      contentImg.src = contentImageDataURL;
    });
  } catch (error) {
    console.error("应用图像遮罩失败:", error);
    throw error;
  }
};

/**
 * 创建带羽化效果的遮罩图像（高级版本）
 * @param {Object} clippingObject 裁剪路径对象
 * @param {Object} selectionBounds 选区边界框
 * @param {Number} qualityMultiplier 质量倍数
 * @param {Number} featherAmount 羽化值
 * @returns {Promise<String>} 遮罩图像的DataURL
 */
const createAdvancedMaskImage = async ({
  clippingObject,
  selectionBounds,
  qualityMultiplier,
  featherAmount = 0,
}) => {
  try {
    console.log(`🎭 创建高级遮罩图像 (羽化: ${featherAmount})`);

    // 创建专门用于渲染遮罩的画布
    const maskCanvas = new fabric.StaticCanvas();

    const canvasWidth = Math.ceil(selectionBounds.width * qualityMultiplier);
    const canvasHeight = Math.ceil(selectionBounds.height * qualityMultiplier);

    maskCanvas.setDimensions({
      width: canvasWidth,
      height: canvasHeight,
    });

    // 克隆路径对象并处理描边转填充
    const maskPath = await createSolidMaskPath(
      clippingObject,
      selectionBounds,
      qualityMultiplier
    );

    // 如果有羽化值，添加模糊效果
    if (featherAmount > 0) {
      const adjustedFeather = featherAmount * qualityMultiplier;
      maskPath.shadow = new fabric.Shadow({
        color: "#ffffff",
        blur: adjustedFeather,
        offsetX: 0,
        offsetY: 0,
      });
    }

    // 添加路径到遮罩画布
    maskCanvas.add(maskPath);
    maskCanvas.renderAll();

    // 如果有羽化，需要进行后处理
    if (featherAmount > 0) {
      return await applyCanvasBlur(
        maskCanvas,
        featherAmount * qualityMultiplier
      );
    }

    // 生成遮罩图像
    const maskDataURL = maskCanvas.toDataURL({
      format: "png",
      quality: 1.0,
      multiplier: 1,
    });

    // 清理遮罩画布
    maskCanvas.dispose();

    console.log("✅ 高级遮罩图像创建完成");
    return maskDataURL;
  } catch (error) {
    console.error("创建高级遮罩图像失败:", error);
    throw error;
  }
};

/**
 * 对画布应用模糊效果
 * @param {fabric.StaticCanvas} canvas 要处理的画布
 * @param {Number} blurAmount 模糊值
 * @returns {Promise<String>} 处理后的DataURL
 */
const applyCanvasBlur = async (canvas, blurAmount) => {
  try {
    // 获取原始图像数据
    const originalDataURL = canvas.toDataURL({
      format: "png",
      quality: 1.0,
      multiplier: 1,
    });

    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => {
        // 创建一个新的Canvas进行模糊处理
        const blurCanvas = document.createElement("canvas");
        const ctx = blurCanvas.getContext("2d");

        blurCanvas.width = canvas.width;
        blurCanvas.height = canvas.height;

        // 应用CSS滤镜模糊
        ctx.filter = `blur(${Math.max(1, blurAmount / 2)}px)`;
        ctx.drawImage(img, 0, 0);

        // 重置滤镜
        ctx.filter = "none";

        const blurredDataURL = blurCanvas.toDataURL("image/png", 1.0);
        resolve(blurredDataURL);
      };

      img.onerror = () => {
        reject(new Error("处理模糊效果失败"));
      };

      img.src = originalDataURL;
    });
  } catch (error) {
    console.error("应用画布模糊失败:", error);
    throw error;
  }
};

/**
 * 创建实体遮罩路径（将描边转换为填充）
 * @param {Object} clippingObject 原始裁剪对象
 * @param {Object} selectionBounds 选区边界框
 * @param {Number} qualityMultiplier 质量倍数
 * @returns {Promise<fabric.Object>} 处理后的遮罩路径对象
 */
const createSolidMaskPath = async (
  clippingObject,
  selectionBounds,
  qualityMultiplier
) => {
  try {
    console.log("🔧 创建实体遮罩路径，处理描边转填充");

    // 克隆原始对象
    const maskPath = await cloneObjectAsync(clippingObject);

    // 检查是否有描边需要处理
    const hasStroke = maskPath.stroke && maskPath.strokeWidth > 0;

    if (hasStroke) {
      console.log(
        `📏 检测到描边: ${maskPath.stroke}, 宽度: ${maskPath.strokeWidth}`
      );

      // 对于有描边的路径，我们需要更精确的处理
      const strokeWidth = maskPath.strokeWidth;

      // 方法1: 如果是简单的几何形状（矩形、圆形等），可以通过调整尺寸来补偿描边
      if (
        maskPath.type === "rect" ||
        maskPath.type === "circle" ||
        maskPath.type === "ellipse"
      ) {
        // 对于矩形和椭圆，增加宽高来包含描边
        const strokeOffset = strokeWidth;

        maskPath.set({
          left:
            (maskPath.left - selectionBounds.left - strokeOffset / 2) *
            qualityMultiplier,
          top:
            (maskPath.top - selectionBounds.top - strokeOffset / 2) *
            qualityMultiplier,
          scaleX: (maskPath.scaleX || 1) * qualityMultiplier,
          scaleY: (maskPath.scaleY || 1) * qualityMultiplier,
          width: (maskPath.width || 0) + strokeOffset,
          height: (maskPath.height || 0) + strokeOffset,
          fill: "#ffffff",
          stroke: "",
          strokeWidth: 0,
          selectable: false,
          evented: false,
        });
      } else {
        // 对于复杂路径，使用缩放方式来近似包含描边区域
        const pathBounds = maskPath.getBoundingRect(true, true);
        const minDimension = Math.min(pathBounds.width, pathBounds.height);
        const expandRatio = 1 + (strokeWidth * 2) / minDimension;
        const strokeOffset = strokeWidth / 2;

        maskPath.set({
          left:
            (maskPath.left - selectionBounds.left - strokeOffset) *
            qualityMultiplier,
          top:
            (maskPath.top - selectionBounds.top - strokeOffset) *
            qualityMultiplier,
          scaleX: (maskPath.scaleX || 1) * qualityMultiplier * expandRatio,
          scaleY: (maskPath.scaleY || 1) * qualityMultiplier * expandRatio,
          fill: "#ffffff",
          stroke: "",
          strokeWidth: 0,
          selectable: false,
          evented: false,
        });
      }

      console.log(`✅ 描边已转换为填充，类型: ${maskPath.type}`);
    } else {
      // 没有描边，直接处理位置和缩放
      maskPath.set({
        left: (maskPath.left - selectionBounds.left) * qualityMultiplier,
        top: (maskPath.top - selectionBounds.top) * qualityMultiplier,
        scaleX: (maskPath.scaleX || 1) * qualityMultiplier,
        scaleY: (maskPath.scaleY || 1) * qualityMultiplier,
        fill: "#ffffff", // 白色表示可见区域
        stroke: "", // 确保没有描边
        strokeWidth: 0,
        selectable: false,
        evented: false,
      });
    }

    // 确保对象在画布中心正确对齐
    maskPath.setCoords();

    return maskPath;
  } catch (error) {
    console.error("创建实体遮罩路径失败:", error);
    throw error;
  }
};

/**
 * 优化边界计算，确保遮罩和内容对齐
 * @param {Object} clippingObject 裁剪对象
 * @param {Array} fabricObjects 内容对象数组
 * @returns {Object} 优化后的边界框信息
 */
const calculateOptimizedBounds = (clippingObject, fabricObjects) => {
  try {
    console.log("📐 计算优化后的边界框");

    // 获取裁剪对象的边界框（包含描边）
    const clippingBounds = clippingObject.getBoundingRect(true, true);

    // 如果有描边，需要调整边界框
    if (clippingObject.stroke && clippingObject.strokeWidth > 0) {
      const strokeWidth = clippingObject.strokeWidth;
      const halfStroke = strokeWidth / 2;

      // 扩展边界框以包含完整的描边区域
      clippingBounds.left -= halfStroke;
      clippingBounds.top -= halfStroke;
      clippingBounds.width += strokeWidth;
      clippingBounds.height += strokeWidth;

      console.log(`🖊️ 调整描边边界框，描边宽度: ${strokeWidth}`);
    }

    // 计算内容对象的边界框
    const contentBounds = calculateBounds(fabricObjects);

    // 使用裁剪边界框作为最终的选区边界框
    const optimizedBounds = {
      ...clippingBounds,
      // 确保边界框不为负数或零
      width: Math.max(1, clippingBounds.width),
      height: Math.max(1, clippingBounds.height),
    };

    console.log("✅ 边界框优化完成", {
      original: clippingObject.getBoundingRect(true, true),
      optimized: optimizedBounds,
      hasStroke: !!(clippingObject.stroke && clippingObject.strokeWidth > 0),
    });

    return optimizedBounds;
  } catch (error) {
    console.warn("计算优化边界框失败:", error);
    // 返回原始计算方式作为备选
    return clippingObject.getBoundingRect(true, true);
  }
};
