<template>
  <transition name="fade">
    <div v-if="visible" class="liquify-panel">
      <div class="liquify-panel-header">
        <div class="header-title">液化工具</div>
        <!-- <div class="header-actions">
          <button class="header-btn cancel-btn" @click="cancel">取消</button>
          <button class="header-btn confirm-btn" @click="confirm">完成</button>
        </div> -->
      </div>

      <div class="liquify-panel-content">
        <!-- 液化模式选择器 -->
        <div class="liquify-modes">
          <div
            v-for="mode in availableModes"
            :key="mode.id"
            class="mode-item"
            :class="{ active: currentMode === mode.id }"
            @click="selectMode(mode.id)"
          >
            <div class="mode-icon" :class="`mode-${mode.id}`">
              <!-- <component :is="mode.icon" v-if="mode.icon" />
            <span v-else>{{ mode.iconText }}</span> -->
            </div>
            <div class="mode-name">{{ mode.name }}</div>
          </div>
        </div>

        <!-- 分割线 -->
        <div class="liquify-divider"></div>

        <!-- 参数调整区域 -->
        <div class="liquify-params">
          <div class="param-item">
            <div class="param-label">尺寸</div>
            <div class="param-control">
              <input
                type="range"
                v-model.number="size"
                min="5"
                max="200"
                @input="updateParam('size', size)"
                class="slider-control"
              />
              <div class="param-value">{{ size }}%</div>
            </div>
          </div>

          <div class="param-item">
            <div class="param-label">压力</div>
            <div class="param-control">
              <input
                type="range"
                v-model.number="pressure"
                min="0"
                max="100"
                @input="updateParam('pressure', pressure / 100)"
                class="slider-control"
              />
              <div class="param-value">{{ pressure }}%</div>
            </div>
          </div>

          <div class="param-item" v-if="showDistortion">
            <div class="param-label">失真</div>
            <div class="param-control">
              <input
                type="range"
                v-model.number="distortion"
                min="0"
                max="100"
                @input="updateParam('distortion', distortion / 100)"
                class="slider-control"
              />
              <div class="param-value">{{ distortion }}%</div>
            </div>
          </div>

          <div class="param-item">
            <div class="param-label">动力</div>
            <div class="param-control">
              <input
                type="range"
                v-model.number="power"
                min="0"
                max="100"
                @input="updateParam('power', power / 100)"
                class="slider-control"
              />
              <div class="param-value">{{ power }}%</div>
            </div>
          </div>
        </div>

        <!-- 调试信息 (开发模式) -->
        <div v-if="debug" class="debug-info">
          <div class="debug-header">调试信息</div>
          <div class="debug-item">
            渲染模式: <span>{{ renderMode }}</span>
          </div>
          <div class="debug-item">
            WebGL可用: <span>{{ webglAvailable ? "是" : "否" }}</span>
          </div>
          <div class="debug-item">
            操作次数: <span>{{ operationCount }}</span>
          </div>
          <div class="debug-item">
            平均耗时: <span>{{ avgOperationTime.toFixed(2) }}ms</span>
          </div>
          <div class="debug-item">
            当前液化图: <span><img :src="currImage" class="currImage" /> </span>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script setup>
import { ref, computed, onMounted, onUnmounted, watch } from "vue";
import {
  CompositeLiquifyCommand,
  createLiquifyResetCommand,
  createLiquifyDeformCommand,
} from "../commands/LiquifyCommands";
import { OperationType } from "../utils/layerHelper";

// Props定义
const props = defineProps({
  canvas: {
    type: Object,
    required: true,
  },
  commandManager: {
    type: Object,
    required: true,
  },
  liquifyManager: {
    type: Object,
    required: true,
  },
  layerManager: {
    type: Object,
    required: true,
  },
  // 添加当前工具的prop
  activeTool: {
    type: String,
    required: true,
  },
});

// 响应式数据
const visible = ref(false);
const debug = ref(true); // 设为true可以显示调试信息
const currImage = ref("");

// 当前状态
const isEditing = ref(false);
const isDrawing = ref(false); // 是否正在绘制
const targetObject = ref(null);
const targetLayerId = ref(null);
const originalImageData = ref(null);

// 渲染模式信息
const renderMode = ref("未知");
const webglAvailable = ref(false);
const operationCount = ref(0);
const avgOperationTime = ref(0);

