import { Command } from "./Command";
import { isGroupLayer } from "../utils/layerHelper";

/**
 * 跨层级移动命令基类
 */
export class CrossLevelMoveCommand extends Command {
  constructor(options) {
    super({
      name: "跨层级移动",
      undoable: true,
    });

    this.layers = options.layers;
    this.layerManager = options.layerManager;
    this.canvas = options.canvas;

    // 移动相关参数
    this.layerId = options.layerId;
    this.fromContainerType = options.fromContainerType; // 'root' | 'child'
    this.toContainerType = options.toContainerType; // 'root' | 'child'
    this.fromParentId = options.fromParentId;
    this.toParentId = options.toParentId;
    this.newIndex = options.newIndex;
    this.oldIndex = options.oldIndex;

    // 保存状态用于撤销
    this.beforeState = null;
    this.afterState = null;
  }

  /**
   * 保存移动前的状态
   */
  saveBeforeState() {
    this.beforeState = {
      layerStructure: this.cloneLayerStructure(),
      fabricObjects: this.saveFabricObjectStates(),
    };
  }

  /**
   * 保存移动后的状态
   */
  saveAfterState() {
    this.afterState = {
      layerStructure: this.cloneLayerStructure(),
      fabricObjects: this.saveFabricObjectStates(),
    };
  }

  /**
   * 克隆图层结构
   */
  cloneLayerStructure() {
    return JSON.parse(
      JSON.stringify(
        this.layers.value.map((layer) => ({
          id: layer.id,
          name: layer.name,
          parentId: layer.parentId,
          children: layer.children
            ? layer.children.map((child) => ({
                id: child.id,
                name: child.name,
                parentId: child.parentId,
              }))
            : [],
          isBackground: layer.isBackground,
          isFixed: layer.isFixed,
          visible: layer.visible,
          locked: layer.locked,
        }))
      )
    );
  }

  /**
   * 保存fabric对象状态
   */
  saveFabricObjectStates() {
    const states = {};

    // 只保存fabric对象的容器关系，不保存具体的属性
    this.layers.value.forEach((layer) => {
      if (layer.fabricObject) {
        states[layer.id] = {
          isInCanvas: this.canvas ? this.canvas.contains(layer.fabricObject) : false,
          parentGroupId: null,
          visible: layer.fabricObject.visible,
        };

        // 检查是否在某个组中
        this.layers.value.forEach((otherLayer) => {
          if (
            otherLayer.fabricObject &&
            otherLayer.fabricObject.type === "group" &&
            otherLayer.fabricObject.contains &&
            otherLayer.fabricObject.contains(layer.fabricObject)
          ) {
            states[layer.id].parentGroupId = otherLayer.id;
            states[layer.id].isInCanvas = false;
          }
        });
      }
    });

    return states;
  }

  /**
   * 查找图层
   */
  findLayer(layerId, containerType, parentId) {
    if (containerType === "root") {
      return this.layers.value.find((layer) => layer.id === layerId);
    } else if (containerType === "child" && parentId) {
      const parent = this.layers.value.find((layer) => layer.id === parentId);
      return parent?.children?.find((child) => child.id === layerId);
    }
    return null;
  }

  /**
   * 验证移动的有效性
   */
  validateMove() {
    const layer = this.findLayer(this.layerId, this.fromContainerType, this.fromParentId);

    if (!layer) {
      throw new Error(`找不到要移动的图层: ${this.layerId}`);
    }

    // 检查是否为不可移动的图层
    if (layer.isBackground || layer.isFixed) {
      throw new Error("背景层和固定层不能移动");
    }

    // 检查是否试图将图层移动到自己的子层级中（防止循环引用）
    if (
      this.toContainerType === "child" &&
      this.toParentId &&
      this.isDescendantOf(this.toParentId, this.layerId)
    ) {
      throw new Error("不能将图层移动到自己的子层级中");
    }

    // 检查目标父图层是否为组
    if (this.toContainerType === "child") {
      const targetParent = this.layers.value.find((layer) => layer.id === this.toParentId);
      if (!targetParent || !isGroupLayer(targetParent)) {
        throw new Error("目标图层不是组图层");
      }
    }

    return layer;
  }

