import { fill, isArray } from "lodash-es";

/**
 * 图层关联工具类
 * 提供图层与画布对象关联管理的通用方法
 */

/**
 * 构建单个图层与画布对象的关联关系
 * @param {Object} layer 图层对象
 * @param {Array} canvasObjects 画布对象数组
 */
export function buildLayerAssociations(layer, canvasObjects) {
  if (!layer || !canvasObjects || !isArray(canvasObjects)) return;
  // 处理单个fabricObject关联
  if (layer.fabricObject) {
    // 如果图层已经有关联的fabricObject，确保它的layerId和layerName正确
    layer.fabricObject =
      canvasObjects.find((obj) => obj.id === layer.fabricObject.id) || null;
  }

  if (layer.clippingMask) {
    // clippingMask 可能是一个fabricObject或组 也可能是一个简单对象
    const clippingMaskObj = canvasObjects.find(
      (obj) => obj.id === layer.clippingMask.id
    );
    layer.clippingMask = clippingMaskObj
      ? clippingMaskObj?.toObject?.(["id"])
      : layer.clippingMask;
  }

  // 处理多个fabricObjects关联
  if (layer.fabricObjects && isArray(layer.fabricObjects)) {
    layer.fabricObjects = layer.fabricObjects
      .map((fabricObject) => {
        // 确保每个fabricObject的layerId和layerName正确
        const obj = canvasObjects.find((obj) => obj.id === fabricObject.id);
        if (obj) {
          obj.layerId = layer.id; // 确保对象的layerId正确
          obj.layerName = layer.name; // 确保对象的layerName正确
          return obj;
        }
        return null; // 如果没有找到对象，返回null
      })
      .filter((obj) => obj !== null); // 过滤掉null值
  }
}

/**
 * 恢复对象与图层的关联关系
 * @param {Object} layerManager 图层管理器实例
 * @param {Array} canvasObjects 画布对象数组
 */
export function restoreObjectLayerAssociations(layers, canvasObjects) {
  if (!layers || !canvasObjects || !isArray(canvasObjects)) return;
  layers.forEach((layer) => {
    buildLayerAssociations(layer, canvasObjects);
    // 处理子图层
    if (layer?.children?.length) {
      restoreObjectLayerAssociations(layer.children, canvasObjects);
    }
  });
}

/**
 * 为画布对象设置图层信息
 * @param {Object} fabricObject 画布对象
 * @param {Object} layer 图层对象
 */
export function setObjectLayerInfo(fabricObject, layer) {
  if (!fabricObject || !layer) return;

  fabricObject.layerId = layer.id;
  fabricObject.layerName = layer.name;
}

/**
 * 清除画布对象的图层信息
 * @param {Object} fabricObject 画布对象
 */
export function clearObjectLayerInfo(fabricObject) {
  if (!fabricObject) return;

  delete fabricObject.layerId;
  delete fabricObject.layerName;
}

/**
 * 验证图层关联关系的完整性
 * @param {Object} layerManager 图层管理器实例
 * @param {fabric.Canvas} canvas 画布实例
 * @returns {Object} 验证结果 { valid: boolean, issues: Array }
 */
export function validateLayerAssociations(layers, canvasObjects) {
  const issues = [];

  // 检查画布对象是否都有对应的图层
  canvasObjects.forEach((obj) => {
    if (obj.layerId) {
      const layer = layers.find((l) => l.id === obj.layerId);
      if (!layer) {
        issues.push({
          type: "orphaned_object",
          objectId: obj.id,
          layerId: obj.layerId,
          message: `对象 ${obj.id} 关联的图层 ${obj.layerId} 不存在`,
        });
      }
    } else {
      issues.push({
        type: "missing_layer_id",
        objectId: obj.id,
        message: `对象 ${obj.id} 缺少图层ID关联`,
      });
    }
  });

  // 检查图层是否都有对应的画布对象
  layers.forEach((layer) => {
    if (layer.fabricObject && layer.fabricObject.id) {
      const obj = canvasObjects.find((o) => o.id === layer.fabricObject.id);
      if (!obj) {
        issues.push({
          type: "missing_object",
          layerId: layer.id,
          objectId: layer.fabricObject.id,
          message: `图层 ${layer.id} 关联的对象 ${layer.fabricObject.id} 不存在于画布中`,
        });
      }
    }

    if (layer.fabricObjects && isArray(layer.fabricObjects)) {
      layer.fabricObjects.forEach((fabricObj) => {
        if (fabricObj.id) {
          const obj = canvasObjects.find((o) => o.id === fabricObj.id);
          if (!obj) {
            issues.push({
              type: "missing_object",
              layerId: layer.id,
              objectId: fabricObj.id,
              message: `图层 ${layer.id} 关联的对象 ${fabricObj.id} 不存在于画布中`,
            });
          }
        }
      });
    }
  });

  return {
    valid: issues.length === 0,
    issues,
  };
}