// 鼠标位置追踪
const lastX = ref(0);
const lastY = ref(0);

// 当前模式
const currentMode = ref("push"); // 默认为推动模式

// 参数设置
const size = ref(50); // 工具大小 (5-200)
const pressure = ref(50); // 压力大小 (0-100)
const distortion = ref(0); // 失真程度 (0-100)
const power = ref(50); // 动力/强度 (0-100)

// 批量操作缓存
const compositeCommand = ref(null);

// 可用液化模式
const availableModes = ref([
  { id: "push", name: "推", iconText: "↔" },
  { id: "clockwise", name: "顺时针转动", iconText: "↻" },
  { id: "counterclockwise", name: "逆时针转动", iconText: "↺" },
  { id: "pinch", name: "捏合", iconText: "⤢" },
  { id: "expand", name: "展开", iconText: "⤡" },
  // { id: "crystal", name: "水晶", iconText: "✧" },
  { id: "edge", name: "边缘", iconText: "◈" },
  { id: "reconstruct", name: "重建", iconText: "↩" },
]);

// 事件监听器引用
let _handleMouseDown = null;
let _handleMouseMove = null;
let _handleMouseUp = null;

// 计算属性
const showDistortion = computed(() => {
  // 只在特定模式下显示失真控制
  return ["crystal", "edge"].includes(currentMode.value);
});

// 监听当前工具变化 - 参考 SelectionPanel 的实现方式
watch(
  () => props.activeTool,
  (newTool, oldTool) => {
    console.log("LiquifyPanel.vue 工具切换:", oldTool, "->", newTool);
    // 当工具切换到液化工具时显示面板
    if (newTool === OperationType.LIQUIFY) {
      console.log("切换到液化工具，准备显示面板");
      // 如果面板未显示且有合适的目标对象，则显示面板
      if (!visible.value) {
        visible.value = true;
        // 检查是否有可液化的对象
        checkAndShowPanel();
      }
    } else {
      visible.value = false; // 切换到其他工具时隐藏面板
      // 切换到其他工具，隐藏液化面板
      if (visible.value) {
        console.log("切换到其他工具，隐藏液化面板");
        close();
      }
    }
  },
  { immediate: true }
);

/**
 * 检查并显示面板
 */
function checkAndShowPanel() {
  // 检查当前是否有可液化的图层或对象
  if (props.canvas && props.activeTool === OperationType.LIQUIFY) {
    const activeLayer = props.layerManager.getActiveLayer();
    const activeObject = props.canvas
      .getObjects()
      .find((fItem) => fItem.layerId === activeLayer.id);
    if (activeObject) {
      // 有合适的对象，准备液化环境
      isEditing.value = true;
      // 准备液化环境
      prepareForLiquify(activeObject);
    } else {
      // 没有合适的对象
      targetObject.value = null;
      console.log("未选择有效的图像对象");
    }
  }
}

/**
 * 准备液化环境
 */
async function prepareForLiquify(targetObj) {
  if (!props.liquifyManager || !targetObj) return;

  targetObject.value = targetObj;

  // 获取图层信息
  const layerId = targetObj.layerId || props.canvas.activeLayerId?.value;
  targetLayerId.value = layerId;

  try {
    // 初始化液化管理器
    await props.liquifyManager.initialize({
      canvas: props.canvas,
      layerManager: props.layerManager,
    });

    // 准备液化环境
    const result = await props.liquifyManager.prepareForLiquify(targetObj);

    if (result && result.originalImageData) {
      originalImageData.value = result.originalImageData;

      // 创建合成命令
      compositeCommand.value = new CompositeLiquifyCommand({
        canvas: props.canvas,
        targetObject: targetObject.value,
        targetLayerId: targetLayerId.value,
        originalData: originalImageData.value,
        layerManager: props.layerManager,
      });

      // 获取渲染模式信息
      renderMode.value = result.renderMode || "未知";
      const status =
        props.liquifyManager.getStatus?.() ||
        props.liquifyManager.enhancedManager?.getStatus?.() ||
        {};
      webglAvailable.value = status.isWebGLAvailable || false;

      // 设置当前模式和参数
      if (props.liquifyManager.setMode) {
        props.liquifyManager.setMode(currentMode.value);
      }
      updateAllParams();

      console.log("液化环境准备完成");
    }
  } catch (error) {
    console.error("准备液化环境失败:", error);
  }
}

