import { createLayer, findInChildLayers, LayerType } from "../utils/layerHelper.js";
import { createRasterizedImage } from "../utils/selectionToImage.js";
import { CompositeCommand, Command } from "./Command.js";
import { CreateImageLayerCommand } from "./LayerCommands.js";
import { fabric } from "fabric-with-all";
import { generateId } from "../utils/helper.js";
import { ClearSelectionCommand } from "./LassoCutoutCommand.js";
import { ClearSelectionContentCommand } from "./ClearSelectionContentCommand.js";

/**
 * 剪切选区到新图层命令
 * 实现将选区内容复制到新图层，并将复制的选区作为组的遮罩
 */
export class CutSelectionToNewLayerCommand extends CompositeCommand {
  constructor(options = {}) {
    super([], {
      name: "剪切选区到新图层",
      description: "将选区复制到新图层并作为组遮罩",
    });
    this.canvas = options.canvas;
    this.layerManager = options.layerManager;
    this.selectionManager = options.selectionManager;
    this.toolManager = options.toolManager;
    this.sourceLayerId = options.sourceLayerId;
    this.newLayerName = options.newLayerName || "剪切";
    this.newLayerId = null;
    this.cutoutImageUrl = null;
    this.fabricImage = null;
    this.executedCommands = [];

    // 高清截图选项
    this.highResolutionEnabled = options.highResolutionEnabled !== false; // 默认启用
    this.baseResolutionScale = options.baseResolutionScale || 2; // 基础分辨率倍数

    this.groupId = options.groupId || `cut-group-${Date.now()}`;
    this.groupName = options.groupName || `剪切组`;
    this.groupLayer = null; // 保存组图层的引用
    this.originalLayersLength = 0; // 保存原始图层数量

    // 复制的选区对象，用作遮罩
    this.clippingMaskObject = null;
    this.sourceLayerId = null; // 保存源图层ID

    // 在初始化时克隆保存选区对象，避免撤销后重做时获取不到选区对象
    this._clonedSelectionObject = null;
    this._initializeClonedSelection();
  }

  /**
   * 初始化克隆的选区对象
   * @private
   */
  async _initializeClonedSelection() {
    if (this.selectionManager) {
      const selectionObject = this.selectionManager.getSelectionObject();
      if (selectionObject) {
        try {
          this._clonedSelectionObject = await this._cloneObject(selectionObject);
          console.log("剪切选区：选区对象已克隆保存");
        } catch (error) {
          console.error("剪切选区：克隆选区对象失败:", error);
          // 备用方案：序列化保存
          this.serializedSelectionObject = selectionObject.toObject([
            "id",
            "layerId",
            "layerName",
            "parentId",
          ]);
        }
      }
    }
  }

