import { getSmoothStepPath } from "../xyflow/react.js";
import { useMemo } from "react";
import { ARROW_OFFSETS, EDGE_CONSTANTS } from "../components/Edges/shared/constants.js";
import { GRID_SPACING } from "../constants.js";
import { snapToGrid } from "../utils/NodeUtils.js";
const LOOP_HEIGHT = 6 * GRID_SPACING;
const LOOP_SUCCESS_HEIGHT = 7 * GRID_SPACING;
const LOOP_RIGHT_EXTENSION = 3 * GRID_SPACING;
const LOOP_SUCCESS_RIGHT_EXTENSION = 4 * GRID_SPACING;
const LOOP_LEFT_EXTENSION = 2 * GRID_SPACING;
const LOOP_CORNER_RADIUS = GRID_SPACING;
const SOURCE_OFFSETS = ARROW_OFFSETS;
const createLoopPath = ({ sourceX, sourceY, sourcePosition, targetX, targetY, sourceHandleId })=>{
    const offsets = SOURCE_OFFSETS[sourcePosition];
    const sourceOffsetX = sourceX + offsets.x;
    const sourceOffsetY = sourceY + offsets.y;
    const loopHeight = 'success' === sourceHandleId ? LOOP_SUCCESS_HEIGHT : LOOP_HEIGHT;
    const bottomY = Math.max(sourceOffsetY, targetY) + loopHeight;
    const rightExtension = 'success' === sourceHandleId ? LOOP_SUCCESS_RIGHT_EXTENSION : LOOP_RIGHT_EXTENSION;
    const rightPoint = snapToGrid(sourceX + rightExtension);
    const leftPoint = snapToGrid(targetX - LOOP_LEFT_EXTENSION);
    const path = `
    M ${sourceOffsetX} ${sourceOffsetY}
    L ${rightPoint - LOOP_CORNER_RADIUS} ${sourceOffsetY}
    Q ${rightPoint} ${sourceOffsetY} ${rightPoint} ${sourceOffsetY + LOOP_CORNER_RADIUS}
    L ${rightPoint} ${bottomY - LOOP_CORNER_RADIUS}
    Q ${rightPoint} ${bottomY} ${rightPoint - LOOP_CORNER_RADIUS} ${bottomY}
    L ${leftPoint + LOOP_CORNER_RADIUS} ${bottomY}
    Q ${leftPoint} ${bottomY} ${leftPoint} ${bottomY - LOOP_CORNER_RADIUS}
    L ${leftPoint} ${targetY + LOOP_CORNER_RADIUS}
    Q ${leftPoint} ${targetY} ${leftPoint + LOOP_CORNER_RADIUS} ${targetY}
    L ${targetX} ${targetY}
  `.trim().replace(/\s+/g, ' ');
    return {
        path,
        loopHeight
    };
};
function useEdgePath({ sourceNodeId, sourceHandleId, sourceX, sourceY, sourcePosition, targetNodeId, targetHandleId, targetX, targetY, targetPosition }) {
    return useMemo(()=>{
        const isSelfLoop = sourceNodeId === targetNodeId;
        const isLoopBackEdge = 'loopBack' === targetHandleId;
        const needsCustomPath = isSelfLoop || isLoopBackEdge;
        let edgePath;
        let labelX;
        let labelY;
        if (needsCustomPath) {
            const { path, loopHeight } = createLoopPath({
                sourceX,
                sourceY,
                sourceNodeId,
                sourceHandleId,
                sourcePosition,
                targetNodeId,
                targetHandleId,
                targetX,
                targetY,
                targetPosition
            });
            edgePath = path;
            labelX = (sourceX + targetX) / 2;
            labelY = Math.max(sourceY, targetY) + loopHeight;
        } else {
            const { sourceOffsetX, sourceOffsetY } = {
                sourceOffsetX: sourceX + SOURCE_OFFSETS[sourcePosition].x,
                sourceOffsetY: sourceY + SOURCE_OFFSETS[sourcePosition].y
            };
            [edgePath, labelX, labelY] = getSmoothStepPath({
                sourceX: sourceOffsetX,
                sourceY: sourceOffsetY,
                sourcePosition,
                targetX,
                targetY,
                targetPosition,
                borderRadius: EDGE_CONSTANTS.BORDER_RADIUS
            });
        }
        return {
            edgePath,
            labelX,
            labelY,
            isLoopEdge: needsCustomPath
        };
    }, [
        sourceNodeId,
        targetNodeId,
        targetHandleId,
        sourceHandleId,
        sourceX,
        sourceY,
        targetX,
        targetY,
        sourcePosition,
        targetPosition
    ]);
}
export { useEdgePath };