// 生命周期 - mounted
onMounted(() => {
  // 生命周期 - created的逻辑
  // 监听显示事件
  document.addEventListener("showLiquifyPanel", showPanel);

  // 监听画布事件
  setupCanvasListeners();
});

// 生命周期 - beforeUnmount
onUnmounted(() => {
  document.removeEventListener("showLiquifyPanel", showPanel);
  removeCanvasListeners();
});

// 方法定义
/**
 * 显示液化面板
 */
function showPanel(event) {
  console.log("接收到showLiquifyPanel事件", event.detail);
  console.log(props);
  // 检查当前工具是否是液化工具 - 只在必要时进行检查
  if (props.activeTool !== OperationType.LIQUIFY) {
    console.log(
      "当前工具不是液化工具，不显示面板。当前工具:",
      props.activeTool,
      "期望工具:",
      OperationType.LIQUIFY
    );
    return;
  }

  // 获取从事件传入的详情数据
  const detail = event.detail || {};

  // 检查是否包含必要的液化信息
  if (!detail.canLiquify && !detail.targetObject) {
    if (detail.layerStatus && detail.layerStatus.message) {
      console.log("液化操作提示:", detail.layerStatus.message);
    } else {
      console.log("未选择有效图像或图层不适合液化操作");
    }
    visible.value = true; // 仍然显示面板以便用户看到提示
    return;
  }

  // 从事件中获取目标对象和图层信息
  const targetObj = detail.targetObject;
  const targetLayerIdValue = detail.activeLayerId || detail.targetLayerId;
  const originalImageDataValue = detail.originalImageData;

  // 确保有可用的目标对象
  if (!targetObj) {
    console.log("未选择有效的图像对象");
    visible.value = true; // 仍然显示面板以便显示提示
    return;
  }

  console.log(
    "显示液化面板，目标对象:",
    targetObj.type,
    "图层ID:",
    targetLayerIdValue
  );

  // 更新面板状态，但保持当前模式不变
  // 只有在首次显示面板或面板已关闭时才重置模式
  if (!visible.value) {
    currentMode.value = "push"; // 默认模式
    resetParams();
  }

  targetObject.value = targetObj;
  targetLayerId.value = targetLayerIdValue;

  // 处理originalImageData
  // 如果提供了新的图像数据，使用新的；否则保留现有的（如果有）
  if (originalImageDataValue) {
    originalImageData.value = originalImageDataValue;
    console.log(
      "收到原始图像数据，尺寸:",
      originalImageDataValue.width,
      "x",
      originalImageDataValue.height
    );
  }

  // 创建或更新合成命令
  if (!compositeCommand.value || !isEditing.value) {
    compositeCommand.value = new CompositeLiquifyCommand({
      canvas: props.canvas,
      targetObject: targetObject.value,
      targetLayerId: targetLayerId.value,
      originalData: originalImageData.value,
      layerManager: props.layerManager,
    });
  }

  visible.value = true;
  isEditing.value = true;

  // 初始化液化管理器并准备液化环境
  if (props.liquifyManager && targetObject.value) {
    // 确保液化管理器正确初始化
    props.liquifyManager.initialize({
      canvas: props.canvas,
      layerManager: props.layerManager,
    });

    // 如果没有原始图像数据，则需要先准备液化环境
    if (!originalImageData.value) {
      // 准备液化环境并获取原始图像数据
      props.liquifyManager
        .prepareForLiquify(targetObject.value)
        .then((result) => {
          if (result && result.originalImageData) {
            originalImageData.value = result.originalImageData;
            console.log(
              "准备液化环境，获取原始图像数据成功:",
              originalImageData.value.width,
              "x",
              originalImageData.value.height
            );

            // 获取渲染模式信息
            renderMode.value = result.renderMode || "未知";
            const status = props.liquifyManager.getStatus
              ? props.liquifyManager.getStatus()
              : props.liquifyManager.enhancedManager
              ? props.liquifyManager.enhancedManager.getStatus()
              : {};

            webglAvailable.value = status.isWebGLAvailable || false;

            // 更新合成命令的原始数据
            if (compositeCommand.value) {
              compositeCommand.value.originalData = originalImageData.value;
            }

            // 立即设置当前模式
            if (currentMode.value && props.liquifyManager.setMode) {
              props.liquifyManager.setMode(currentMode.value);
            }

            // 设置当前参数
            updateAllParams();
          }
        })
        .catch((err) => {
          console.error("准备液化环境失败:", err);
        });
    } else {
      // 已有原始图像数据，直接准备环境
      props.liquifyManager
        .prepareForLiquify(targetObject.value)
        .then((result) => {
          if (result) {
            // 获取渲染模式信息
            renderMode.value = result.renderMode || "未知";

            const status = props.liquifyManager.getStatus
              ? props.liquifyManager.getStatus()
              : props.liquifyManager.enhancedManager
              ? props.liquifyManager.enhancedManager.getStatus()
              : {};

            webglAvailable.value = status.isWebGLAvailable || false;

            // 立即设置当前模式
            if (currentMode.value && props.liquifyManager.setMode) {
              props.liquifyManager.setMode(currentMode.value);
            }

            // 设置当前参数
            updateAllParams();
          }
        });
    }
  }
}