/**
 * 简化layers对象属性，只保留必要的属性
 * @param {Array} layers 图层数组
 * @param {Array} excludedLayers 排除的图层ID数组
 * @returns {Array} 简化后的图层数组
 */
export function simplifyLayers(layers, excludedLayers = []) {
  if (!layers || !isArray(layers)) {
    console.warn("simplifyLayers 请传入有效的图层数组:", layers);
    return [];
  }

  return layers.map((layer) => {
    // 检查是否在排除列表中
    if (excludedLayers && excludedLayers.includes(layer.id)) return null;

    const simplifiedLayer = {
      id: layer.id,
      name: layer.name,
      visible: layer.visible,
      locked: layer.locked,
      opacity: layer.opacity,
      isBackground: layer.isBackground || false,
      isFixed: layer.isFixed || false,
	  isFixedOther: layer.isFixedOther || false,
	  isFixedClipMask: layer.isFixedClipMask || false,
      isHidenDragHandle: layer.isHidenDragHandle || false,
      isDisableUnlock: layer.isDisableUnlock || false,
      clippingMask:
        layer.clippingMask?.toObject?.(["id", "layerId"]) ||
        layer.clippingMask ||
        null, // 可能是一个fabricObject或组 也可能是一个简单对象
      // ? {
      //     id: layer.clippingMask.id,
      //     type: layer.clippingMask.type,
      //   }
      // : null,
      fabricObject: layer.fabricObject
        ? {
            id: layer.fabricObject.id,
            type: layer.fabricObject.type,
          }
        : null,
      fabricObjects:
        layer.fabricObjects && isArray(layer.fabricObjects)
          ? layer.fabricObjects
              .map((fabricObject) =>
                fabricObject?.id
                  ? {
                      id: fabricObject.id,
                      type: fabricObject.type,
                    }
                  : null
              )
              .filter((obj) => obj !== null)
          : [],
      children:
        layer.children && isArray(layer.children)
          ? simplifyLayers(layer.children)
          : [],
      fill: layer?.fill || null,
      fillColor: layer.fillColor,
      selectObject: layer.selectObject,
	  blendMode: layer.blendMode || null,
    };

    return simplifiedLayer;
  }).filter((layer) => !!layer);
}

/**
 * 恢复图层的完整关联关系
 * @param {Array} simplifiedLayers 简化的图层数组
 * @param {Array} canvasObjects 画布对象数组
 * @returns {Array} 恢复关联后的图层数组
 */