  async execute() {
    if (!this.canvas || !this.layerManager || !this.selectionManager) {
      console.error("无法执行剪切选区：参数无效");
      return false;
    }

    try {
      this.executedCommands = [];

      // 保存原始图层数量，用于撤销时的验证
      this.originalLayersLength = this.layerManager.layers.value.length;

      // 获取选区
      const selectionObject = await this._getSelectionObject();
      if (!selectionObject) {
        console.error("无法执行剪切选区：当前没有选区");
        return false;
      }

      // 确定源图层
      const sourceLayer = this.layerManager.getActiveLayer();
      if (!sourceLayer) {
        console.error("无法执行剪切选区：没有活动图层");
        return false;
      }

      // 保存源图层ID
      this.sourceLayerId = sourceLayer.id;

      // 获取源图层的所有对象（包括子图层）
      const sourceObjects = this._getLayerObjects(sourceLayer);
      if (sourceObjects.length === 0) {
        console.error("无法执行剪切选区：源图层没有可见对象");
        return false;
      }

      // 保存原图层状态用于撤销
      await this._backupOriginalLayer(sourceLayer, sourceObjects);

      // 获取选区边界信息用于后续定位
      const selectionBounds = selectionObject.getBoundingRect(true, true);

      // 步骤1: 先创建抠图到新图层（复制选区内容）
      this.fabricImage = await this._performCutoutWithRasterized(
        sourceObjects,
        selectionObject,
        selectionBounds
      );

      if (!this.fabricImage) {
        console.error("抠图失败");
        return false;
      }

      // 步骤2: 对原图层进行栅格化处理，移除选区内容
      await this._rasterizeOriginalLayerWithCutout(sourceLayer, sourceObjects, selectionObject);

      // 步骤3: 创建图像图层命令
      const createImageLayerCmd = new CreateImageLayerCommand({
        layerManager: this.layerManager,
        fabricImage: this.fabricImage,
        toolManager: this.toolManager,
        layerName: this.newLayerName,
      });

      // 执行创建图像图层命令
      const result = await createImageLayerCmd.execute();
      this.newLayerId = createImageLayerCmd.newLayerId;
      this.executedCommands.push(createImageLayerCmd);

      // 步骤4: 创建组图层并设置剪切结果为遮罩
      const topLayerIndex = this.layerManager.layers.value.findIndex(
        (layer) => layer.id === this.newLayerId
      );

      const selectLayer = this.layerManager.layers.value[topLayerIndex];

      // 创建新的组图层
      this.groupLayer = createLayer({
        id: this.groupId,
        name: this.groupName || `剪切组`,
        type: LayerType.GROUP,
        visible: true,
        locked: false,
        opacity: 1.0,
        fabricObjects: [],
        children: [],
      });

      this.fabricImage.set({
        selectable: true,
        evented: true,
      });

      selectLayer.parentId = this.groupId;
      selectLayer.fabricObjects = [
        this.fabricImage.toObject("id", "layerId", "layerName", "parentId"),
      ];
      this.groupLayer.clippingMask = this.fabricImage.toObject(
        "id",
        "layerId",
        "layerName",
        "parentId"
      );
      this.groupLayer.children.push(selectLayer);

      // 插入新组图层
      this.layerManager.layers.value.splice(topLayerIndex, 1, this.groupLayer);

      this.canvas.discardActiveObject();
      this.canvas.setActiveObject(this.fabricImage);
      await this.layerManager.updateLayersObjectsInteractivity(true);

      console.log(`剪切选区完成，新图层ID: ${this.newLayerId}`);
      return {
        newLayerId: this.newLayerId,
        cutoutImageUrl: this.cutoutImageUrl,
        groupId: this.groupId,
        groupName: this.groupName,
      };
    } catch (error) {
      console.error("剪切选区过程中出错:", error);

      // 错误清理和回滚
      await this._handleExecutionError();
      throw error;
    }
  }

  async undo() {
    try {
      console.log(`↩️ 开始撤销剪切选区操作`);

      // 1. 首先移除组图层（如果存在）
      if (this.groupId) {
        const groupIndex = this.layerManager.layers.value.findIndex(
          (layer) => layer.id === this.groupId
        );
        if (groupIndex !== -1) {
          this.layerManager.layers.value.splice(groupIndex, 1);
          console.log(`移除了组图层: ${this.groupId}`);
        }
      }

      if (this.fabricImage) {
        // 从画布移除抠图对象
        if (this.canvas.getObjects().includes(this.fabricImage)) {
          this.canvas.remove(this.fabricImage);
        }
      }

      // 2. 恢复原图层状态（关键：在撤销子命令之前恢复原图层）
      if (this.originalLayerRasterized) {
        await this._restoreOriginalLayer();
      }

      // 3. 逆序撤销所有已执行的子命令
      for (let i = this.executedCommands.length - 1; i >= 0; i--) {
        const command = this.executedCommands[i];
        try {
          if (command && typeof command.undo === "function") {
            await command.undo();
            console.log(`✅ 子命令撤销成功: ${command.constructor.name}`);
          }
        } catch (error) {
          console.error(`❌ 子命令撤销失败: ${command.constructor.name}`, error);
          // 子命令撤销失败不中断整个撤销过程
        }
      }

      // 4. 清理状态
      this.executedCommands = [];
      this.newLayerId = null;
      this.cutoutImageUrl = null;
      this.fabricImage = null;
      this.groupLayer = null;

      // 重置栅格化标记
      this.originalLayerRasterized = false;
      this.rasterizedOriginalImage = null;

      // 5. 更新画布和图层交互性
      await this.layerManager.updateLayersObjectsInteractivity(true);

      console.log(`✅ 剪切选区撤销完成`);
      return true;
    } catch (error) {
      console.error("❌ 撤销剪切选区失败:", error);
      return false;
    }
  }