// 更新所有参数到液化管理器
function updateAllParams() {
  if (!props.liquifyManager) return;

  updateParam("size", size.value);
  updateParam("pressure", pressure.value / 100);
  updateParam("distortion", distortion.value / 100);
  updateParam("power", power.value / 100);
}

/**
 * 设置画布事件监听
 */
function setupCanvasListeners() {
  if (!props.canvas) return;

  _handleMouseDown = handleMouseDown;
  _handleMouseMove = handleMouseMove;
  _handleMouseUp = handleMouseUp;

  props.canvas.on("mouse:down", _handleMouseDown);
  props.canvas.on("mouse:move", _handleMouseMove);
  props.canvas.on("mouse:up", _handleMouseUp);
}

/**
 * 移除画布事件监听
 */
function removeCanvasListeners() {
  if (!props.canvas) return;

  props.canvas.off("mouse:down", _handleMouseDown);
  props.canvas.off("mouse:move", _handleMouseMove);
  props.canvas.off("mouse:up", _handleMouseUp);

  _handleMouseDown = null;
  _handleMouseMove = null;
  _handleMouseUp = null;
}

/**
 * 鼠标按下事件处理
 */
function handleMouseDown(event) {
  if (!isEditing.value || !visible.value || !props.liquifyManager) return;

  isDrawing.value = true;

  const pointer = props.canvas.getPointer(event.e);

  // 记录起始点
  lastX.value = pointer.x;
  lastY.value = pointer.y;

  // 应用液化效果
  applyLiquifyAtPoint(pointer.x, pointer.y);
}

/**
 * 鼠标移动事件处理
 */
async function handleMouseMove(event) {
  if (!isEditing.value || !visible.value || !isDrawing.value) return;

  const pointer = props.canvas.getPointer(event.e);

  // 应用液化效果
  applyLiquifyAtPoint(pointer.x, pointer.y);

  // 更新坐标
  lastX.value = pointer.x;
  lastY.value = pointer.y;
}

/**
 * 鼠标抬起事件处理
 */
function handleMouseUp() {
  if (!isEditing.value || !visible.value) return;

  // 设置绘制状态为false，但不触发其他事件
  isDrawing.value = false;

  // 在这里不要触发其他可能导致重复初始化的事件
  console.log("鼠标抬起，结束液化变形操作");
}

/**
 * 在特定点应用液化效果
 */