  /**
   * 检查是否为子层级关系（防止循环引用）
   */
  isDescendantOf(ancestorId, layerId) {
    const checkChildren = (children) => {
      if (!children) return false;
      for (const child of children) {
        if (child.id === layerId) return true;
        if (child.children && checkChildren(child.children)) return true;
      }
      return false;
    };

    const ancestor = this.layers.value.find((layer) => layer.id === ancestorId);
    return ancestor ? checkChildren(ancestor.children) : false;
  }

  async execute() {
    console.log("🎯 执行跨层级移动命令:", {
      layerId: this.layerId,
      from: this.fromContainerType,
      to: this.toContainerType,
      fromParentId: this.fromParentId,
      toParentId: this.toParentId,
    });

    // 验证移动
    const draggedLayer = this.validateMove();

    // 保存移动前状态
    this.saveBeforeState();

    try {
      // 根据移动类型执行对应操作
      if (this.fromContainerType === "root" && this.toContainerType === "child") {
        this.moveRootToGroup(draggedLayer);
      } else if (this.fromContainerType === "child" && this.toContainerType === "root") {
        this.moveGroupToRoot(draggedLayer);
      } else if (
        this.fromContainerType === "child" &&
        this.toContainerType === "child" &&
        this.fromParentId !== this.toParentId
      ) {
        this.moveGroupToGroup(draggedLayer);
      }

      // 保存移动后状态
      this.saveAfterState();

      // 刷新画布
      // if (this.canvas) {
      //   this.canvas.renderAll();
      //   console.log("🎨 画布已刷新");
      // }

      await this.layerManager?.updateLayersObjectsInteractivity();
      this.canvas?.renderAll();

      // 生成缩略图
      this.fromParentId &&
        this.layerManager?.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(
          this.fromParentId
        );

      this.toParentId &&
        this.layerManager?.canvasManager?.thumbnailManager?.generateLayerThumbnail?.(
          this.toParentId
        );

      console.log("✅ 跨层级移动命令执行成功");
      return true;
    } catch (error) {
      console.error("❌ 跨层级移动命令执行失败:", error);

      // 如果执行失败，尝试恢复到之前的状态
      if (this.beforeState) {
        try {
          this.restoreLayerStructure(this.beforeState.layerStructure);
          this.restoreFabricObjectStates(this.beforeState.fabricObjects);
          if (this.canvas) {
            this.canvas.renderAll();
          }
          console.log("🔄 已恢复到移动前状态");
        } catch (restoreError) {
          console.error("❌ 恢复状态失败:", restoreError);
        }
      }

      throw error;
    }
  }

  async undo() {
    if (!this.beforeState) {
      throw new Error("没有保存的前置状态，无法撤销");
    }

    console.log("🔄 撤销跨层级移动命令");

    try {
      // 恢复图层结构
      this.restoreLayerStructure(this.beforeState.layerStructure);

      // 恢复fabric对象状态
      this.restoreFabricObjectStates(this.beforeState.fabricObjects);

      await this.layerManager?.updateLayersObjectsInteractivity();
      // 刷新画布
      this.canvas?.renderAll();
      console.log("✅ 跨层级移动命令撤销成功");
      return true;
    } catch (error) {
      console.error("❌ 跨层级移动命令撤销失败:", error);

      // 尝试基本的恢复操作
      try {
        console.log("🔄 尝试基本恢复操作");
        this.basicRestore();
      } catch (restoreError) {
        console.error("❌ 基本恢复也失败:", restoreError);
      }

      throw error;
    }
  }

  /**
   * 基本恢复操作（当标准撤销失败时使用）
   */
  basicRestore() {
    // 重新组织所有图层的fabric对象
    this.layers.value.forEach((layer) => {
      if (layer.fabricObject) {
        try {
          // 先从所有容器中移除
          this.removeFromAllContainers(layer.fabricObject);

          // 根据图层的parentId重新放置
          if (layer.parentId) {
            const parentLayer = this.layers.value.find((l) => l.id === layer.parentId);
            if (
              parentLayer &&
              parentLayer.fabricObject &&
              parentLayer.fabricObject.type === "group"
            ) {
              this.safeAddToContainer(
                layer.fabricObject,
                parentLayer.fabricObject,
                `父组${layer.parentId}`
              );
            }
          } else {
            this.safeAddToContainer(layer.fabricObject, this.canvas, "画布");
          }
        } catch (error) {
          console.error(`❌ 基本恢复图层 ${layer.id} 失败:`, error);
        }
      }
    });

    if (this.canvas) {
      this.canvas.renderAll();
    }
  }