  /**
   * 恢复原图层状态 - 关键修复方法
   * @private
   */
  async _restoreOriginalLayer() {
    try {
      console.log("🔄 开始恢复原图层状态...");

      if (!this.originalLayerBackup || !this.sourceLayerId) {
        console.warn("没有原图层备份数据或源图层ID");
        return;
      }

      // 1. 移除栅格化后的图像
      if (this.rasterizedOriginalImage) {
        if (this.canvas.getObjects().includes(this.rasterizedOriginalImage)) {
          this.canvas.remove(this.rasterizedOriginalImage);
          console.log("移除了栅格化图像");
        }
      }

      // 2. 获取当前的源图层引用
      const sourceLayer = this.layerManager.getLayerById(this.sourceLayerId);
      if (!sourceLayer) {
        console.error(`找不到源图层: ${this.sourceLayerId}`);
        return;
      }

      // 3. 清空当前图层的对象列表
      sourceLayer.fabricObjects = [];

      // 4. 恢复原始对象数据到图层
      if (this.originalLayerObjectsData.length > 0) {
        // 使用备份的序列化数据重建对象
        await this._restoreObjectsFromBackup(sourceLayer);
      } else {
        // 备用方案：恢复原始的fabricObjects数组
        sourceLayer.fabricObjects = this.originalLayerBackup.fabricObjects || [];

        if (sourceLayer.fabricObjects.length > 0) {
          await this._restoreLayerObjects(sourceLayer);
        }
      }

      console.log(`✅ 原图层状态恢复完成，恢复了 ${sourceLayer.fabricObjects.length} 个对象`);
    } catch (error) {
      console.error("恢复原图层状态失败:", error);
      throw error;
    }
  }

  /**
   * 从备份数据恢复对象 - 修复版本
   * @param {Object} layer 目标图层
   * @private
   */
  async _restoreObjectsFromBackup(layer) {
    return new Promise((resolve, reject) => {
      if (!this.originalLayerObjectsData || this.originalLayerObjectsData.length === 0) {
        console.warn("没有对象备份数据");
        resolve();
        return;
      }

      try {
        console.log(`开始从备份恢复 ${this.originalLayerObjectsData.length} 个对象...`);

        // 使用fabric.util.enlivenObjects重建对象
        fabric.util.enlivenObjects(this.originalLayerObjectsData, (restoredObjects) => {
          try {
            let successCount = 0;

            restoredObjects.forEach((obj, index) => {
              if (obj) {
                // 确保对象有正确的属性
                obj.set({
                  layerId: layer.id,
                  layerName: layer.name,
                  selectable: true,
                  evented: true,
                  visible: true,
                });

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

                // 添加到图层的fabricObjects数组
                layer.fabricObjects.push(
                  obj.toObject([
                    "id",
                    "layerId",
                    "layerName",
                    "parentId",
                    "selectable",
                    "evented",
                    "visible",
                  ])
                );

                successCount++;
                console.log(
                  `恢复对象 ${index + 1}/${restoredObjects.length}: ${obj.id || obj.type}`
                );
              } else {
                console.warn(`对象 ${index + 1} 恢复失败`);
              }
            });

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

            console.log(
              `✅ 成功恢复了 ${successCount}/${this.originalLayerObjectsData.length} 个对象`
            );
            resolve();
          } catch (error) {
            console.error("处理恢复的对象时出错:", error);
            reject(error);
          }
        });
      } catch (error) {
        console.error("恢复对象时出错:", error);
        reject(error);
      }
    });
  }

  /**
   * 重做操作
   * @returns {Promise<boolean>} 执行结果
   */
  async redo() {
    try {
      console.log(`🔄 开始重做剪切选区操作`);

      // 重做时重新执行整个操作
      const result = await this.execute();

      if (result) {
        console.log(`✅ 剪切选区重做完成`);
        return true;
      } else {
        console.log(`❌ 剪切选区重做失败`);
        return false;
      }
    } catch (error) {
      console.error("❌ 重做剪切选区失败:", error);
      return false;
    }
  }