async function applyLiquifyAtPoint(x, y) {
  if (!props.liquifyManager || !targetObject.value) {
    console.error("无法应用液化效果: 缺少liquifyManager或targetObject");
    return;
  }

  if (!originalImageData.value) {
    console.error("无法应用液化效果: 缺少原始图像数据");
    return;
  }

  try {
    // 将Fabric画布坐标转换为图像内部坐标
    const imageCoords = _convertFabricCoordsToImageCoords(x, y);

    if (!imageCoords) {
      console.warn("坐标转换失败，点击位置不在目标图像范围内");
      return;
    }

    console.log(
      "原始坐标:",
      x,
      y,
      "转换后图像坐标:",
      imageCoords.x,
      imageCoords.y
    );

    // 获取当前参数
    const params = {
      size: size.value,
      pressure: pressure.value / 100,
      distortion: distortion.value / 100,
      power: power.value / 100,
    };

    // 创建液化变形命令
    const deformCommand = createLiquifyDeformCommand({
      canvas: props.canvas,
      layerManager: props.layerManager,
      liquifyManager: props.liquifyManager,
      mode: currentMode.value,
      params: params,
      targetObject: targetObject.value,
      targetLayerId: targetLayerId.value,
      x: imageCoords.x, // 使用转换后的图像坐标
      y: imageCoords.y,
      originalData: originalImageData.value,
    });

    // 添加到合成命令
    if (compositeCommand.value) {
      compositeCommand.value.addCommand(deformCommand);
    }

    // 开始计时
    const startTime = performance.now();

    console.log(
      "应用液化变形，模式:",
      currentMode.value,
      "在图像坐标:",
      imageCoords.x,
      imageCoords.y
    );

    // 应用液化效果（实际执行变形）
    const resultData = await props.liquifyManager.applyLiquify(
      targetObject.value,
      currentMode.value,
      params,
      imageCoords.x, // 使用转换后的图像坐标
      imageCoords.y
    );
    // 关键修复：将变形结果应用到画布上的对象
    if (resultData) {
      await _updateCanvasObject(resultData);
    }

    // 计算操作耗时
    const endTime = performance.now();
    operationCount.value++;
    const operationTime = endTime - startTime;

    // 更新平均耗时 (指数移动平均)
    if (avgOperationTime.value === 0) {
      avgOperationTime.value = operationTime;
    } else {
      avgOperationTime.value =
        0.7 * avgOperationTime.value + 0.3 * operationTime;
    }

    // 检查渲染模式
    if (props.liquifyManager.getStatus) {
      const status = props.liquifyManager.getStatus();
      renderMode.value = status.renderMode || "未知";
      webglAvailable.value = status.isWebGLAvailable || false;
    } else if (
      props.liquifyManager.enhancedManager &&
      props.liquifyManager.enhancedManager.getStatus
    ) {
      const status = props.liquifyManager.enhancedManager.getStatus();
      renderMode.value = status.renderMode || "未知";
      webglAvailable.value = status.isWebGLAvailable || false;
    }
  } catch (error) {
    console.error("应用液化效果失败:", error);
  }
}

/**
 * 将变形后的ImageData更新到Canvas对象上
 * @param {ImageData} imageData 变形后的图像数据
 * @private
 */
async function _updateCanvasObject(imageData) {
  if (!imageData || !targetObject.value || !props.canvas) return;

  // 创建临时Canvas来渲染结果数据
  const tempCanvas = document.createElement("canvas");
  tempCanvas.width = imageData.width;
  tempCanvas.height = imageData.height;
  const tempCtx = tempCanvas.getContext("2d");
  tempCtx.putImageData(imageData, 0, 0);

  // 将Canvas转换为DataURL
  const dataURL = tempCanvas.toDataURL("png", 1);
  currImage.value = dataURL;

  // 创建新的fabric图像对象
  return new Promise((resolve) => {
    fabric.Image.fromURL(dataURL, (img) => {
      // 保留原对象的变换属性
      img.set({
        left: targetObject.value.left,
        top: targetObject.value.top,
        scaleX: targetObject.value.scaleX,
        scaleY: targetObject.value.scaleY,
        angle: targetObject.value.angle,
        flipX: targetObject.value.flipX,
        flipY: targetObject.value.flipY,
        opacity: targetObject.value.opacity,
        originX: targetObject.value.originX,
        originY: targetObject.value.originY,
        id: targetObject.value.id,
        name: targetObject.value.name,
        layerId: targetLayerId.value,
        selected: false,
        evented: false,
      });

      // 替换Canvas上的对象
      const allObjects = props.canvas?.getObjects?.();

      const index = allObjects.indexOf(targetObject.value);
      if (index !== -1) {
        props.canvas.remove(targetObject.value);
        props.canvas.insertAt(img, index);
        targetObject.value = img;

        // 更新图层引用
        const layer = props.layerManager.getLayerById(targetLayerId.value);
        if (layer) {
          if (layer.type === "background" || layer.isBackground) {
            layer.fabricObject = img;
          } else if (layer.fabricObjects) {
            const objIndex = layer.fabricObjects.findIndex(
              (obj) => obj.id === img.id
            );
            if (objIndex !== -1) {
              layer.fabricObjects[objIndex] = img;
            }
          }
        }
      } else {
        const fabricObject = allObjects.find(
          (fItem) => fItem.layerId === props.layerManager.getActiveLayerId()
        );
        targetObject.value = img;
        props.canvas.remove(fabricObject);
        props.canvas.add(img);
      }
      props.canvas.renderAll();
      resolve(img);
    });
  });
}