  /**
   * 重做命令
   */
  async redo() {
    if (!this.afterState) {
      throw new Error("没有保存的后置状态，无法重做");
    }

    console.log("🔄 重做跨层级移动命令");

    try {
      // 恢复图层结构
      this.restoreLayerStructure(this.afterState.layerStructure);

      // 恢复fabric对象状态
      this.restoreFabricObjectStates(this.afterState.fabricObjects);

      await this.layerManager?.updateLayersObjectsInteractivity();
      // 刷新画布
      this.canvas?.renderAll();

      console.log("✅ 跨层级移动命令重做成功");
      return true;
    } catch (error) {
      console.error("❌ 跨层级移动命令重做失败:", error);

      // 尝试基本的恢复操作
      try {
        console.log("🔄 尝试基本恢复操作");
        this.basicRestore();
      } catch (restoreError) {
        console.error("❌ 基本恢复也失败:", restoreError);
      }

      throw error;
    }
  }

  /**
   * 恢复图层结构
   */
  restoreLayerStructure(layerStructure) {
    // 保存原始图层数组的引用
    const originalLayers = [...this.layers.value];

    // 清空当前图层
    this.layers.value.splice(0);

    // 重建图层结构
    layerStructure.forEach((layerData) => {
      // 首先从原始图层数组中查找图层
      let layer = originalLayers.find((l) => l.id === layerData.id);

      // 如果没找到，尝试在嵌套结构中查找
      if (!layer) {
        layer = this.findLayerInOriginalStructure(layerData.id, originalLayers);
      }

      if (layer) {
        // 更新图层属性
        layer.parentId = layerData.parentId;
        layer.visible = layerData.visible;
        layer.locked = layerData.locked;

        // 重建children数组
        if (layerData.children && layerData.children.length > 0) {
          layer.children = layerData.children
            .map((childData) => {
              // 从原始图层数组中查找子图层
              let childLayer = originalLayers.find((l) => l.id === childData.id);
              if (!childLayer) {
                childLayer = this.findLayerInOriginalStructure(childData.id, originalLayers);
              }
              if (childLayer) {
                // 更新子图层属性
                childLayer.parentId = childData.parentId;
                childLayer.visible = childData.visible;
                childLayer.locked = childData.locked;
                return childLayer;
              }
              return null;
            })
            .filter(Boolean);
        } else {
          layer.children = [];
        }

        this.layers.value.push(layer);
      }
    });
  }

  /**
   * 在原始结构中查找图层
   */
  findLayerInOriginalStructure(layerId, layers = null) {
    const layersToSearch = layers || this.layers.value;

    const findInLayers = (layersList) => {
      for (const layer of layersList) {
        if (layer.id === layerId) return layer;
        if (layer.children) {
          const found = findInLayers(layer.children);
          if (found) return found;
        }
      }
      return null;
    };

    return findInLayers(layersToSearch);
  }