  /**
   * 获取命令信息
   * @returns {Object} 命令详细信息
   */
  getInfo() {
    return {
      name: this.name,
      description: this.description,
      newLayerId: this.newLayerId,
      newLayerName: this.newLayerName,
      groupId: this.groupId,
      groupName: this.groupName,
      executedCommandsCount: this.executedCommands.length,
      hasGroupLayer: !!this.groupLayer,
      sourceLayerId: this.sourceLayerId,
      highResolutionEnabled: this.highResolutionEnabled,
      baseResolutionScale: this.baseResolutionScale,
      hasSerializedSelection: !!this.serializedSelectionObject,
      selectionType: this.serializedSelectionObject?.type || null,
      subCommands: this.executedCommands.map((cmd) => ({
        name: cmd.constructor.name,
        info: cmd.getInfo ? cmd.getInfo() : {},
      })),
    };
  }

  /**
   * 使用createRasterizedImage执行抠图操作
   * @param {Array} sourceObjects 源对象数组
   * @param {Object} selectionObject 选区对象
   * @param {Object} selectionBounds 选区边界
   * @returns {fabric.Image} 抠图结果的fabric图像对象
   * @private
   */
  async _performCutoutWithRasterized(sourceObjects, selectionObject, selectionBounds) {
    try {
      console.log("=== 开始使用createRasterizedImage执行剪切抠图 ===");
      console.log(`源对象数量: ${sourceObjects.length}`);
      console.log(`选区边界:`, selectionBounds);

      // 确定缩放因子，确保高质量输出
      let scaleFactor = this.baseResolutionScale;
      if (this.highResolutionEnabled) {
        const currentZoom = this.canvas.getZoom?.() || 1;
        scaleFactor = Math.max(scaleFactor || this.canvas?.getRetinaScaling?.(), currentZoom);
        scaleFactor = Math.min(scaleFactor, 3);
      }

      // 使用createRasterizedImage生成栅格化图像，将选区作为裁剪路径
      const rasterizedImage = await createRasterizedImage({
        canvas: this.canvas,
        fabricObjects: sourceObjects,
        clipPath: selectionObject,
        trimWhitespace: true,
        trimPadding: 2,
        quality: 1.0,
        format: "png",
        scaleFactor: scaleFactor,
        preserveOriginalQuality: true,
        selectionManager: this.selectionManager,
      });

      if (!rasterizedImage) {
        console.error("高质量剪切抠图失败");
        return null;
      }

      console.log(`✅ 高质量剪切抠图完成，缩放因子: ${scaleFactor}x`);
      return rasterizedImage;
    } catch (error) {
      console.error("使用createRasterizedImage执行剪切抠图失败:", error);
      throw error;
    }
  }

  /**
   * 获取图层的所有对象（包括子图层，从画布中查找真实对象）
   * @param {Object} layer 图层对象
   * @returns {Array} 真实的fabric对象数组
   * @private
   */
  _getLayerObjects(layer) {
    const objects = [];
    const canvasObjects = this.canvas.getObjects();

    // 递归获取图层及其子图层的所有对象
    const collectLayerObjects = (currentLayer) => {
      // 处理图层的fabricObjects
      if (currentLayer.fabricObjects && Array.isArray(currentLayer.fabricObjects)) {
        currentLayer.fabricObjects.forEach((fabricObj) => {
          if (fabricObj && fabricObj.id) {
            const realObject = canvasObjects.find((canvasObj) => canvasObj.id === fabricObj.id);
            if (realObject && realObject.visible !== false) {
              objects.push(realObject);
            }
          }
        });
      }

      // 处理单个fabricObject（背景图层等）
      if (currentLayer.fabricObject && currentLayer.fabricObject.id) {
        const realObject = canvasObjects.find(
          (canvasObj) => canvasObj.id === currentLayer.fabricObject.id
        );
        if (realObject && realObject.visible !== false) {
          objects.push(realObject);
        }
      }

      // 递归处理子图层
      if (currentLayer.children && Array.isArray(currentLayer.children)) {
        currentLayer.children.forEach((childLayer) => {
          collectLayerObjects(childLayer);
        });
      }
    };

    collectLayerObjects(layer);

    console.log(`从图层 "${layer.name}" 收集到 ${objects.length} 个可见对象`);
    return objects;
  }