/**
 * 将Fabric画布坐标转换为图像内部坐标
 * @param {number} fabricX Fabric画布X坐标
 * @param {number} fabricY Fabric画布Y坐标
 * @returns {Object|null} 图像内部坐标 {x, y} 或 null（如果不在图像范围内）
 * @private
 */
function _convertFabricCoordsToImageCoords(fabricX, fabricY) {
  if (!targetObject.value || !originalImageData.value) {
    return null;
  }

  const obj = targetObject.value;

  // 创建变换矩阵（考虑对象的位置、缩放、旋转等）
  const transform = obj.calcTransformMatrix();

  // 将变换矩阵转换为fabric矩阵格式
  const matrix = fabric.util.invertTransform(transform);

  // 应用逆变换，将画布坐标转换为对象本地坐标
  const localPoint = fabric.util.transformPoint(
    new fabric.Point(fabricX, fabricY),
    matrix
  );

  // 获取图像的原始尺寸（未缩放前）
  const imageWidth = originalImageData.value.width;
  const imageHeight = originalImageData.value.height;

  // 获取对象的原始尺寸
  const objWidth = obj.width;
  const objHeight = obj.height;

  // 计算从对象坐标到图像像素坐标的缩放比例
  const scaleX = imageWidth / objWidth;
  const scaleY = imageHeight / objHeight;

  // 转换为图像像素坐标
  // 注意：Fabric对象坐标原点在中心，需要调整到左上角
  // 修复：检查对象是否有翻转，如果有flipX，则需要翻转X坐标
  let imageX = (localPoint.x + objWidth / 2) * scaleX;
  const imageY = (localPoint.y + objHeight / 2) * scaleY;

  // 处理图像翻转的情况
  if (obj.flipX) {
    imageX = imageWidth - imageX;
  }

  console.log(
    `坐标转换: Fabric(${fabricX}, ${fabricY}) -> 本地(${localPoint.x.toFixed(
      2
    )}, ${localPoint.y.toFixed(2)}) -> 图像(${imageX.toFixed(
      2
    )}, ${imageY.toFixed(2)}), flipX=${obj.flipX}`
  );

  // 检查坐标是否在图像范围内
  if (
    imageX < 0 ||
    imageX >= imageWidth ||
    imageY < 0 ||
    imageY >= imageHeight
  ) {
    return null;
  }

  return {
    x: Math.round(imageX),
    y: Math.round(imageY),
  };
}

/**
 * 选择液化模式
 */
function selectMode(modeId) {
  console.log("选择液化模式:", modeId);
  currentMode.value = modeId;

  // 为水晶和边缘模式设置默认失真值
  if (modeId === "crystal" || modeId === "edge") {
    if (distortion.value === 0) {
      distortion.value = 30; // 设置默认失真值为30%
      console.log("为", modeId, "模式设置默认失真值:", distortion.value);
    }
  }

  if (props.liquifyManager) {
    props.liquifyManager.setMode(modeId);
    console.log("液化管理器模式已设置为:", modeId);

    // 立即更新所有参数，确保失真参数正确传递
    updateAllParams();
  }

  // 如果是重建模式，重置为原始状态
  if (modeId === "reconstruct") {
    resetToOriginal();
  }
}

/**
 * 重置为原始状态
 */
function resetToOriginal() {
  if (!props.liquifyManager || !originalImageData.value || !targetObject.value)
    return;

  // 创建重置命令
  const resetCommand = createLiquifyResetCommand({
    canvas: props.canvas,
    layerManager: props.layerManager,
    targetObject: targetObject.value,
    targetLayerId: targetLayerId.value,
    originalImageData: originalImageData.value,
  });

  // 执行重置
  props.commandManager.execute(resetCommand);

  // 重新初始化液化环境
  props.liquifyManager.prepareForLiquify(targetObject.value);

  // 创建新的合成命令
  compositeCommand.value = new CompositeLiquifyCommand({
    canvas: props.canvas,
    targetObject: targetObject.value,
    targetLayerId: targetLayerId.value,
    originalData: originalImageData.value,
    layerManager: props.layerManager,
  });
}

