import { _objectSpread2 } from "../../../_virtual/_@oxc-project_runtime@0.122.0/helpers/objectSpread2.js";
import { FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND, FLOOR_MAP_IMAGE_ELEMENT_KIND, FLOOR_MAP_STAGE_ELEMENT_KIND } from "../types.js";
import { FLOOR_MAP_BUILTIN_SHAPES } from "../utils/floorMapBuiltinShapes.js";
import { FLOOR_MAP_RESOURCE_PLACE_DEFAULT, isDirectPlacePaletteKind, resolveDataBindingPolicy } from "../utils/floorMapElementKindUtils.js";
import { FLOOR_MAP_PALETTE_DRAG_MIME } from "../utils/floorMapDropUtils.js";
import { FLOOR_MAP_LAYOUT_CLASS_PREFIX, FLOOR_MAP_PHONE_TOOLBAR_DRAWER_Z_INDEX } from "../floorMapLayoutConstants.js";
import { buildToolbarPaletteEntries, getPaletteSidebarVisibleEntries, shouldShowPaletteViewAll } from "../utils/floorMapToolbarPalette.js";
import FloorMapToolbarViewAllModal from "./FloorMapToolbarViewAllModal.js";
import React, { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { locales } from "@pisell/utils";
import { Drawer, message } from "antd";
import { LeftOutlined, RightOutlined } from "@ant-design/icons";
import classNames from "classnames";
import "./FloorMapToolbar.less";
//#region src/components/pisellFloorMapLayout/components/FloorMapToolbar.tsx
/**
* FloorMapToolbar - 编辑态左侧侧边栏：按分类添加图元、绑定数据源与行；保存可选（默认用顶栏）
*/
const I18N_TB = "pisell-floor-map-layout.toolbar";
/** 绑定类图元：解析默认数据源 key（allowedDataSourceKeys 与 dataSources 交集的首项） */
function resolveBindingDataSourceKey(kind, dataSources) {
	var _kind$allowedDataSour;
	const allKeys = Object.keys(dataSources !== null && dataSources !== void 0 ? dataSources : {});
	return (((_kind$allowedDataSour = kind.allowedDataSourceKeys) === null || _kind$allowedDataSour === void 0 ? void 0 : _kind$allowedDataSour.length) ? kind.allowedDataSourceKeys.filter((x) => allKeys.includes(x)) : allKeys)[0];
}
const DEFAULT_PLACEMENT_SIZE = FLOOR_MAP_RESOURCE_PLACE_DEFAULT;
const DEFAULT_DECORATION_SIZE = 48;
/**
* 侧栏 palette 预览：按 cell 尺寸 contain 缩放，以 cell 中心为锚点。
* 与 `.toolbar-preview-content` 的 `left/top: 50%` 配合，避免 flex 居中与
* transform 叠算导致预览贴角。
*/
function getToolbarPreviewScaledStyle(cellW, cellH, contentW, contentH) {
	return {
		width: contentW,
		height: contentH,
		transform: `translate(-50%, -50%) scale(${Math.min(cellW / contentW, cellH / contentH)})`,
		transformOrigin: "center center"
	};
}
function getUnplacedRecordsForKey(dataSourceKey, dataSources, elements) {
	var _dataSources$dataSour;
	const used = new Set(elements.filter((e) => {
		var _e$dataBinding;
		return ((_e$dataBinding = e.dataBinding) === null || _e$dataBinding === void 0 ? void 0 : _e$dataBinding.dataSourceKey) === dataSourceKey;
	}).map((e) => e.dataBinding.recordId));
	return ((_dataSources$dataSour = dataSources[dataSourceKey]) !== null && _dataSources$dataSour !== void 0 ? _dataSources$dataSour : []).filter((r) => r && typeof r.id === "string" && !used.has(r.id));
}
function buildScenePreviewMergedItem(kind, dataSourceKey, size, builtinShapeKey) {
	var _FLOOR_MAP_BUILTIN_SH;
	const el = _objectSpread2(_objectSpread2({
		instanceId: `preview_${kind.value}`,
		canvasId: "",
		x: 0,
		y: 0,
		width: size.width,
		height: size.height,
		elementKind: kind.value,
		shape: kind.defaultShape,
		dataBinding: dataSourceKey && resolveDataBindingPolicy(kind) !== "none" ? {
			dataSourceKey,
			recordId: ""
		} : void 0
	}, kind.value === "floorMapImage" ? { imageUrl: "" } : {}), kind.value === "floorMapBuiltinShape" ? { builtinShapeKey: builtinShapeKey !== null && builtinShapeKey !== void 0 ? builtinShapeKey : (_FLOOR_MAP_BUILTIN_SH = FLOOR_MAP_BUILTIN_SHAPES[0]) === null || _FLOOR_MAP_BUILTIN_SH === void 0 ? void 0 : _FLOOR_MAP_BUILTIN_SH.key } : {});
	return {
		id: el.instanceId,
		instanceId: el.instanceId,
		x: 0,
		y: 0,
		width: size.width,
		height: size.height,
		shape: kind.defaultShape,
		elementKind: kind.value,
		_sceneElement: el
	};
}
const STAGE_PREVIEW_SIZE = {
	width: 160,
	height: 64
};
const IMAGE_PREVIEW_SIZE = {
	width: 140,
	height: 80
};
/** 内置图形预览：略小于图片，正方形便于 5 种图形（厕所/柱子/沙发/大门/分隔）通用展示 */
const BUILTIN_SHAPE_PREVIEW_SIZE = {
	width: 96,
	height: 96
};
/** 侧栏 palette 预览 cell 基准尺寸（再乘 {@link SIDEBAR_PALETTE_PREVIEW_SCALE}） */
const PALETTE_PREVIEW_CELL_BASE = {
	stage: {
		w: 92,
		h: 40
	},
	placement: {
		w: 80,
		h: 54
	}
};
/** 侧栏缩略图相对历史尺寸：现为原先一半（stage 46×20、placement 40×27、装饰 24×24） */
const SIDEBAR_PALETTE_PREVIEW_SCALE = .5;
/** 「查看全部」弹窗内预览与侧栏同尺寸（相对历史全尺寸仍为 0.5） */
const MODAL_PALETTE_PREVIEW_SCALE_RELATIVE_TO_SIDEBAR = 1;
function resolvePalettePreviewScale(modal) {
	return modal ? SIDEBAR_PALETTE_PREVIEW_SCALE * MODAL_PALETTE_PREVIEW_SCALE_RELATIVE_TO_SIDEBAR : SIDEBAR_PALETTE_PREVIEW_SCALE;
}
function scalePalettePreviewCell(n, modal) {
	return Math.max(8, Math.round(n * resolvePalettePreviewScale(modal)));
}
/** 侧栏 / 弹窗 palette 预览区外框尺寸 */
function getPalettePreviewCellSize(options) {
	const { isStage, placementLike, decorationPreviewSize, modal = false } = options;
	const baseW = isStage ? PALETTE_PREVIEW_CELL_BASE.stage.w : placementLike ? PALETTE_PREVIEW_CELL_BASE.placement.w : decorationPreviewSize;
	const baseH = isStage ? PALETTE_PREVIEW_CELL_BASE.stage.h : placementLike ? PALETTE_PREVIEW_CELL_BASE.placement.h : decorationPreviewSize;
	return {
		cellW: scalePalettePreviewCell(baseW, modal),
		cellH: scalePalettePreviewCell(baseH, modal)
	};
}
function FloorMapToolbar(props) {
	var _resourcePickerCtx$mo;
	const { config, dataSources, dataSourceLabels = {}, canCreate, placeMode, onPlaceModeChange, renderPreviewItem, placementPreviewSize = DEFAULT_PLACEMENT_SIZE, decorationPreviewSize = DEFAULT_DECORATION_SIZE, sceneElements = [], onSave, saving, saveError, layoutDirty, className, onPaletteCardPointerDown, consumeToolbarClickIfTouchDrag, phoneLayout = false, defaultCollapsed = false, onRequestPlaceAtCanvasCenter, paletteSidebarVisibleLimit, onBulkAddPaletteToCanvas, renderPaletteViewAllModal, onDirectPlacePaletteItem, onResourcePickerConfirmPlace, renderResourcePickerModal } = props;
	/**
	* 侧栏收起 / 展开：仅会话内状态，**不写入 localStorage**。
	* 桌面默认展开；手机编辑态可由 `defaultCollapsed` 默认收起。
	*/
	const [collapsed, setCollapsed] = useState(() => defaultCollapsed === true);
	/** 当前打开的「查看全部」弹窗所属分类（任意分类超过展示上限时触发） */
	const [viewAllModal, setViewAllModal] = useState(null);
	/** 新建绑定类图元：在弹窗内选择数据行（替代侧栏 Select 多选） */
	const [resourcePickerOpen, setResourcePickerOpen] = useState(false);
	const [resourcePickerCtx, setResourcePickerCtx] = useState(null);
	const handleToggleCollapsed = useCallback(() => {
		setCollapsed((prev) => !prev);
	}, []);
	const paletteKinds = useMemo(() => {
		var _config$elementKinds;
		return ((_config$elementKinds = config.elementKinds) !== null && _config$elementKinds !== void 0 ? _config$elementKinds : []).filter((k) => k.showInPalette !== false);
	}, [config.elementKinds]);
	const categories = useMemo(() => {
		var _config$elementKindCa;
		const sorted = [...(_config$elementKindCa = config.elementKindCategories) !== null && _config$elementKindCa !== void 0 ? _config$elementKindCa : []].sort((a, b) => {
			var _a$order, _b$order;
			return ((_a$order = a.order) !== null && _a$order !== void 0 ? _a$order : 0) - ((_b$order = b.order) !== null && _b$order !== void 0 ? _b$order : 0);
		});
		return sorted.length ? sorted : [{
			id: "_uncat",
			label: locales.getText(`${I18N_TB}.category-fallback`),
			order: 0
		}];
	}, [config.elementKindCategories]);
	const kindsByCategory = useMemo(() => {
		var _categories$0$id, _categories$;
		const map = /* @__PURE__ */ new Map();
		for (const c of categories) map.set(c.id, []);
		const fallbackId = (_categories$0$id = (_categories$ = categories[0]) === null || _categories$ === void 0 ? void 0 : _categories$.id) !== null && _categories$0$id !== void 0 ? _categories$0$id : "_uncat";
		for (const k of paletteKinds) {
			var _k$categoryId;
			const cid = (_k$categoryId = k.categoryId) !== null && _k$categoryId !== void 0 ? _k$categoryId : fallbackId;
			if (!map.has(cid)) map.set(cid, []);
			map.get(cid).push(k);
		}
		return map;
	}, [categories, paletteKinds]);
	const paletteEntriesByCategory = useMemo(() => {
		const map = /* @__PURE__ */ new Map();
		for (const c of categories) {
			var _kindsByCategory$get;
			const kinds = (_kindsByCategory$get = kindsByCategory.get(c.id)) !== null && _kindsByCategory$get !== void 0 ? _kindsByCategory$get : [];
			map.set(c.id, buildToolbarPaletteEntries(kinds, (shapeDef) => locales.getText(shapeDef.labelKey)));
		}
		return map;
	}, [categories, kindsByCategory]);
	/**
	* 手机模式下，「点 palette 卡片 → 落画布 / 打开资源选择 modal」一类「新增到画布」
	* 流程触发后，主动收起 toolbar drawer，避免抽屉遮挡画布或新弹出的 modal。
	* 取消 / 切换选中态等流程不调用此方法。
	*/
	const collapseToolbarOnPhone = useCallback(() => {
		if (phoneLayout) setCollapsed(true);
	}, [phoneLayout]);
	const directPlacePaletteItem = (item) => {
		onDirectPlacePaletteItem === null || onDirectPlacePaletteItem === void 0 || onDirectPlacePaletteItem(item);
		onPlaceModeChange(null);
		collapseToolbarOnPhone();
	};
	const cancelPlaceMode = () => {
		onPlaceModeChange(null);
		setResourcePickerOpen(false);
		setResourcePickerCtx(null);
	};
	/**
	* 绑定类图元：自动选定数据源并打开资源筛选弹窗（不再在侧栏先选单选项数据源）。
	*/
	const openResourcePickerForBindingKind = useCallback((kind, carryMode) => {
		const key = resolveBindingDataSourceKey(kind, dataSources);
		if (!key) {
			message.warning(locales.getText(`${I18N_TB}.no-data-sources`));
			setResourcePickerOpen(false);
			setResourcePickerCtx(null);
			return;
		}
		const unplaced = getUnplacedRecordsForKey(key, dataSources, sceneElements);
		const sameKind = (carryMode === null || carryMode === void 0 ? void 0 : carryMode.elementKind) === kind.value ? carryMode : void 0;
		const mode = {
			type: "scene",
			elementKind: kind.value,
			dataSourceKey: key,
			recordId: sameKind === null || sameKind === void 0 ? void 0 : sameKind.recordId,
			recordIds: sameKind === null || sameKind === void 0 ? void 0 : sameKind.recordIds
		};
		onPlaceModeChange(mode);
		setResourcePickerCtx({
			mode,
			dataSourceKey: key,
			records: unplaced
		});
		setResourcePickerOpen(true);
		collapseToolbarOnPhone();
	}, [
		dataSources,
		sceneElements,
		onPlaceModeChange,
		collapseToolbarOnPhone
	]);
	const handleSelectKind = (kind) => {
		/** 装饰分类下无绑定项（如底图图片）：点击即落画布 */
		if (isDirectPlacePaletteKind(kind)) {
			setResourcePickerOpen(false);
			setResourcePickerCtx(null);
			directPlacePaletteItem({ elementKind: kind.value });
			return;
		}
		if ((placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" && placeMode.elementKind === kind.value) {
			cancelPlaceMode();
			return;
		}
		openResourcePickerForBindingKind(kind, (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" ? placeMode : void 0);
	};
	/** 内置图形（厕所/分隔/柱子等）：点击即落画布，无需再点画布 */
	const handleSelectBuiltinShape = (kind, shapeKey) => {
		directPlacePaletteItem({
			elementKind: kind.value,
			builtinShapeKey: shapeKey
		});
	};
	const resourcePickerModalProps = resourcePickerOpen && resourcePickerCtx ? {
		open: true,
		records: resourcePickerCtx.records,
		mode: "multiple",
		value: ((_resourcePickerCtx$mo = resourcePickerCtx.mode.recordIds) === null || _resourcePickerCtx$mo === void 0 ? void 0 : _resourcePickerCtx$mo.length) ? resourcePickerCtx.mode.recordIds : resourcePickerCtx.mode.recordId ? [resourcePickerCtx.mode.recordId] : [],
		title: dataSourceLabels[resourcePickerCtx.dataSourceKey] ? locales.getText(`${I18N_TB}.select-with-label`).replace("{label}", dataSourceLabels[resourcePickerCtx.dataSourceKey]) : locales.getText(`${I18N_TB}.open-resource-picker`),
		onClose: cancelPlaceMode,
		onConfirm: (ids) => {
			var _ids$filter, _onResourcePickerConf;
			const list = (_ids$filter = ids === null || ids === void 0 ? void 0 : ids.filter(Boolean)) !== null && _ids$filter !== void 0 ? _ids$filter : [];
			if (list.length === 0) {
				message.warning(locales.getText(`${I18N_TB}.resource-picker-none-selected`));
				return;
			}
			const scene = _objectSpread2(_objectSpread2({}, resourcePickerCtx.mode), {}, {
				recordIds: list,
				recordId: void 0
			});
			setResourcePickerOpen(false);
			setResourcePickerCtx(null);
			if (!((_onResourcePickerConf = onResourcePickerConfirmPlace === null || onResourcePickerConfirmPlace === void 0 ? void 0 : onResourcePickerConfirmPlace(scene)) !== null && _onResourcePickerConf !== void 0 ? _onResourcePickerConf : false)) onPlaceModeChange(scene);
		}
	} : null;
	const resourcePickerModal = resourcePickerModalProps && renderResourcePickerModal ? renderResourcePickerModal(resourcePickerModalProps) : null;
	const warnedMissingResourcePickerRef = useRef(false);
	useEffect(() => {
		if (!resourcePickerModalProps || renderResourcePickerModal) return;
		if (warnedMissingResourcePickerRef.current) return;
		warnedMissingResourcePickerRef.current = true;
		/**
		* 通用基础 modal 已下线；业务侧需通过 `renderResourcePickerModal` 注入实现。
		*/
		if (typeof console !== "undefined") console.warn("[PisellFloorMapLayout] renderResourcePickerModal 未注入，资源选择弹窗不会渲染。");
	}, [resourcePickerModalProps, renderResourcePickerModal]);
	/**
	* 弹窗 / 侧栏缩略图：仅渲染预览 cell，不含落点控件。
	* 预览统一在 cell 内水平/垂直居中，避免细长图元贴左上角时视觉发"歪"。
	*/
	const renderPaletteEntryPreview = (entry) => {
		var _item$width, _item$height;
		const k = entry.kind;
		const policy = resolveDataBindingPolicy(k);
		const isStage = k.value === FLOOR_MAP_STAGE_ELEMENT_KIND;
		const isImageKind = k.value === FLOOR_MAP_IMAGE_ELEMENT_KIND;
		const isBuiltinShapeKind = k.value === FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND;
		const placementLike = policy !== "none" && !isStage || isImageKind || isBuiltinShapeKind;
		const size = entry.shapeDef ? entry.shapeDef.defaultSize : isStage ? STAGE_PREVIEW_SIZE : placementLike ? isImageKind ? IMAGE_PREVIEW_SIZE : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE : placementPreviewSize : {
			width: decorationPreviewSize,
			height: decorationPreviewSize
		};
		const item = buildScenePreviewMergedItem(k, void 0, {
			width: size.width,
			height: size.height
		}, entry.builtinShapeKey);
		const { cellW, cellH } = getPalettePreviewCellSize({
			isStage,
			placementLike,
			decorationPreviewSize,
			modal: true
		});
		const previewW = entry.shapeDef ? entry.shapeDef.defaultSize.width : isImageKind ? IMAGE_PREVIEW_SIZE.width : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE.width : placementPreviewSize.width;
		const previewH = entry.shapeDef ? entry.shapeDef.defaultSize.height : isImageKind ? IMAGE_PREVIEW_SIZE.height : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE.height : placementPreviewSize.height;
		const stageW = (_item$width = item.width) !== null && _item$width !== void 0 ? _item$width : cellW;
		const stageH = (_item$height = item.height) !== null && _item$height !== void 0 ? _item$height : cellH;
		const contentW = entry.shapeDef ? entry.shapeDef.defaultSize.width : isStage ? stageW : placementLike ? previewW : decorationPreviewSize;
		const contentH = entry.shapeDef ? entry.shapeDef.defaultSize.height : isStage ? stageH : placementLike ? previewH : decorationPreviewSize;
		return /* @__PURE__ */ React.createElement("div", {
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-cell`,
			style: {
				width: cellW,
				height: cellH
			}
		}, renderPreviewItem ? /* @__PURE__ */ React.createElement("div", {
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-content`,
			style: getToolbarPreviewScaledStyle(cellW, cellH, contentW, contentH)
		}, renderPreviewItem(item)) : /* @__PURE__ */ React.createElement("span", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-fallback` }, entry.label));
	};
	const viewAllModalPlatform = phoneLayout ? "h5" : "pc";
	const paletteViewAllModal = viewAllModal ? renderPaletteViewAllModal ? renderPaletteViewAllModal({
		open: true,
		categoryLabel: viewAllModal.categoryLabel,
		entries: viewAllModal.entries,
		onClose: () => setViewAllModal(null),
		onConfirm: (items) => {
			onBulkAddPaletteToCanvas === null || onBulkAddPaletteToCanvas === void 0 || onBulkAddPaletteToCanvas(items);
			collapseToolbarOnPhone();
		},
		renderEntryPreview: (entry) => renderPaletteEntryPreview(entry),
		platform: viewAllModalPlatform
	}) : /* @__PURE__ */ React.createElement(FloorMapToolbarViewAllModal, {
		open: true,
		categoryLabel: viewAllModal.categoryLabel,
		entries: viewAllModal.entries,
		onClose: () => setViewAllModal(null),
		onConfirm: (items) => {
			onBulkAddPaletteToCanvas === null || onBulkAddPaletteToCanvas === void 0 || onBulkAddPaletteToCanvas(items);
			collapseToolbarOnPhone();
		},
		renderEntryPreview: (entry) => renderPaletteEntryPreview(entry),
		platform: viewAllModalPlatform
	}) : null;
	/** 内置图形：每种预设单独一张 palette 卡，图标与名称直接展开 */
	const renderBuiltinShapePaletteCard = (kind, shapeDef) => {
		const shapeLabel = locales.getText(shapeDef.labelKey);
		const previewW = shapeDef.defaultSize.width;
		const previewH = shapeDef.defaultSize.height;
		const { cellW, cellH } = getPalettePreviewCellSize({
			isStage: false,
			placementLike: true,
			decorationPreviewSize
		});
		const item = buildScenePreviewMergedItem(kind, void 0, {
			width: previewW,
			height: previewH
		}, shapeDef.key);
		const paletteDragPayload = {
			elementKind: kind.value,
			builtinShapeKey: shapeDef.key
		};
		return /* @__PURE__ */ React.createElement("div", {
			key: `${kind.value}-${shapeDef.key}`,
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-card-wrap`
		}, /* @__PURE__ */ React.createElement("button", {
			type: "button",
			draggable: true,
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-card`,
			onClick: () => {
				if (consumeToolbarClickIfTouchDrag === null || consumeToolbarClickIfTouchDrag === void 0 ? void 0 : consumeToolbarClickIfTouchDrag()) return;
				handleSelectBuiltinShape(kind, shapeDef.key);
			},
			onPointerDown: (e) => onPaletteCardPointerDown === null || onPaletteCardPointerDown === void 0 ? void 0 : onPaletteCardPointerDown(paletteDragPayload, e),
			onDragStart: (e) => {
				e.dataTransfer.setData(FLOOR_MAP_PALETTE_DRAG_MIME, JSON.stringify(paletteDragPayload));
				e.dataTransfer.effectAllowed = "copy";
			},
			title: locales.getText(`${I18N_TB}.palette-card-title`).replace(/\{name\}/g, shapeLabel)
		}, /* @__PURE__ */ React.createElement("div", {
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-cell`,
			style: {
				width: cellW,
				height: cellH
			}
		}, renderPreviewItem ? /* @__PURE__ */ React.createElement("div", {
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-content`,
			style: getToolbarPreviewScaledStyle(cellW, cellH, previewW, previewH)
		}, renderPreviewItem(item)) : /* @__PURE__ */ React.createElement("span", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-fallback` }, shapeLabel)), /* @__PURE__ */ React.createElement("span", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-card-label` }, shapeLabel)));
	};
	const renderKindCard = (k) => {
		var _placeMode$builtinSha, _FLOOR_MAP_BUILTIN_SH2, _FLOOR_MAP_BUILTIN_SH3, _item$width2, _item$height2, _k$allowedDataSourceK, _FLOOR_MAP_BUILTIN_SH4;
		const policy = resolveDataBindingPolicy(k);
		const isStage = k.value === FLOOR_MAP_STAGE_ELEMENT_KIND;
		const isImageKind = k.value === FLOOR_MAP_IMAGE_ELEMENT_KIND;
		const isBuiltinShapeKind = k.value === FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND;
		/** 与图片图元同档：无数据绑定但展示一个完整视觉单体，按 placement 大卡片预览 */
		const placementLike = policy !== "none" && !isStage || isImageKind || isBuiltinShapeKind;
		const size = isStage ? STAGE_PREVIEW_SIZE : placementLike ? isImageKind ? IMAGE_PREVIEW_SIZE : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE : placementPreviewSize : {
			width: decorationPreviewSize,
			height: decorationPreviewSize
		};
		const activeDs = (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" && placeMode.elementKind === k.value ? placeMode.dataSourceKey : void 0;
		/**
		* 内置图形 kind：侧栏 Select 当前选中的图形 key。读 `placeMode.builtinShapeKey`，
		* 未选时回退枚举首项，让 palette 预览缩略图与 Select 默认值始终一致。
		*/
		const activeBuiltinShapeKey = isBuiltinShapeKind ? (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" && placeMode.elementKind === k.value ? (_placeMode$builtinSha = placeMode.builtinShapeKey) !== null && _placeMode$builtinSha !== void 0 ? _placeMode$builtinSha : (_FLOOR_MAP_BUILTIN_SH2 = FLOOR_MAP_BUILTIN_SHAPES[0]) === null || _FLOOR_MAP_BUILTIN_SH2 === void 0 ? void 0 : _FLOOR_MAP_BUILTIN_SH2.key : (_FLOOR_MAP_BUILTIN_SH3 = FLOOR_MAP_BUILTIN_SHAPES[0]) === null || _FLOOR_MAP_BUILTIN_SH3 === void 0 ? void 0 : _FLOOR_MAP_BUILTIN_SH3.key : void 0;
		const item = buildScenePreviewMergedItem(k, activeDs, size, activeBuiltinShapeKey);
		const isActive = (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" && placeMode.elementKind === k.value;
		/**
		* 预览缩略图尺寸：配合 sidebar 124px 抽屉；相对历史尺寸为一半。
		* stage 46×20、placement-like 40×27、装饰类 decorationPreviewSize×0.5（默认 24）。
		*/
		const { cellW, cellH } = getPalettePreviewCellSize({
			isStage,
			placementLike,
			decorationPreviewSize
		});
		const previewW = isImageKind ? IMAGE_PREVIEW_SIZE.width : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE.width : placementPreviewSize.width;
		const previewH = isImageKind ? IMAGE_PREVIEW_SIZE.height : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE.height : placementPreviewSize.height;
		const stageW = (_item$width2 = item.width) !== null && _item$width2 !== void 0 ? _item$width2 : cellW;
		const stageH = (_item$height2 = item.height) !== null && _item$height2 !== void 0 ? _item$height2 : cellH;
		const allKeys = Object.keys(dataSources);
		!((_k$allowedDataSourceK = k.allowedDataSourceKeys) === null || _k$allowedDataSourceK === void 0) && _k$allowedDataSourceK.length && k.allowedDataSourceKeys.filter((x) => allKeys.includes(x));
		const paletteDragPayload = _objectSpread2(_objectSpread2({ elementKind: k.value }, (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" && placeMode.elementKind === k.value ? _objectSpread2({ dataSourceKey: placeMode.dataSourceKey }, placeMode.recordIds && placeMode.recordIds.length > 0 ? { recordIds: placeMode.recordIds } : placeMode.recordId ? { recordId: placeMode.recordId } : {}) : {}), isBuiltinShapeKind ? { builtinShapeKey: activeBuiltinShapeKey !== null && activeBuiltinShapeKey !== void 0 ? activeBuiltinShapeKey : (_FLOOR_MAP_BUILTIN_SH4 = FLOOR_MAP_BUILTIN_SHAPES[0]) === null || _FLOOR_MAP_BUILTIN_SH4 === void 0 ? void 0 : _FLOOR_MAP_BUILTIN_SH4.key } : {});
		return /* @__PURE__ */ React.createElement("div", {
			key: k.value,
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-card-wrap`
		}, /* @__PURE__ */ React.createElement("button", {
			type: "button",
			draggable: true,
			className: classNames(`${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-card`, !placementLike ? `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-card-deco` : void 0, { [`${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-card-active`]: isActive }),
			onClick: () => {
				if (consumeToolbarClickIfTouchDrag === null || consumeToolbarClickIfTouchDrag === void 0 ? void 0 : consumeToolbarClickIfTouchDrag()) return;
				handleSelectKind(k);
			},
			onPointerDown: (e) => onPaletteCardPointerDown === null || onPaletteCardPointerDown === void 0 ? void 0 : onPaletteCardPointerDown(paletteDragPayload, e),
			onDragStart: (e) => {
				e.dataTransfer.setData(FLOOR_MAP_PALETTE_DRAG_MIME, JSON.stringify(paletteDragPayload));
				e.dataTransfer.effectAllowed = "copy";
			},
			title: locales.getText(`${I18N_TB}.palette-card-title`).replace(/\{name\}/g, k.label)
		}, /* @__PURE__ */ React.createElement("div", {
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-cell`,
			style: {
				width: cellW,
				height: cellH
			}
		}, renderPreviewItem ? /* @__PURE__ */ React.createElement("div", {
			className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-content`,
			style: getToolbarPreviewScaledStyle(cellW, cellH, isStage ? stageW : placementLike ? previewW : decorationPreviewSize, isStage ? stageH : placementLike ? previewH : decorationPreviewSize)
		}, renderPreviewItem(item)) : /* @__PURE__ */ React.createElement("span", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-fallback` }, k.label)), /* @__PURE__ */ React.createElement("span", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-preview-card-label` }, k.label)));
	};
	const collapseBtn = /* @__PURE__ */ React.createElement("button", {
		type: "button",
		className: classNames(`${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-collapse-handle`, phoneLayout && `pisell-floor-map-layout-toolbar-collapse-handle--in-drawer`),
		onClick: handleToggleCollapsed,
		"aria-label": collapsed ? locales.getText(`${I18N_TB}.expand`) : locales.getText(`${I18N_TB}.collapse`),
		title: collapsed ? locales.getText(`${I18N_TB}.expand`) : locales.getText(`${I18N_TB}.collapse`)
	}, collapsed ? /* @__PURE__ */ React.createElement(RightOutlined, null) : /* @__PURE__ */ React.createElement(LeftOutlined, null));
	/**
	* 内层容器：实际承载 body / footer，并在动画过程中负责水平裁剪。
	* 桌面：宽度跟随 sidebar（100%）伸缩；手机：antd Drawer 承载内容 + 边缘折叠柄。
	*/
	const toolbarInner = /* @__PURE__ */ React.createElement("div", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-inner` }, /* @__PURE__ */ React.createElement("div", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-body` }, canCreate && /* @__PURE__ */ React.createElement(React.Fragment, null, categories.map((cat) => {
		var _paletteEntriesByCate;
		const entries = (_paletteEntriesByCate = paletteEntriesByCategory.get(cat.id)) !== null && _paletteEntriesByCate !== void 0 ? _paletteEntriesByCate : [];
		if (!entries.length) return null;
		const visibleEntries = getPaletteSidebarVisibleEntries(entries, paletteSidebarVisibleLimit);
		const showViewAll = shouldShowPaletteViewAll(entries.length, paletteSidebarVisibleLimit);
		return /* @__PURE__ */ React.createElement("section", {
			key: cat.id,
			className: `pisell-floor-map-layout-toolbar-section`
		}, /* @__PURE__ */ React.createElement("h3", { className: `pisell-floor-map-layout-toolbar-section-title` }, cat.label), /* @__PURE__ */ React.createElement("div", { className: `pisell-floor-map-layout-toolbar-preview-list` }, /* @__PURE__ */ React.createElement("div", { className: `pisell-floor-map-layout-toolbar-preview-group` }, visibleEntries.map((entry) => entry.builtinShapeKey && entry.shapeDef ? renderBuiltinShapePaletteCard(entry.kind, entry.shapeDef) : renderKindCard(entry.kind)), showViewAll ? /* @__PURE__ */ React.createElement("button", {
			type: "button",
			className: `pisell-floor-map-layout-toolbar-view-all`,
			onClick: () => {
				setViewAllModal({
					categoryLabel: cat.label,
					entries
				});
				collapseToolbarOnPhone();
			}
		}, locales.getText(`${I18N_TB}.view-all`)) : null)));
	})), phoneLayout && onRequestPlaceAtCanvasCenter && (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === "scene" ? /* @__PURE__ */ React.createElement("div", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-section` }, /* @__PURE__ */ React.createElement("button", {
		type: "button",
		className: classNames(`${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-btn`, "primary"),
		onClick: () => {
			onRequestPlaceAtCanvasCenter();
			collapseToolbarOnPhone();
		}
	}, locales.getText(`${I18N_TB}.add-to-canvas`))) : null), onSave && config.canvasUi.canEdit && /* @__PURE__ */ React.createElement("div", { className: `pisell-floor-map-layout-toolbar-footer` }, layoutDirty ? /* @__PURE__ */ React.createElement("span", {
		className: `pisell-floor-map-layout-toolbar-dirty-hint`,
		role: "status"
	}, locales.getText(`${I18N_TB}.layout-dirty-hint`)) : null, saveError && /* @__PURE__ */ React.createElement("span", { className: `pisell-floor-map-layout-toolbar-error` }, typeof saveError === "string" ? saveError : saveError === null || saveError === void 0 ? void 0 : saveError.message), /* @__PURE__ */ React.createElement("button", {
		type: "button",
		className: classNames(`pisell-floor-map-layout-toolbar-btn`, "primary", { [`pisell-floor-map-layout-toolbar-save-dirty`]: layoutDirty }),
		disabled: saving,
		onClick: onSave
	}, saving ? locales.getText(`${I18N_TB}.saving`) : locales.getText(`${I18N_TB}.save`))));
	if (phoneLayout)
 /**
	* 必须包在 `${PREFIX}-toolbar` 根下，否则 Less 里 `.pisell-floor-map-layout-toolbar &-collapse-handle`
	* 等选择器无法命中，展开态右侧折叠柄会失去定位与样式。
	*/
	return /* @__PURE__ */ React.createElement("div", { className: classNames(`${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar`, className) }, paletteViewAllModal, resourcePickerModal, /* @__PURE__ */ React.createElement(Drawer, {
		placement: "left",
		open: !collapsed,
		onClose: () => setCollapsed(true),
		width: "min(320px, 88vw)",
		zIndex: FLOOR_MAP_PHONE_TOOLBAR_DRAWER_Z_INDEX,
		maskClosable: true,
		destroyOnClose: false,
		closable: false,
		forceRender: false,
		rootClassName: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-phone-drawer-root`,
		classNames: { body: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-phone-drawer-body` },
		styles: { body: {
			padding: 0,
			overflow: "visible",
			display: "flex",
			flexDirection: "column",
			height: "100%"
		} },
		getContainer: typeof document !== "undefined" ? () => document.body : void 0
	}, /* @__PURE__ */ React.createElement("div", { className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-phone-drawer-inner` }, toolbarInner, collapseBtn)), collapsed ? /* @__PURE__ */ React.createElement("button", {
		type: "button",
		className: `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-phone-peek-trigger`,
		onClick: () => setCollapsed(false),
		"aria-label": locales.getText(`${I18N_TB}.expand`),
		title: locales.getText(`${I18N_TB}.expand`)
	}, /* @__PURE__ */ React.createElement(RightOutlined, null)) : null);
	return /* @__PURE__ */ React.createElement("div", { className: classNames(`${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar`, `${FLOOR_MAP_LAYOUT_CLASS_PREFIX}-toolbar-sidebar`, collapsed && `pisell-floor-map-layout-toolbar-sidebar--collapsed`, className) }, paletteViewAllModal, resourcePickerModal, collapseBtn, toolbarInner);
}
//#endregion
export { FloorMapToolbar as default };
