/**
 * useDragConstraints
 *
 * Constraint helpers for drag operations — snap-to-grid,
 * boundary clamping, alignment guides.
 *
 * Extracted from useNodeDrag.ts in v1.6.0.
 *
 * @since 1.6.0
 */

import type { NodePosition } from '../core/types';

// --- Types ---

export interface DragConstraintOptions {
	/** Grid size for snap-to-grid (0 = disabled) */
	gridSize?: number;
	/** Bounds to clamp position within */
	bounds?: {
		minX: number;
		minY: number;
		maxX: number;
		maxY: number;
	};
}

// --- Functions ---

/**
 * Snap a position to a grid.
 */
export function snapToGrid(pos: NodePosition, gridSize: number): NodePosition {
	if (gridSize <= 0) return pos;
	return {
		x: Math.round(pos.x / gridSize) * gridSize,
		y: Math.round(pos.y / gridSize) * gridSize,
	};
}

/**
 * Clamp a position within bounds.
 */
export function clampToBounds(
	pos: NodePosition,
	bounds: { minX: number; minY: number; maxX: number; maxY: number },
): NodePosition {
	return {
		x: Math.max(bounds.minX, Math.min(bounds.maxX, pos.x)),
		y: Math.max(bounds.minY, Math.min(bounds.maxY, pos.y)),
	};
}

/**
 * Apply all drag constraints to a position.
 */
export function applyDragConstraints(
	pos: NodePosition,
	options: DragConstraintOptions = {},
): NodePosition {
	let result = pos;
	if (options.gridSize && options.gridSize > 0) {
		result = snapToGrid(result, options.gridSize);
	}
	if (options.bounds) {
		result = clampToBounds(result, options.bounds);
	}
	return result;
}