/**
 * 更新参数
 */
function updateParam(name, value) {
  if (props.liquifyManager) {
    props.liquifyManager.setParam(name, value);
  }
}

/**
 * 重置参数为默认值
 */
function resetParams() {
  size.value = 50;
  pressure.value = 50;
  distortion.value = 0;
  power.value = 50;

  if (props.liquifyManager) {
    props.liquifyManager.resetParams();
  }
}

/**
 * 取消液化操作
 */
function cancel() {
  // 还原为原始状态
  resetToOriginal();

  // 关闭面板
  close();
}

/**
 * 确认液化操作
 */
async function confirm() {
  try {
    // 如果有合成命令，执行它
    if (
      compositeCommand.value &&
      compositeCommand.value.commands &&
      compositeCommand.value.commands.length > 0
    ) {
      // 提交命令到命令管理器
      await props.commandManager.execute(compositeCommand.value);
    }

    // 关闭面板
    close();
  } catch (error) {
    console.error("确认液化操作失败:", error);
    alert("保存液化效果失败: " + error.message);
  }
}

/**
 * 关闭面板
 */
function close() {
  debugger;
  visible.value = false;
  isEditing.value = false;
  targetObject.value = null;
  targetLayerId.value = null;
  compositeCommand.value = null;

  // 重置性能统计
  operationCount.value = 0;
  avgOperationTime.value = 0;

  // 释放液化管理器资源
  if (props.liquifyManager) {
    props.liquifyManager.dispose();
  }
}
</script>

<style scoped>
.liquify-panel {
  position: absolute;
  bottom: 22px;
  left: 20px;
  right: 20px;
  max-width: min(90vw, 640px);
  margin: 0 auto;
  background-color: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(15px);
  -webkit-backdrop-filter: blur(15px);
  border-radius: 8px;
  box-shadow: 0 -4px 20px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  color: #333;
  border: 1px solid rgba(0, 0, 0, 0.05);
}

.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s, transform 0.3s;
}
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
  transform: translateY(30px);
}

.currImage {
  position: fixed;
  right: -319px;
  bottom: 0;
  width: 244px;
  height: auto;
  min-height: 32px;
  object-fit: cover;
  border-radius: 4px;
  margin-left: 4px;
  background-color: red;
  display: block;
}

/* 平板和手机适配 */
@media screen and (max-width: 768px) {
  .liquify-panel {
    bottom: 15px;
    left: 15px;
    right: 15px;
    max-width: calc(100vw - 30px);
    border-radius: 6px;
  }
}

@media screen and (max-width: 480px) {
  .liquify-panel {
    bottom: 10px;
    left: 10px;
    right: 10px;
    max-width: calc(100vw - 20px);
  }
}

/* .liquify-panel.is-active {
  transform: translateY(0);
} */

.liquify-panel-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 6px 10px;
  border-bottom: 1px solid rgba(0, 0, 0, 0.05);
  background-color: rgba(255, 255, 255, 0.8);
  border-radius: 8px 8px 0 0;
}

.header-title {
  font-size: 13px;
  font-weight: 500;
  color: #333;
}

.header-btn {
  background: none;
  border: none;
  color: #333;
  font-size: 12px;
  cursor: pointer;
  padding: 3px 6px;
  border-radius: 3px;
  transition: background-color 0.2s ease;
  min-width: 32px;
}

.header-btn:hover {
  background-color: rgba(0, 0, 0, 0.05);
}

.header-actions {
  display: flex;
  gap: 6px;
}

.cancel-btn {
  color: #666;
}

.confirm-btn {
  color: #4285f4;
  font-weight: 500;
}

.liquify-panel-content {
  padding: 8px 10px 10px;
}

.liquify-modes {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(42px, 1fr));
  gap: 4px;
  margin-bottom: 8px;
}

/* 平板适配：最多6列 */
@media screen and (max-width: 768px) {
  .liquify-modes {
    grid-template-columns: repeat(6, 1fr);
    gap: 3px;
  }

  .liquify-panel-header {
    padding: 5px 8px;
    border-radius: 6px 6px 0 0;
  }

  .liquify-panel-content {
    padding: 6px 8px 8px;
  }
}