  /**
   * 序列化选区对象
   * @private
   */
  _serializeSelectionObject() {
    try {
      if (!this.selectionManager) {
        console.warn("选区管理器不存在，无法序列化选区对象");
        return;
      }

      const selectionObject = this.selectionManager.getSelectionObject();
      if (!selectionObject) {
        console.warn("当前没有选区对象，无法序列化");
        return;
      }

      // 将选区对象转换为可序列化的对象
      this.serializedSelectionObject = selectionObject.toObject([
        "id",
        "layerId",
        "layerName",
        "parentId",
      ]);

      console.log("选区对象已序列化保存");
    } catch (error) {
      console.error("序列化选区对象失败:", error);
      this.serializedSelectionObject = null;
    }
  }

  /**
   * 反序列化选区对象
   * @returns {Promise<Object>} 选区对象
   * @private
   */
  async _getSelectionObject() {
    try {
      // 优先使用克隆的选区对象
      if (this._clonedSelectionObject) {
        console.log("使用克隆的选区对象");
        return await this._cloneObject(this._clonedSelectionObject);
      }

      // 尝试从选区管理器获取当前选区
      const currentSelection = this.selectionManager.getSelectionObject();
      if (currentSelection) {
        console.log("从选区管理器获取到当前选区");
        return currentSelection;
      }

      // 最后使用序列化数据恢复（备用方案）
      if (!this.serializedSelectionObject) {
        console.error("没有可用的选区对象数据");
        return null;
      }

      console.log("从序列化数据恢复选区对象");

      // 根据选区对象类型进行反序列化
      return new Promise((resolve, reject) => {
        const objectType = this.serializedSelectionObject.type;

        if (objectType === "path") {
          fabric.Path.fromObject(this.serializedSelectionObject, (path) => {
            if (path) {
              console.log("路径选区对象反序列化成功");
              resolve(path);
            } else {
              reject(new Error("路径选区对象反序列化失败"));
            }
          });
        } else if (objectType === "polygon") {
          fabric.Polygon.fromObject(this.serializedSelectionObject, (polygon) => {
            if (polygon) {
              console.log("多边形选区对象反序列化成功");
              resolve(polygon);
            } else {
              reject(new Error("多边形选区对象反序列化失败"));
            }
          });
        } else if (objectType === "rect") {
          fabric.Rect.fromObject(this.serializedSelectionObject, (rect) => {
            if (rect) {
              console.log("矩形选区对象反序列化成功");
              resolve(rect);
            } else {
              reject(new Error("矩形选区对象反序列化失败"));
            }
          });
        } else if (objectType === "ellipse" || objectType === "circle") {
          fabric.Ellipse.fromObject(this.serializedSelectionObject, (ellipse) => {
            if (ellipse) {
              console.log("椭圆选区对象反序列化成功");
              resolve(ellipse);
            } else {
              reject(new Error("椭圆选区对象反序列化失败"));
            }
          });
        } else {
          // 通用对象反序列化
          fabric.util.enlivenObjects([this.serializedSelectionObject], (objects) => {
            if (objects && objects.length > 0) {
              console.log("通用选区对象反序列化成功");
              resolve(objects[0]);
            } else {
              reject(new Error("通用选区对象反序列化失败"));
            }
          });
        }
      });
    } catch (error) {
      console.error("获取选区对象失败:", error);
      return null;
    }
  }

  /**
   * 克隆fabric对象
   * @param {Object} obj fabric对象
   * @returns {Object} 克隆的对象
   * @private
   */
  async _cloneObject(obj) {
    return new Promise((resolve, reject) => {
      if (!obj) {
        reject(new Error("对象无效，无法克隆"));
        return;
      }

      try {
        obj.clone((cloned) => {
          if (cloned) {
            resolve(cloned);
          } else {
            reject(new Error("对象克隆失败"));
          }
        });
      } catch (error) {
        reject(error);
      }
    });
  }

  /**
   * 备份原图层状态
   * @param {Object} sourceLayer 源图层
   * @param {Array} sourceObjects 源对象数组
   * @private
   */
  async _backupOriginalLayer(sourceLayer, sourceObjects) {
    try {
      console.log("🔄 备份原图层状态...");

      // 深度复制图层对象
      this.originalLayerBackup = JSON.parse(JSON.stringify(sourceLayer));

      // 备份图层中的所有对象数据
      this.originalLayerObjectsData = [];
      for (const obj of sourceObjects) {
        if (obj && obj.toObject) {
          const objData = obj.toObject([
            "id",
            "layerId",
            "layerName",
            "parentId",
            "selectable",
            "evented",
            "visible",
          ]);
          this.originalLayerObjectsData.push(objData);
        }
      }

      this.originalLayerRasterized = false; // 标记原图层是否已栅格化

      console.log(`✅ 原图层状态已备份，对象数量: ${this.originalLayerObjectsData.length}`);
    } catch (error) {
      console.error("备份原图层状态失败:", error);
      throw error;
    }
  }

