const require_objectSpread2 = require("../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
//#region src/components/pisellFloorMapLayout/utils/alignSnap.ts
function getSelfEdgesX(rect) {
	return [
		{
			edge: "left",
			value: rect.left
		},
		{
			edge: "centerX",
			value: rect.left + rect.width / 2
		},
		{
			edge: "right",
			value: rect.left + rect.width
		}
	];
}
function getSelfEdgesY(rect) {
	return [
		{
			edge: "top",
			value: rect.top
		},
		{
			edge: "centerY",
			value: rect.top + rect.height / 2
		},
		{
			edge: "bottom",
			value: rect.top + rect.height
		}
	];
}
function getOtherEdgesX(rect) {
	return getSelfEdgesX(rect);
}
function getOtherEdgesY(rect) {
	return getSelfEdgesY(rect);
}
/**
* 对一个 rect 做边对齐吸附。返回 snap 后的 rect + 实际命中的辅助线（0~2 条）。
*
* 算法：对 x、y 轴独立处理；每轴在所有「自身 3 边 × 所有 other 3 边」组合
* 中选距离最小且 < threshold 的一对，把自身整体平移让它们贴齐；同时记录
* 所有「平移后仍精确贴齐」的参考线（可能不止 1 条，例如 left 和 centerX
* 同时与他人对齐时只有 1 条平移量但 2 条 guide）。
*/
function snapRectToOthers(rect, others, options) {
	var _dx$delta, _dy$delta;
	const threshold = Math.max(0, options.threshold);
	if (threshold <= 0 || others.length === 0) return {
		rect: stripId(rect),
		guides: []
	};
	/** 1) 找最优偏移 dx / dy */
	const dx = findBestDelta(getSelfEdgesX(rect), others.flatMap((o) => getOtherEdgesX(o).map((e) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, e), {}, { ownerId: o.id }))), threshold, options.mode === "resize" ? options.movableEdgesX : void 0);
	const dy = findBestDelta(getSelfEdgesY(rect), others.flatMap((o) => getOtherEdgesY(o).map((e) => require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({}, e), {}, { ownerId: o.id }))), threshold, options.mode === "resize" ? options.movableEdgesY : void 0);
	/** 2) 根据 mode 把 dx/dy 应用到 rect（drag: 平移；resize: 只动可动边）*/
	const snapped = applyDelta(rect, (_dx$delta = dx === null || dx === void 0 ? void 0 : dx.delta) !== null && _dx$delta !== void 0 ? _dx$delta : 0, (_dy$delta = dy === null || dy === void 0 ? void 0 : dy.delta) !== null && _dy$delta !== void 0 ? _dy$delta : 0, options);
	/** 3) 重新计算所有边坐标，列出与 other 边精确相等的 guide（不限 1 条） */
	const guides = [];
	if (dx) {
		for (const self of getSelfEdgesX(snapped)) for (const o of others) for (const oe of getOtherEdgesX(o)) if (self.value === oe.value) {
			const top = Math.min(snapped.top, o.top);
			const bottom = Math.max(snapped.top + snapped.height, o.top + o.height);
			guides.push({
				orientation: "v",
				position: self.value,
				start: top,
				end: bottom,
				selfEdge: self.edge,
				otherEdge: oe.edge,
				otherId: o.id
			});
		}
	}
	if (dy) {
		for (const self of getSelfEdgesY(snapped)) for (const o of others) for (const oe of getOtherEdgesY(o)) if (self.value === oe.value) {
			const left = Math.min(snapped.left, o.left);
			const right = Math.max(snapped.left + snapped.width, o.left + o.width);
			guides.push({
				orientation: "h",
				position: self.value,
				start: left,
				end: right,
				selfEdge: self.edge,
				otherEdge: oe.edge,
				otherId: o.id
			});
		}
	}
	return {
		rect: snapped,
		guides
	};
}
/** 在所有 self×other 组合中选距离最小且 < threshold 的一组 */
function findBestDelta(selfEdges, otherEdges, threshold, movableFilter) {
	let best = null;
	for (const self of selfEdges) {
		/** resize 模式下：「centerX/centerY 不可动；left/right/top/bottom 必须在 movable 列表里」 */
		if (movableFilter) {
			if (self.edge === "centerX" || self.edge === "centerY") continue;
			if (!movableFilter.includes(self.edge)) continue;
		}
		for (const o of otherEdges) {
			const dist = o.value - self.value;
			const ad = Math.abs(dist);
			if (ad > threshold) continue;
			if (!best || ad < best.absDist) best = {
				delta: dist,
				absDist: ad
			};
		}
	}
	return best ? { delta: best.delta } : null;
}
function applyDelta(rect, dx, dy, options) {
	var _options$movableEdges, _options$movableEdges2;
	if (options.mode === "drag") return {
		left: rect.left + dx,
		top: rect.top + dy,
		width: rect.width,
		height: rect.height
	};
	/** resize：根据可动边把 dx/dy 应用到该边 */
	let { left, top, width, height } = rect;
	const right = left + width;
	const bottom = top + height;
	const mx = (_options$movableEdges = options.movableEdgesX) !== null && _options$movableEdges !== void 0 ? _options$movableEdges : [];
	const my = (_options$movableEdges2 = options.movableEdgesY) !== null && _options$movableEdges2 !== void 0 ? _options$movableEdges2 : [];
	let newLeft = left;
	let newRight = right;
	let newTop = top;
	let newBottom = bottom;
	if (dx !== 0) {
		if (mx.includes("left")) newLeft = left + dx;
		else if (mx.includes("right")) newRight = right + dx;
	}
	if (dy !== 0) {
		if (my.includes("top")) newTop = top + dy;
		else if (my.includes("bottom")) newBottom = bottom + dy;
	}
	/** 保证 width/height >= 1，否则忽略该轴 snap */
	if (newRight - newLeft < 1) {
		newLeft = left;
		newRight = right;
	}
	if (newBottom - newTop < 1) {
		newTop = top;
		newBottom = bottom;
	}
	return {
		left: newLeft,
		top: newTop,
		width: newRight - newLeft,
		height: newBottom - newTop
	};
}
function stripId(rect) {
	return {
		left: rect.left,
		top: rect.top,
		width: rect.width,
		height: rect.height
	};
}
//#endregion
exports.snapRectToOthers = snapRectToOthers;