/* 手机适配：最多4列 */
@media screen and (max-width: 480px) {
  .liquify-modes {
    grid-template-columns: repeat(4, 1fr);
    gap: 2px;
  }

  .header-title {
    font-size: 12px;
  }

  .header-btn {
    font-size: 11px;
    padding: 2px 4px;
    min-width: 28px;
  }
}

.mode-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  cursor: pointer;
  padding: 4px 2px;
  border-radius: 4px;
  transition: all 0.2s ease;
  min-height: 48px;
}

.mode-item:hover {
  background-color: rgba(0, 0, 0, 0.05);
}

.mode-item.active {
  background-color: rgba(66, 133, 244, 0.1);
}

.mode-icon {
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 16px;
  margin-bottom: 2px;
  color: #555;
}

.mode-item.active .mode-icon {
  color: #4285f4;
}

.mode-name {
  font-size: 9px;
  color: #333;
  text-align: center;
  line-height: 1.1;
  word-wrap: break-word;
  max-width: 100%;
}

/* 平板适配 */
@media screen and (max-width: 768px) {
  .mode-item {
    padding: 3px 1px;
    min-height: 44px;
  }

  .mode-icon {
    width: 22px;
    height: 22px;
    font-size: 15px;
  }

  .mode-name {
    font-size: 8px;
  }
}

/* 手机适配 */
@media screen and (max-width: 480px) {
  .mode-item {
    padding: 2px 1px;
    min-height: 40px;
  }

  .mode-icon {
    width: 20px;
    height: 20px;
    font-size: 14px;
  }

  .mode-name {
    font-size: 7px;
  }
}

.liquify-divider {
  height: 1px;
  background-color: rgba(0, 0, 0, 0.05);
  margin: 6px 0 8px;
}

.liquify-params {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: 12px;
  align-items: start;
}

.param-item {
  margin-bottom: 0;
}

.param-label {
  font-size: 11px;
  margin-bottom: 6px;
  color: #666;
  font-weight: 500;
}

.param-control {
  display: flex;
  align-items: center;
  gap: 8px;
}

.slider-control {
  flex: 1;
  height: 3px;
  background: rgba(0, 0, 0, 0.1);
  border-radius: 2px;
  -webkit-appearance: none;
  appearance: none;
  min-width: 60px;
}

.slider-control::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: #4285f4;
  cursor: pointer;
}

.param-value {
  font-size: 10px;
  width: 32px;
  text-align: right;
  color: #333;
  font-weight: 500;
}

/* 平板适配 */
@media screen and (max-width: 768px) {
  .liquify-params {
    grid-template-columns: repeat(2, 1fr);
    gap: 10px;
  }

  .liquify-divider {
    margin: 5px 0 6px;
  }

  .param-label {
    font-size: 10px;
    margin-bottom: 5px;
  }

  .param-control {
    gap: 6px;
  }

  .param-value {
    font-size: 9px;
    width: 28px;
  }

  .slider-control {
    height: 2px;
    min-width: 50px;
  }

  .slider-control::-webkit-slider-thumb {
    width: 8px;
    height: 8px;
  }
}

/* 手机适配 */
@media screen and (max-width: 480px) {
  .liquify-params {
    grid-template-columns: 1fr;
    gap: 8px;
  }
}

/* 不同模式的图标样式 */
.mode-push::before {
  content: "↔";
}

.mode-clockwise::before {
  content: "↻";
}

.mode-counterclockwise::before {
  content: "↺";
}

.mode-pinch::before {
  content: "⤢";
}

.mode-expand::before {
  content: "⤡";
}

.mode-crystal::before {
  content: "✧";
}

.mode-edge::before {
  content: "◈";
}

.mode-reconstruct::before {
  content: "↩";
}

/* 调试信息区域 */
.debug-info {
  margin-top: 12px;
  padding: 8px;
  background-color: rgba(0, 0, 0, 0.03);
  border-radius: 4px;
  font-size: 10px;
  color: #666;
}

.debug-header {
  font-weight: 500;
  margin-bottom: 4px;
  font-size: 10px;
  color: #444;
}

.debug-item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 2px;
}

.debug-item span {
  color: #4285f4;
  font-weight: 500;
}
</style>
