const require_runtime = require("../../../_virtual/_rolldown/runtime.js");
const require_objectSpread2 = require("../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js");
let react = require("react");
react = require_runtime.__toESM(react);
let classnames = require("classnames");
classnames = require_runtime.__toESM(classnames);
require("./ItemLayer.less");
//#region src/components/pisellFloorMapLayout/components/ItemLayer.tsx
/**
* ItemLayer - 楼层图展示层
* 按 items 的 (x, y) 与 cellSize 定位，用 renderItem 渲染每项内容
*/
const PREFIX = "pisell-floor-map-layout";
/** 图元内可滚动区标记（如预约房间卡 body / multi-list），与 private-materials 约定一致 */
const ROOM_SCROLL_SURFACE_SELECTOR = "[data-pisell-floor-room-scroll-surface]";
/** 与 EditableItemLayer `SELECTED_ITEM_STACK_Z` 一致：阅读态选中时抬升，避免邻桌图形盖住描边 */
const READ_MODE_SELECTED_STACK_Z = 1e6;
function getItemKey(item, index, rowKey) {
	var _rowKey;
	if (!rowKey) return item.id;
	if (typeof rowKey === "string") return String((_rowKey = item[rowKey]) !== null && _rowKey !== void 0 ? _rowKey : item.id);
	return rowKey(item, index);
}
/**
* 根据形状返回 item 容器的 style（clip-path / border-radius）
*/
function getShapeStyle(shape = "rect") {
	switch (shape) {
		case "circle": return { borderRadius: "50%" };
		case "triangle": return { clipPath: "polygon(50% 0%, 0% 100%, 100% 100%)" };
		case "polygon":
		case "custom": return {};
		default: return {};
	}
}
function ItemLayer(props) {
	const { items, renderItem, viewportScale, rowKey, cellSize, itemUnit = "cell", itemGap = 0, contentWidth, contentHeight, contentOffsetX = 0, contentOffsetY = 0, enableHover = true, itemHoverOutline = true, onItemClick, onItemHover, onItemLeave, getMergedItemWrapperStyle, onInteractionChange, readModeSelectedItemId, className } = props;
	/** 触控/指针在房间卡滚动区内按下时禁用画布 pan，松手恢复 */
	const notifyRoomScrollSurfaceActive = (0, react.useCallback)(() => {
		if (!onInteractionChange) return;
		onInteractionChange(true);
		const finish = () => {
			onInteractionChange(false);
		};
		window.addEventListener("pointerup", finish, { once: true });
		window.addEventListener("pointercancel", finish, { once: true });
		window.addEventListener("touchend", finish, {
			once: true,
			passive: true
		});
		window.addEventListener("touchcancel", finish, {
			once: true,
			passive: true
		});
	}, [onInteractionChange]);
	/**
	* 只对触屏指针拦截画布 pan：触屏在卡内纵向滑动时会和画布 pan 抢事件，
	* 这里把 `isInteractingWithElement` 拉起来让 TransformWrapper 关掉 panning，
	* 让原生 scroll 接管列表。
	*
	* 鼠标 / 触控笔（pen）不走这条路径——桌面端鼠标要可以从任意图元上按下并直接拖动画布，
	* 否则用户会发现「只有空白处才能拖动画布」（react-zoom-pan-pinch 的鼠标 pan 走的是
	* window 的 mousedown 监听，但 panning.disabled=true 一样会让它直接拒绝启动）。
	*
	* 触屏 e.button 默认为 0，不再前置 `e.button !== 0` 早返；鼠标右键此时已被 pointerType 过滤掉。
	*/
	const handleItemPointerDownCapture = (0, react.useCallback)((e) => {
		var _el$closest;
		if (!onInteractionChange) return;
		if (e.pointerType !== "touch") return;
		const el = e.target;
		if (!(el === null || el === void 0 || (_el$closest = el.closest) === null || _el$closest === void 0 ? void 0 : _el$closest.call(el, ROOM_SCROLL_SURFACE_SELECTOR))) return;
		notifyRoomScrollSurfaceActive();
	}, [onInteractionChange, notifyRoomScrollSurfaceActive]);
	const handleItemTouchStartCapture = (0, react.useCallback)((e) => {
		var _el$closest2;
		if (!onInteractionChange) return;
		const el = e.target;
		if (!(el === null || el === void 0 || (_el$closest2 = el.closest) === null || _el$closest2 === void 0 ? void 0 : _el$closest2.call(el, ROOM_SCROLL_SURFACE_SELECTOR))) return;
		notifyRoomScrollSurfaceActive();
	}, [onInteractionChange, notifyRoomScrollSurfaceActive]);
	(0, react.useEffect)(() => {
		return () => {
			onInteractionChange === null || onInteractionChange === void 0 || onInteractionChange(false);
		};
	}, [onInteractionChange]);
	const itemNodes = (0, react.useMemo)(() => {
		const isPixel = itemUnit === "pixel";
		const g = itemGap;
		const sorted = [...items].sort((a, b) => {
			var _a$zIndex, _b$zIndex;
			return ((_a$zIndex = a.zIndex) !== null && _a$zIndex !== void 0 ? _a$zIndex : 0) - ((_b$zIndex = b.zIndex) !== null && _b$zIndex !== void 0 ? _b$zIndex : 0);
		});
		const renderOpts = viewportScale != null && Number.isFinite(viewportScale) && viewportScale > 0 ? { viewportScale } : void 0;
		return sorted.map((item, index) => {
			var _item$zIndex, _item$zIndex2;
			let left;
			let top;
			let width;
			let height;
			if (isPixel) {
				var _item$width, _item$height;
				width = (_item$width = item.width) !== null && _item$width !== void 0 ? _item$width : cellSize;
				height = (_item$height = item.height) !== null && _item$height !== void 0 ? _item$height : cellSize;
				left = item.x;
				top = item.y;
			} else {
				var _item$width2, _item$height2;
				const w = (_item$width2 = item.width) !== null && _item$width2 !== void 0 ? _item$width2 : 1;
				const h = (_item$height2 = item.height) !== null && _item$height2 !== void 0 ? _item$height2 : 1;
				left = g > 0 ? item.x * (cellSize + g) + g : item.x * cellSize;
				top = g > 0 ? item.y * (cellSize + g) + g : item.y * cellSize;
				width = g > 0 ? w * cellSize + (w - 1) * g : w * cellSize;
				height = g > 0 ? h * cellSize + (h - 1) * g : h * cellSize;
			}
			const key = getItemKey(item, index, rowKey);
			const shapeStyle = getShapeStyle(item.shape);
			const selectedRead = readModeSelectedItemId != null && String(readModeSelectedItemId).trim() !== "" && key === String(readModeSelectedItemId);
			return /* @__PURE__ */ react.default.createElement("div", {
				key,
				className: (0, classnames.default)(`${PREFIX}-item`, {
					[`${PREFIX}-item-hoverable`]: enableHover,
					[`${PREFIX}-item-hover-outline`]: enableHover && itemHoverOutline,
					[`${PREFIX}-item-read-selected`]: selectedRead
				}),
				style: require_objectSpread2._objectSpread2(require_objectSpread2._objectSpread2({
					position: "absolute",
					left,
					top,
					width,
					height,
					boxSizing: "border-box",
					zIndex: selectedRead ? READ_MODE_SELECTED_STACK_Z + ((_item$zIndex = item.zIndex) !== null && _item$zIndex !== void 0 ? _item$zIndex : 0) : (_item$zIndex2 = item.zIndex) !== null && _item$zIndex2 !== void 0 ? _item$zIndex2 : 0,
					pointerEvents: "auto"
				}, shapeStyle), getMergedItemWrapperStyle === null || getMergedItemWrapperStyle === void 0 ? void 0 : getMergedItemWrapperStyle(item, index)),
				onClick: (e) => onItemClick === null || onItemClick === void 0 ? void 0 : onItemClick(item, index, e),
				onMouseEnter: (e) => onItemHover === null || onItemHover === void 0 ? void 0 : onItemHover(item, index, e),
				onMouseLeave: (e) => onItemLeave === null || onItemLeave === void 0 ? void 0 : onItemLeave(item, index, e),
				onPointerDownCapture: handleItemPointerDownCapture,
				onTouchStartCapture: handleItemTouchStartCapture
			}, renderItem(item, index, renderOpts));
		});
	}, [
		items,
		renderItem,
		viewportScale,
		rowKey,
		cellSize,
		itemUnit,
		itemGap,
		enableHover,
		itemHoverOutline,
		onItemClick,
		onItemHover,
		onItemLeave,
		getMergedItemWrapperStyle,
		handleItemPointerDownCapture,
		handleItemTouchStartCapture,
		readModeSelectedItemId
	]);
	return /* @__PURE__ */ react.default.createElement("div", {
		className: (0, classnames.default)(`${PREFIX}-item-layer`, className),
		style: {
			position: "absolute",
			left: 0,
			top: 0,
			width: contentWidth,
			height: contentHeight,
			minWidth: contentWidth,
			minHeight: contentHeight
		}
	}, contentOffsetX !== 0 || contentOffsetY !== 0 ? /* @__PURE__ */ react.default.createElement("div", { style: {
		position: "absolute",
		left: 0,
		top: 0,
		width: contentWidth,
		height: contentHeight,
		transform: `translate(${contentOffsetX}px, ${contentOffsetY}px)`,
		pointerEvents: "none"
	} }, itemNodes) : itemNodes);
}
//#endregion
exports.default = ItemLayer;