  /**
   * 恢复fabric对象状态
   */
  restoreFabricObjectStates(fabricStates) {
    if (!this.canvas || !fabricStates) return;

    console.log("🔧 开始恢复fabric对象状态");

    // 重新组织fabric对象的层级关系
    this.layers.value.forEach((layer) => {
      if (layer.fabricObject && fabricStates[layer.id]) {
        const targetState = fabricStates[layer.id];
        console.log(`🔍 恢复图层 ${layer.id} 的fabric对象状态:`, targetState);

        try {
          // 首先从所有容器中移除对象
          this.removeFromAllContainers(layer.fabricObject);

          // 根据目标状态放置对象
          if (targetState.parentGroupId) {
            // 应该在特定组中
            const parentLayer = this.layers.value.find((l) => l.id === targetState.parentGroupId);
            if (
              parentLayer &&
              parentLayer.fabricObject &&
              parentLayer.fabricObject.type === "group"
            ) {
              this.safeAddToContainer(
                layer.fabricObject,
                parentLayer.fabricObject,
                `父组${targetState.parentGroupId}`
              );
            }
          } else if (targetState.isInCanvas) {
            // 应该在画布中
            this.safeAddToContainer(layer.fabricObject, this.canvas, "画布");
          }

          // 恢复可见性
          if (layer.fabricObject.visible !== targetState.visible) {
            layer.fabricObject.visible = targetState.visible;
          }
        } catch (error) {
          console.error(`❌ 恢复图层 ${layer.id} 的fabric对象时出错:`, error);
        }
      }
    });

    // 强制重新渲染画布
    if (this.canvas) {
      this.canvas.renderAll();
      console.log("✅ 画布已重新渲染");
    }
  }

  /**
   * 安全地处理fabric对象操作
   */
  safeFabricOperation(operation, operationName = "fabric操作") {
    try {
      return operation();
    } catch (error) {
      console.error(`❌ ${operationName}失败:`, error);
      return false;
    }
  }

  /**
   * 安全地添加fabric对象到容器
   */
  safeAddToContainer(fabricObject, container, containerName) {
    return this.safeFabricOperation(() => {
      if (container && container.add && !container.contains(fabricObject)) {
        container.add(fabricObject);
        console.log(`✅ 成功将对象添加到${containerName}`);
        return true;
      }
      return false;
    }, `添加对象到${containerName}`);
  }

  /**
   * 安全地从容器移除fabric对象
   */
  safeRemoveFromContainer(fabricObject, container, containerName) {
    return this.safeFabricOperation(() => {
      if (container && container.remove && container.contains && container.contains(fabricObject)) {
        container.remove(fabricObject);
        console.log(`✅ 成功从${containerName}移除对象`);
        return true;
      }
      return false;
    }, `从${containerName}移除对象`);
  }

  /**
   * 从所有容器中移除fabric对象
   */
  removeFromAllContainers(fabricObject) {
    // 从画布中移除
    this.safeRemoveFromContainer(fabricObject, this.canvas, "画布");

    // 从所有组中移除
    this.layers.value.forEach((layer) => {
      if (layer.fabricObject && layer.fabricObject.type === "group") {
        this.safeRemoveFromContainer(fabricObject, layer.fabricObject, `组${layer.id}`);
      }
    });
  }

  /**
   * 从顶级图层移动到组图层内
   */
  moveRootToGroup(draggedLayer) {
    console.log("📥 执行顶级图层移动到组内:", {
      layerId: draggedLayer.id,
      toParentId: this.toParentId,
      newIndex: this.newIndex,
    });

    const targetParent = this.layers.value.find((layer) => layer.id === this.toParentId);
    if (!targetParent) {
      throw new Error(`找不到目标父图层: ${this.toParentId}`);
    }

    // 确保父图层有children数组
    if (!targetParent.children) {
      targetParent.children = [];
    }

    // 从顶级图层数组中移除
    const rootIndex = this.layers.value.findIndex((layer) => layer.id === draggedLayer.id);
    if (rootIndex !== -1) {
      this.layers.value.splice(rootIndex, 1);
      console.log(`🗑️ 从顶级图层数组中移除图层 ${draggedLayer.id}`);
    }

    // 更新图层关系
    draggedLayer.parentId = this.toParentId;
    targetParent.children.splice(this.newIndex, 0, draggedLayer);
    console.log(`📂 将图层 ${draggedLayer.id} 添加到父图层 ${this.toParentId} 的children中`);

    // 处理fabric对象的层级关系
    if (draggedLayer.fabricObject && targetParent.fabricObject) {
      console.log(`🎨 处理fabric对象层级关系`);

      // 从画布中移除
      this.safeRemoveFromContainer(draggedLayer.fabricObject, this.canvas, "画布");

      // 添加到父组
      this.safeAddToContainer(
        draggedLayer.fabricObject,
        targetParent.fabricObject,
        `父组${this.toParentId}`
      );
    }

    console.log("✅ 顶级图层移动到组内完成");
  }

