/**
 * Minimap Utilities
 *
 * Pure computation functions for the Minimap component:
 * graph bounds, coordinate transforms, world conversion.
 *
 * Extracted from Minimap.tsx in v1.7.0.
 *
 * @since 1.7.0
 */

// --- Types ---

export interface NodeLike {
	position: { x: number; y: number };
	width?: number;
	height?: number;
}

export interface GraphBounds {
	minX: number;
	minY: number;
	maxX: number;
	maxY: number;
}

export interface MinimapTransform {
	scale: number;
	offsetX: number;
	offsetY: number;
	minX: number;
	minY: number;
}

// --- Functions ---

/**
 * Compute the bounding box of all nodes.
 * Returns null for empty node arrays.
 */
export function computeGraphBounds(nodes: NodeLike[]): GraphBounds | null {
	if (nodes.length === 0) return null;

	let minX = Infinity;
	let minY = Infinity;
	let maxX = -Infinity;
	let maxY = -Infinity;

	for (const node of nodes) {
		const x = node.position.x;
		const y = node.position.y;
		const w = node.width ?? 200;
		const h = node.height ?? 100;

		if (x < minX) minX = x;
		if (y < minY) minY = y;
		if (x + w > maxX) maxX = x + w;
		if (y + h > maxY) maxY = y + h;
	}

	return { minX, minY, maxX, maxY };
}

/**
 * Compute the transform from graph world coordinates to minimap pixel coordinates.
 */
export function getMinimapTransform(
	bounds: GraphBounds,
	minimapWidth: number,
	minimapHeight: number,
	padding: number = 20,
): MinimapTransform | null {
	const graphW = bounds.maxX - bounds.minX;
	const graphH = bounds.maxY - bounds.minY;
	if (graphW <= 0 || graphH <= 0) return null;

	const scaleX = (minimapWidth - padding * 2) / graphW;
	const scaleY = (minimapHeight - padding * 2) / graphH;
	const scale = Math.min(scaleX, scaleY);

	const offsetX = padding + ((minimapWidth - padding * 2) - graphW * scale) / 2;
	const offsetY = padding + ((minimapHeight - padding * 2) - graphH * scale) / 2;

	return { scale, offsetX, offsetY, minX: bounds.minX, minY: bounds.minY };
}

/**
 * Convert minimap pixel coordinates to world coordinates.
 */
export function minimapToWorld(
	mx: number,
	my: number,
	transform: MinimapTransform,
): { x: number; y: number } {
	return {
		x: (mx - transform.offsetX) / transform.scale + transform.minX,
		y: (my - transform.offsetY) / transform.scale + transform.minY,
	};
}