export function restoreLayers(simplifiedLayers, canvasObjects) {
  if (!simplifiedLayers || !isArray(simplifiedLayers)) {
    console.warn("restoreLayers 请传入有效的简化图层数组:", simplifiedLayers);
    return [];
  }

  if (!canvasObjects || !isArray(canvasObjects)) {
    console.warn("restoreLayers 请传入有效的画布对象数组:", canvasObjects);
    return simplifiedLayers;
  }

  return simplifiedLayers.map((layer) => {
    const restoredLayer = { ...layer };

    // 恢复clippingMask关联
    // if (layer.clippingMask?.id) {
    //   const clippingMaskObj = canvasObjects.find(
    //     (obj) => obj.id === layer.clippingMask.id
    //   );
    //   restoredLayer.clippingMask = clippingMaskObj || null;
    // }

    if (layer.clippingMask) {
      // clippingMask 可能是一个fabricObject或组 也可能是一个简单对象
      const clippingMaskObj = canvasObjects.find(
        (obj) => obj.id === layer.clippingMask.id
      );
      restoredLayer.clippingMask = clippingMaskObj
        ? clippingMaskObj?.toObject?.(["id"])
        : layer.clippingMask;
    }

    // 恢复单个fabricObject关联
    if (layer.fabricObject?.id) {
      const fabricObj = canvasObjects.find(
        (obj) => obj.id === layer.fabricObject.id
      );
      if (fabricObj) {
        fabricObj.layerId = layer.id;
        fabricObj.layerName = layer.name;
        restoredLayer.fabricObject = fabricObj.toObject([
          "id",
          "layerId",
          "type",
        ]);
      } else {
        restoredLayer.fabricObject = null;
      }
    }

    // 恢复多个fabricObjects关联
    if (layer.fabricObjects && isArray(layer.fabricObjects)) {
      restoredLayer.fabricObjects = layer.fabricObjects
        .map((fabricRef) => {
          const fabricObj = canvasObjects.find(
            (obj) => obj.id === fabricRef.id
          );
          if (fabricObj) {
            fabricObj.layerId = layer.id;
            fabricObj.layerName = layer.name;
            return fabricObj.toObject(["id", "layerId", "type"]);
          }
          return null;
        })
        .filter((obj) => obj !== null);
    }

    // 递归处理子图层
    if (layer.children && isArray(layer.children)) {
      restoredLayer.children = restoreLayers(layer.children, canvasObjects);
    }

    return restoredLayer;
  });
}

/**
 * 序列化图层数据用于保存
 * @param {Array} layers 图层数组
 * @returns {string} 序列化后的JSON字符串
 */
export function serializeLayers(layers) {
  try {
    const simplified = simplifyLayers(layers);
    return JSON.stringify(simplified, null, 2);
  } catch (error) {
    console.error("序列化图层数据失败:", error);
    return null;
  }
}

/**
 * 反序列化图层数据并恢复关联
 * @param {string} serializedLayers 序列化的图层JSON字符串
 * @param {Array} canvasObjects 画布对象数组
 * @returns {Array} 恢复关联后的图层数组
 */
export function deserializeLayers(serializedLayers, canvasObjects) {
  try {
    const simplified = JSON.parse(serializedLayers);
    return restoreLayers(simplified, canvasObjects);
  } catch (error) {
    console.error("反序列化图层数据失败:", error);
    return [];
  }
}

/**
 * 获取图层的存储快照（用于撤销/重做）
 * @param {Array} layers 图层数组
 * @returns {Object} 图层快照对象
 */
export function createLayerSnapshot(layers) {
  return {
    timestamp: Date.now(),
    data: simplifyLayers(layers),
  };
}

/**
 * 从快照恢复图层状态
 * @param {Object} snapshot 图层快照对象
 * @param {Array} canvasObjects 画布对象数组
 * @returns {Array} 恢复的图层数组
 */
export function restoreFromSnapshot(snapshot, canvasObjects) {
  if (!snapshot?.data) {
    console.warn("无效的图层快照:", snapshot);
    return [];
  }

  return restoreLayers(snapshot.data, canvasObjects);
}

/**
 * 获取对象的定位信息
 * @param {Object} object 对象
 * @returns {Object} 对象的定位信息
 */
export function getOriginObjectInfo(object) {
  if (!object) {
    console.warn("getOriginObjectInfo 请传入有效的fabric对象:", object);
    return {};
  }

  // 获取对象的原始信息
  const originInfo = {
    left: object.left || 0,
    top: object.top || 0,
    scaleX: object.scaleX || 1,
    scaleY: object.scaleY || 1,
    angle: object.angle || 0,
    flipX: object.flipX || false,
    flipY: object.flipY || false,
    skewX: object.skewX || 0,
    skewY: object.skewY || 0,
  };

  return originInfo;
}