  /**
   * 从组图层内移动到顶级图层
   */
  moveGroupToRoot(draggedLayer) {
    console.log("📤 执行组内图层移动到顶级:", {
      layerId: draggedLayer.id,
      fromParentId: this.fromParentId,
      newIndex: this.newIndex,
    });

    const sourceParent = this.layers.value.find((layer) => layer.id === this.fromParentId);
    if (!sourceParent || !sourceParent.children) {
      throw new Error(`找不到源父图层或其children数组: ${this.fromParentId}`);
    }

    // 从源父图层的children中移除
    const childIndex = sourceParent.children.findIndex((child) => child.id === draggedLayer.id);
    if (childIndex !== -1) {
      sourceParent.children.splice(childIndex, 1);
      console.log(`🗑️ 从父图层 ${this.fromParentId} 的children中移除图层 ${draggedLayer.id}`);
    }

    // 处理fabric对象的层级关系
    if (draggedLayer.fabricObject && sourceParent.fabricObject) {
      console.log(`🎨 处理fabric对象层级关系`);

      // 从父组中移除
      this.safeRemoveFromContainer(
        draggedLayer.fabricObject,
        sourceParent.fabricObject,
        `父组${this.fromParentId}`
      );

      // 添加到画布
      this.safeAddToContainer(draggedLayer.fabricObject, this.canvas, "画布");
    }

    // 清除图层的parentId
    delete draggedLayer.parentId;
    console.log(`🔗 清除图层 ${draggedLayer.id} 的parentId`);

    // 计算在顶级图层中的插入位置
    const targetIndex = Math.min(this.newIndex, this.layers.value.length);
    this.layers.value.splice(targetIndex, 0, draggedLayer);
    console.log(`📂 将图层 ${draggedLayer.id} 添加到顶级图层数组位置 ${targetIndex}`);

    console.log("✅ 组内图层移动到顶级完成");
  }

  /**
   * 在不同组之间移动
   */
  moveGroupToGroup(draggedLayer) {
    console.log("🔄 执行在不同组间移动:", {
      layerId: draggedLayer.id,
      fromParentId: this.fromParentId,
      toParentId: this.toParentId,
      newIndex: this.newIndex,
    });

    const sourceParent = this.layers.value.find((layer) => layer.id === this.fromParentId);
    const targetParent = this.layers.value.find((layer) => layer.id === this.toParentId);

    if (!sourceParent || !targetParent) {
      throw new Error("找不到源父图层或目标父图层");
    }

    // 从源父图层中移除
    const childIndex = sourceParent.children.findIndex((child) => child.id === draggedLayer.id);
    if (childIndex !== -1) {
      sourceParent.children.splice(childIndex, 1);
      console.log(`🗑️ 从源父图层 ${this.fromParentId} 中移除图层 ${draggedLayer.id}`);

      // 从源父组的fabricObject中移除
      if (draggedLayer.fabricObject && sourceParent.fabricObject) {
        this.safeRemoveFromContainer(
          draggedLayer.fabricObject,
          sourceParent.fabricObject,
          `源父组${this.fromParentId}`
        );
      }
    }

    // 更新图层的parentId
    draggedLayer.parentId = this.toParentId;
    console.log(`🔗 更新图层 ${draggedLayer.id} 的parentId为 ${this.toParentId}`);

    // 确保目标父图层有children数组
    if (!targetParent.children) {
      targetParent.children = [];
    }

    // 将图层添加到目标组
    targetParent.children.splice(this.newIndex, 0, draggedLayer);
    console.log(
      `📂 将图层 ${draggedLayer.id} 添加到目标父图层 ${this.toParentId} 的位置 ${this.newIndex}`
    );

    // 将图层的fabricObject添加到目标父组中
    if (draggedLayer.fabricObject && targetParent.fabricObject) {
      this.safeAddToContainer(
        draggedLayer.fabricObject,
        targetParent.fabricObject,
        `目标父组${this.toParentId}`
      );
    }

    console.log("✅ 不同组间移动完成");
  }
}

/**
 * 创建跨层级移动命令的工厂函数
 */
export function createCrossLevelMoveCommand(options) {
  return new CrossLevelMoveCommand(options);
}