  /**
   * 对原图层进行栅格化处理，移除选区内容
   * @param {Object} sourceLayer 源图层
   * @param {Array} sourceObjects 源对象数组
   * @param {Object} selectionObject 选区对象
   * @private
   */
  async _rasterizeOriginalLayerWithCutout(sourceLayer, sourceObjects, selectionObject) {
    try {
      console.log("=== 开始对原图层进行栅格化处理，移除选区内容 ===");

      // 克隆选区对象，确保不影响原对象
      const clonedSelectionObject = await this._cloneObject(selectionObject);

      // 直接使用 ClearSelectionContentCommand 的正确实现，传入选区对象
      const clearCommand = new ClearSelectionContentCommand({
        canvas: this.canvas,
        layerManager: this.layerManager,
        selectionManager: this.selectionManager,
        selectionObject: clonedSelectionObject, // 传入选区对象
        highResolutionEnabled: this.highResolutionEnabled,
        baseResolutionScale: this.baseResolutionScale,
      });

      // 临时设置目标图层为当前源图层
      clearCommand.targetLayerId = sourceLayer.id;
      clearCommand.targetLayer = sourceLayer;

      // 执行清除选区内容命令
      await clearCommand.execute();

      // 获取清除后的栅格化图像
      this.rasterizedOriginalImage = clearCommand.rasterizedImage;
      this.originalLayerRasterized = true; // 标记原图层已栅格化

      console.log("✅ 原图层栅格化处理完成，选区内容已移除");
    } catch (error) {
      console.error("原图层栅格化处理失败:", error);
      throw error;
    }
  }

  /**
   * 创建反向剪切路径（选区外的内容）
   * @param {Object} selectionObject 选区对象
   * @param {Array} sourceObjects 源对象数组
   * @returns {Object} 反向剪切路径
   * @private
   */
  async _createInvertedClipPath(selectionObject, sourceObjects) {
    try {
      // 计算所有源对象的边界
      let minLeft = Infinity,
        minTop = Infinity,
        maxRight = -Infinity,
        maxBottom = -Infinity;

      sourceObjects.forEach((obj) => {
        const bounds = obj.getBoundingRect(true, true);
        minLeft = Math.min(minLeft, bounds.left);
        minTop = Math.min(minTop, bounds.top);
        maxRight = Math.max(maxRight, bounds.left + bounds.width);
        maxBottom = Math.max(maxBottom, bounds.top + bounds.height);
      });

      // 扩展边界以确保完整覆盖
      const padding = 50;
      const canvasBounds = {
        left: minLeft - padding,
        top: minTop - padding,
        width: maxRight - minLeft + padding * 2,
        height: maxBottom - minTop + padding * 2,
      };

      // 创建画布大小的矩形
      const canvasRect = new fabric.Rect({
        left: canvasBounds.left,
        top: canvasBounds.top,
        width: canvasBounds.width,
        height: canvasBounds.height,
        fill: "rgba(255,255,255,1)",
        stroke: "",
        selectable: false,
        evented: false,
        absolutePositioned: true,
        originX: "left",
        originY: "top",
      });

      // 克隆选区对象作为要移除的部分
      const cutoutPath = await this._cloneObject(selectionObject);
      cutoutPath.set({
        fill: "rgba(0,0,0,1)", // 黑色表示要移除的区域
        stroke: "",
        absolutePositioned: true,
        globalCompositeOperation: "destination-out", // 关键：使用destination-out混合模式
      });

      // 创建复合路径：画布矩形 - 选区 = 反向选区
      const invertedClipPath = new fabric.Group([canvasRect, cutoutPath], {
        selectable: false,
        evented: false,
        absolutePositioned: true,
      });

      return invertedClipPath;
    } catch (error) {
      console.error("创建反向剪切路径失败:", error);
      return null;
    }
  }
}
