function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function (_e) { function e(_x) { return _e.apply(this, arguments); } e.toString = function () { return _e.toString(); }; return e; }(function (e) { throw e; }), f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function (_e2) { function e(_x2) { return _e2.apply(this, arguments); } e.toString = function () { return _e2.toString(); }; return e; }(function (e) { didErr = true; err = e; }), f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
/**
 * FloorMapToolbar - 编辑态左侧侧边栏：按分类添加图元、绑定数据源与行；保存可选（默认用顶栏）
 */
import React, { useMemo, useState, useCallback, useEffect, useRef } from 'react';
import classNames from 'classnames';
import { Drawer, message } from 'antd';
import { LeftOutlined, RightOutlined } from '@ant-design/icons';
import { FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND, FLOOR_MAP_IMAGE_ELEMENT_KIND, FLOOR_MAP_STAGE_ELEMENT_KIND } from "../types";
import { FLOOR_MAP_RESOURCE_PLACE_DEFAULT, isDirectPlacePaletteKind, resolveDataBindingPolicy } from "../utils/floorMapElementKindUtils";
import { FLOOR_MAP_BUILTIN_SHAPES } from "../utils/floorMapBuiltinShapes";
import { FLOOR_MAP_PALETTE_DRAG_MIME } from "../utils/floorMapDropUtils";
import { locales } from '@pisell/utils';
import { FLOOR_MAP_LAYOUT_CLASS_PREFIX as PREFIX, FLOOR_MAP_PHONE_TOOLBAR_DRAWER_Z_INDEX } from "../floorMapLayoutConstants";
import { buildToolbarPaletteEntries, getPaletteSidebarVisibleEntries, shouldShowPaletteViewAll } from "../utils/floorMapToolbarPalette";
import { FloorMapToolbarViewAllModal } from "./FloorMapToolbarViewAllModal";
import "./FloorMapToolbar.less";
var I18N_TB = 'pisell-floor-map-layout.toolbar';

/** 绑定类图元：解析默认数据源 key（allowedDataSourceKeys 与 dataSources 交集的首项） */
function resolveBindingDataSourceKey(kind, dataSources) {
  var _kind$allowedDataSour;
  var allKeys = Object.keys(dataSources !== null && dataSources !== void 0 ? dataSources : {});
  var allowed = (_kind$allowedDataSour = kind.allowedDataSourceKeys) !== null && _kind$allowedDataSour !== void 0 && _kind$allowedDataSour.length ? kind.allowedDataSourceKeys.filter(function (x) {
    return allKeys.includes(x);
  }) : allKeys;
  return allowed[0];
}
var DEFAULT_PLACEMENT_SIZE = FLOOR_MAP_RESOURCE_PLACE_DEFAULT;
var DEFAULT_DECORATION_SIZE = 48;

/**
 * 侧栏 palette 预览：按 cell 尺寸 contain 缩放，以 cell 中心为锚点。
 * 与 `.toolbar-preview-content` 的 `left/top: 50%` 配合，避免 flex 居中与
 * transform 叠算导致预览贴角。
 */
function getToolbarPreviewScaledStyle(cellW, cellH, contentW, contentH) {
  var scale = Math.min(cellW / contentW, cellH / contentH);
  return {
    width: contentW,
    height: contentH,
    transform: "translate(-50%, -50%) scale(".concat(scale, ")"),
    transformOrigin: 'center center'
  };
}
function getUnplacedRecordsForKey(dataSourceKey, dataSources, elements) {
  var _dataSources$dataSour;
  var used = new Set(elements.filter(function (e) {
    var _e$dataBinding;
    return ((_e$dataBinding = e.dataBinding) === null || _e$dataBinding === void 0 ? void 0 : _e$dataBinding.dataSourceKey) === dataSourceKey;
  }).map(function (e) {
    return e.dataBinding.recordId;
  }));
  var list = (_dataSources$dataSour = dataSources[dataSourceKey]) !== null && _dataSources$dataSour !== void 0 ? _dataSources$dataSour : [];
  return list.filter(function (r) {
    return r && typeof r.id === 'string' && !used.has(r.id);
  });
}
function buildScenePreviewMergedItem(kind, dataSourceKey, size, builtinShapeKey) {
  var _FLOOR_MAP_BUILTIN_SH;
  var el = _objectSpread(_objectSpread({
    instanceId: "preview_".concat(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: dataSourceKey,
      recordId: ''
    } : undefined
  }, kind.value === FLOOR_MAP_IMAGE_ELEMENT_KIND ? {
    imageUrl: ''
  } : {}), kind.value === FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND ? {
    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
  };
}
var STAGE_PREVIEW_SIZE = {
  width: 160,
  height: 64
};
var IMAGE_PREVIEW_SIZE = {
  width: 140,
  height: 80
};
/** 内置图形预览：略小于图片，正方形便于 5 种图形（厕所/柱子/沙发/大门/分隔）通用展示 */
var BUILTIN_SHAPE_PREVIEW_SIZE = {
  width: 96,
  height: 96
};

/** 侧栏 palette 预览 cell 基准尺寸（再乘 {@link SIDEBAR_PALETTE_PREVIEW_SCALE}） */
var PALETTE_PREVIEW_CELL_BASE = {
  stage: {
    w: 92,
    h: 40
  },
  placement: {
    w: 80,
    h: 54
  }
};

/** 侧栏缩略图相对历史尺寸：现为原先一半（stage 46×20、placement 40×27、装饰 24×24） */
var SIDEBAR_PALETTE_PREVIEW_SCALE = 0.5;

/** 「查看全部」弹窗内预览与侧栏同尺寸（相对历史全尺寸仍为 0.5） */
var 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) {
  var isStage = options.isStage,
    placementLike = options.placementLike,
    decorationPreviewSize = options.decorationPreviewSize,
    _options$modal = options.modal,
    modal = _options$modal === void 0 ? false : _options$modal;
  var baseW = isStage ? PALETTE_PREVIEW_CELL_BASE.stage.w : placementLike ? PALETTE_PREVIEW_CELL_BASE.placement.w : decorationPreviewSize;
  var 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)
  };
}
export function FloorMapToolbar(props) {
  var _resourcePickerCtx$mo;
  var config = props.config,
    dataSources = props.dataSources,
    _props$dataSourceLabe = props.dataSourceLabels,
    dataSourceLabels = _props$dataSourceLabe === void 0 ? {} : _props$dataSourceLabe,
    canCreate = props.canCreate,
    placeMode = props.placeMode,
    onPlaceModeChange = props.onPlaceModeChange,
    renderPreviewItem = props.renderPreviewItem,
    _props$placementPrevi = props.placementPreviewSize,
    placementPreviewSize = _props$placementPrevi === void 0 ? DEFAULT_PLACEMENT_SIZE : _props$placementPrevi,
    _props$decorationPrev = props.decorationPreviewSize,
    decorationPreviewSize = _props$decorationPrev === void 0 ? DEFAULT_DECORATION_SIZE : _props$decorationPrev,
    _props$sceneElements = props.sceneElements,
    sceneElements = _props$sceneElements === void 0 ? [] : _props$sceneElements,
    onSave = props.onSave,
    saving = props.saving,
    saveError = props.saveError,
    layoutDirty = props.layoutDirty,
    className = props.className,
    onPaletteCardPointerDown = props.onPaletteCardPointerDown,
    consumeToolbarClickIfTouchDrag = props.consumeToolbarClickIfTouchDrag,
    _props$phoneLayout = props.phoneLayout,
    phoneLayout = _props$phoneLayout === void 0 ? false : _props$phoneLayout,
    _props$defaultCollaps = props.defaultCollapsed,
    defaultCollapsed = _props$defaultCollaps === void 0 ? false : _props$defaultCollaps,
    onRequestPlaceAtCanvasCenter = props.onRequestPlaceAtCanvasCenter,
    paletteSidebarVisibleLimit = props.paletteSidebarVisibleLimit,
    onBulkAddPaletteToCanvas = props.onBulkAddPaletteToCanvas,
    renderPaletteViewAllModal = props.renderPaletteViewAllModal,
    onDirectPlacePaletteItem = props.onDirectPlacePaletteItem,
    onResourcePickerConfirmPlace = props.onResourcePickerConfirmPlace,
    renderResourcePickerModal = props.renderResourcePickerModal;

  /**
   * 侧栏收起 / 展开：仅会话内状态，**不写入 localStorage**。
   * 桌面默认展开；手机编辑态可由 `defaultCollapsed` 默认收起。
   */
  var _useState = useState(function () {
      return defaultCollapsed === true;
    }),
    _useState2 = _slicedToArray(_useState, 2),
    collapsed = _useState2[0],
    setCollapsed = _useState2[1];
  /** 当前打开的「查看全部」弹窗所属分类（任意分类超过展示上限时触发） */
  var _useState3 = useState(null),
    _useState4 = _slicedToArray(_useState3, 2),
    viewAllModal = _useState4[0],
    setViewAllModal = _useState4[1];
  /** 新建绑定类图元：在弹窗内选择数据行（替代侧栏 Select 多选） */
  var _useState5 = useState(false),
    _useState6 = _slicedToArray(_useState5, 2),
    resourcePickerOpen = _useState6[0],
    setResourcePickerOpen = _useState6[1];
  var _useState7 = useState(null),
    _useState8 = _slicedToArray(_useState7, 2),
    resourcePickerCtx = _useState8[0],
    setResourcePickerCtx = _useState8[1];
  var handleToggleCollapsed = useCallback(function () {
    setCollapsed(function (prev) {
      return !prev;
    });
  }, []);
  var paletteKinds = useMemo(function () {
    var _config$elementKinds;
    return ((_config$elementKinds = config.elementKinds) !== null && _config$elementKinds !== void 0 ? _config$elementKinds : []).filter(function (k) {
      return k.showInPalette !== false;
    });
  }, [config.elementKinds]);
  var categories = useMemo(function () {
    var _config$elementKindCa;
    var raw = (_config$elementKindCa = config.elementKindCategories) !== null && _config$elementKindCa !== void 0 ? _config$elementKindCa : [];
    var sorted = _toConsumableArray(raw).sort(function (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("".concat(I18N_TB, ".category-fallback")),
      order: 0
    }];
  }, [config.elementKindCategories]);
  var kindsByCategory = useMemo(function () {
    var _categories$0$id, _categories$;
    var map = new Map();
    var _iterator = _createForOfIteratorHelper(categories),
      _step;
    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var c = _step.value;
        map.set(c.id, []);
      }
    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }
    var 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';
    var _iterator2 = _createForOfIteratorHelper(paletteKinds),
      _step2;
    try {
      for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
        var _k$categoryId;
        var _k = _step2.value;
        var 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);
      }
    } catch (err) {
      _iterator2.e(err);
    } finally {
      _iterator2.f();
    }
    return map;
  }, [categories, paletteKinds]);
  var paletteEntriesByCategory = useMemo(function () {
    var map = new Map();
    var _iterator3 = _createForOfIteratorHelper(categories),
      _step3;
    try {
      for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
        var _kindsByCategory$get;
        var c = _step3.value;
        var kinds = (_kindsByCategory$get = kindsByCategory.get(c.id)) !== null && _kindsByCategory$get !== void 0 ? _kindsByCategory$get : [];
        map.set(c.id, buildToolbarPaletteEntries(kinds, function (shapeDef) {
          return locales.getText(shapeDef.labelKey);
        }));
      }
    } catch (err) {
      _iterator3.e(err);
    } finally {
      _iterator3.f();
    }
    return map;
  }, [categories, kindsByCategory]);

  /**
   * 手机模式下，「点 palette 卡片 → 落画布 / 打开资源选择 modal」一类「新增到画布」
   * 流程触发后，主动收起 toolbar drawer，避免抽屉遮挡画布或新弹出的 modal。
   * 取消 / 切换选中态等流程不调用此方法。
   */
  var collapseToolbarOnPhone = useCallback(function () {
    if (phoneLayout) setCollapsed(true);
  }, [phoneLayout]);
  var directPlacePaletteItem = function directPlacePaletteItem(item) {
    onDirectPlacePaletteItem === null || onDirectPlacePaletteItem === void 0 || onDirectPlacePaletteItem(item);
    onPlaceModeChange(null);
    collapseToolbarOnPhone();
  };
  var cancelPlaceMode = function cancelPlaceMode() {
    onPlaceModeChange(null);
    setResourcePickerOpen(false);
    setResourcePickerCtx(null);
  };

  /**
   * 绑定类图元：自动选定数据源并打开资源筛选弹窗（不再在侧栏先选单选项数据源）。
   */
  var openResourcePickerForBindingKind = useCallback(function (kind, carryMode) {
    var key = resolveBindingDataSourceKey(kind, dataSources);
    if (!key) {
      message.warning(locales.getText("".concat(I18N_TB, ".no-data-sources")));
      setResourcePickerOpen(false);
      setResourcePickerCtx(null);
      return;
    }
    var unplaced = getUnplacedRecordsForKey(key, dataSources, sceneElements);
    var sameKind = (carryMode === null || carryMode === void 0 ? void 0 : carryMode.elementKind) === kind.value ? carryMode : undefined;
    var 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: mode,
      dataSourceKey: key,
      records: unplaced
    });
    setResourcePickerOpen(true);
    collapseToolbarOnPhone();
  }, [dataSources, sceneElements, onPlaceModeChange, collapseToolbarOnPhone]);
  var handleSelectKind = function handleSelectKind(kind) {
    /** 装饰分类下无绑定项（如底图图片）：点击即落画布 */
    if (isDirectPlacePaletteKind(kind)) {
      setResourcePickerOpen(false);
      setResourcePickerCtx(null);
      directPlacePaletteItem({
        elementKind: kind.value
      });
      return;
    }
    var isSame = (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' && placeMode.elementKind === kind.value;
    if (isSame) {
      cancelPlaceMode();
      return;
    }
    var carry = (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' ? placeMode : undefined;
    openResourcePickerForBindingKind(kind, carry);
  };

  /** 内置图形（厕所/分隔/柱子等）：点击即落画布，无需再点画布 */
  var handleSelectBuiltinShape = function handleSelectBuiltinShape(kind, shapeKey) {
    directPlacePaletteItem({
      elementKind: kind.value,
      builtinShapeKey: shapeKey
    });
  };
  var resourcePickerModalProps = resourcePickerOpen && resourcePickerCtx ? {
    open: true,
    records: resourcePickerCtx.records,
    mode: 'multiple',
    value: (_resourcePickerCtx$mo = resourcePickerCtx.mode.recordIds) !== null && _resourcePickerCtx$mo !== void 0 && _resourcePickerCtx$mo.length ? resourcePickerCtx.mode.recordIds : resourcePickerCtx.mode.recordId ? [resourcePickerCtx.mode.recordId] : [],
    title: dataSourceLabels[resourcePickerCtx.dataSourceKey] ? locales.getText("".concat(I18N_TB, ".select-with-label")).replace('{label}', dataSourceLabels[resourcePickerCtx.dataSourceKey]) : locales.getText("".concat(I18N_TB, ".open-resource-picker")),
    onClose: cancelPlaceMode,
    onConfirm: function onConfirm(ids) {
      var _ids$filter, _onResourcePickerConf;
      var 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("".concat(I18N_TB, ".resource-picker-none-selected")));
        return;
      }
      var scene = _objectSpread(_objectSpread({}, resourcePickerCtx.mode), {}, {
        recordIds: list,
        recordId: undefined
      });
      setResourcePickerOpen(false);
      setResourcePickerCtx(null);
      var placed = (_onResourcePickerConf = onResourcePickerConfirmPlace === null || onResourcePickerConfirmPlace === void 0 ? void 0 : onResourcePickerConfirmPlace(scene)) !== null && _onResourcePickerConf !== void 0 ? _onResourcePickerConf : false;
      if (!placed) {
        onPlaceModeChange(scene);
      }
    }
  } : null;
  var resourcePickerModal = resourcePickerModalProps && renderResourcePickerModal ? renderResourcePickerModal(resourcePickerModalProps) : null;
  var warnedMissingResourcePickerRef = useRef(false);
  useEffect(function () {
    if (!resourcePickerModalProps || renderResourcePickerModal) {
      return;
    }
    if (warnedMissingResourcePickerRef.current) {
      return;
    }
    warnedMissingResourcePickerRef.current = true;
    /**
     * 通用基础 modal 已下线；业务侧需通过 `renderResourcePickerModal` 注入实现。
     */
    if (typeof console !== 'undefined') {
      // eslint-disable-next-line no-console
      console.warn('[PisellFloorMapLayout] renderResourcePickerModal 未注入，资源选择弹窗不会渲染。');
    }
  }, [resourcePickerModalProps, renderResourcePickerModal]);

  /**
   * 弹窗 / 侧栏缩略图：仅渲染预览 cell，不含落点控件。
   * 预览统一在 cell 内水平/垂直居中，避免细长图元贴左上角时视觉发"歪"。
   */
  var renderPaletteEntryPreview = function renderPaletteEntryPreview(entry) {
    var _item$width, _item$height;
    var k = entry.kind;
    var policy = resolveDataBindingPolicy(k);
    var isStage = k.value === FLOOR_MAP_STAGE_ELEMENT_KIND;
    var isImageKind = k.value === FLOOR_MAP_IMAGE_ELEMENT_KIND;
    var isBuiltinShapeKind = k.value === FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND;
    var placementLike = policy !== 'none' && !isStage || isImageKind || isBuiltinShapeKind;
    var 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
    };
    var item = buildScenePreviewMergedItem(k, undefined, {
      width: size.width,
      height: size.height
    }, entry.builtinShapeKey);
    var _getPalettePreviewCel = getPalettePreviewCellSize({
        isStage: isStage,
        placementLike: placementLike,
        decorationPreviewSize: decorationPreviewSize,
        /** renderPaletteEntryPreview 当前只用于 View All modal，固定走 modal 放大尺寸 */
        modal: true
      }),
      cellW = _getPalettePreviewCel.cellW,
      cellH = _getPalettePreviewCel.cellH;
    var previewW = entry.shapeDef ? entry.shapeDef.defaultSize.width : isImageKind ? IMAGE_PREVIEW_SIZE.width : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE.width : placementPreviewSize.width;
    var previewH = entry.shapeDef ? entry.shapeDef.defaultSize.height : isImageKind ? IMAGE_PREVIEW_SIZE.height : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE.height : placementPreviewSize.height;
    var stageW = (_item$width = item.width) !== null && _item$width !== void 0 ? _item$width : cellW;
    var stageH = (_item$height = item.height) !== null && _item$height !== void 0 ? _item$height : cellH;
    var contentW = entry.shapeDef ? entry.shapeDef.defaultSize.width : isStage ? stageW : placementLike ? previewW : decorationPreviewSize;
    var contentH = entry.shapeDef ? entry.shapeDef.defaultSize.height : isStage ? stageH : placementLike ? previewH : decorationPreviewSize;
    return /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-preview-cell"),
      style: {
        width: cellW,
        height: cellH
      }
    }, renderPreviewItem ? /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-preview-content"),
      style: getToolbarPreviewScaledStyle(cellW, cellH, contentW, contentH)
    }, renderPreviewItem(item)) : /*#__PURE__*/React.createElement("span", {
      className: "".concat(PREFIX, "-toolbar-preview-fallback")
    }, entry.label));
  };
  var viewAllModalPlatform = phoneLayout ? 'h5' : 'pc';
  var paletteViewAllModal = viewAllModal ? renderPaletteViewAllModal ? renderPaletteViewAllModal({
    open: true,
    categoryLabel: viewAllModal.categoryLabel,
    entries: viewAllModal.entries,
    onClose: function onClose() {
      return setViewAllModal(null);
    },
    onConfirm: function onConfirm(items) {
      onBulkAddPaletteToCanvas === null || onBulkAddPaletteToCanvas === void 0 || onBulkAddPaletteToCanvas(items);
      collapseToolbarOnPhone();
    },
    renderEntryPreview: function renderEntryPreview(entry) {
      return renderPaletteEntryPreview(entry);
    },
    platform: viewAllModalPlatform
  }) : /*#__PURE__*/React.createElement(FloorMapToolbarViewAllModal, {
    open: true,
    categoryLabel: viewAllModal.categoryLabel,
    entries: viewAllModal.entries,
    onClose: function onClose() {
      return setViewAllModal(null);
    },
    onConfirm: function onConfirm(items) {
      onBulkAddPaletteToCanvas === null || onBulkAddPaletteToCanvas === void 0 || onBulkAddPaletteToCanvas(items);
      collapseToolbarOnPhone();
    },
    renderEntryPreview: function renderEntryPreview(entry) {
      return renderPaletteEntryPreview(entry);
    },
    platform: viewAllModalPlatform
  }) : null;

  /** 内置图形：每种预设单独一张 palette 卡，图标与名称直接展开 */
  var renderBuiltinShapePaletteCard = function renderBuiltinShapePaletteCard(kind, shapeDef) {
    var shapeLabel = locales.getText(shapeDef.labelKey);
    var previewW = shapeDef.defaultSize.width;
    var previewH = shapeDef.defaultSize.height;
    var _getPalettePreviewCel2 = getPalettePreviewCellSize({
        isStage: false,
        placementLike: true,
        decorationPreviewSize: decorationPreviewSize
      }),
      cellW = _getPalettePreviewCel2.cellW,
      cellH = _getPalettePreviewCel2.cellH;
    var item = buildScenePreviewMergedItem(kind, undefined, {
      width: previewW,
      height: previewH
    }, shapeDef.key);
    var paletteDragPayload = {
      elementKind: kind.value,
      builtinShapeKey: shapeDef.key
    };
    return /*#__PURE__*/React.createElement("div", {
      key: "".concat(kind.value, "-").concat(shapeDef.key),
      className: "".concat(PREFIX, "-toolbar-preview-card-wrap")
    }, /*#__PURE__*/React.createElement("button", {
      type: "button",
      draggable: true,
      className: "".concat(PREFIX, "-toolbar-preview-card"),
      onClick: function onClick() {
        if (consumeToolbarClickIfTouchDrag !== null && consumeToolbarClickIfTouchDrag !== void 0 && consumeToolbarClickIfTouchDrag()) return;
        handleSelectBuiltinShape(kind, shapeDef.key);
      },
      onPointerDown: function onPointerDown(e) {
        return onPaletteCardPointerDown === null || onPaletteCardPointerDown === void 0 ? void 0 : onPaletteCardPointerDown(paletteDragPayload, e);
      },
      onDragStart: function onDragStart(e) {
        e.dataTransfer.setData(FLOOR_MAP_PALETTE_DRAG_MIME, JSON.stringify(paletteDragPayload));
        e.dataTransfer.effectAllowed = 'copy';
      },
      title: locales.getText("".concat(I18N_TB, ".palette-card-title")).replace(/\{name\}/g, shapeLabel)
    }, /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-preview-cell"),
      style: {
        width: cellW,
        height: cellH
      }
    }, renderPreviewItem ? /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-preview-content"),
      style: getToolbarPreviewScaledStyle(cellW, cellH, previewW, previewH)
    }, renderPreviewItem(item)) : /*#__PURE__*/React.createElement("span", {
      className: "".concat(PREFIX, "-toolbar-preview-fallback")
    }, shapeLabel)), /*#__PURE__*/React.createElement("span", {
      className: "".concat(PREFIX, "-toolbar-preview-card-label")
    }, shapeLabel)));
  };
  var renderKindCard = function renderKindCard(k) {
    var _placeMode$builtinSha, _FLOOR_MAP_BUILTIN_SH2, _FLOOR_MAP_BUILTIN_SH3, _item$width2, _item$height2, _k$allowedDataSourceK, _FLOOR_MAP_BUILTIN_SH4;
    var policy = resolveDataBindingPolicy(k);
    var isStage = k.value === FLOOR_MAP_STAGE_ELEMENT_KIND;
    var isImageKind = k.value === FLOOR_MAP_IMAGE_ELEMENT_KIND;
    var isBuiltinShapeKind = k.value === FLOOR_MAP_BUILTIN_SHAPE_ELEMENT_KIND;
    /** 与图片图元同档：无数据绑定但展示一个完整视觉单体，按 placement 大卡片预览 */
    var placementLike = policy !== 'none' && !isStage || isImageKind || isBuiltinShapeKind;
    var size = isStage ? STAGE_PREVIEW_SIZE : placementLike ? isImageKind ? IMAGE_PREVIEW_SIZE : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE : placementPreviewSize : {
      width: decorationPreviewSize,
      height: decorationPreviewSize
    };
    var activeDs = (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' && placeMode.elementKind === k.value ? placeMode.dataSourceKey : undefined;
    /**
     * 内置图形 kind：侧栏 Select 当前选中的图形 key。读 `placeMode.builtinShapeKey`，
     * 未选时回退枚举首项，让 palette 预览缩略图与 Select 默认值始终一致。
     */
    var 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 : undefined;
    var item = buildScenePreviewMergedItem(k, activeDs, size, activeBuiltinShapeKey);
    var 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）。
     */
    var _getPalettePreviewCel3 = getPalettePreviewCellSize({
        isStage: isStage,
        placementLike: placementLike,
        decorationPreviewSize: decorationPreviewSize
      }),
      cellW = _getPalettePreviewCel3.cellW,
      cellH = _getPalettePreviewCel3.cellH;
    var previewW = isImageKind ? IMAGE_PREVIEW_SIZE.width : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE.width : placementPreviewSize.width;
    var previewH = isImageKind ? IMAGE_PREVIEW_SIZE.height : isBuiltinShapeKind ? BUILTIN_SHAPE_PREVIEW_SIZE.height : placementPreviewSize.height;
    var stageW = (_item$width2 = item.width) !== null && _item$width2 !== void 0 ? _item$width2 : cellW;
    var stageH = (_item$height2 = item.height) !== null && _item$height2 !== void 0 ? _item$height2 : cellH;
    var allKeys = Object.keys(dataSources);
    var allowedKeys = (_k$allowedDataSourceK = k.allowedDataSourceKeys) !== null && _k$allowedDataSourceK !== void 0 && _k$allowedDataSourceK.length ? k.allowedDataSourceKeys.filter(function (x) {
      return allKeys.includes(x);
    }) : allKeys;
    var paletteDragPayload = _objectSpread(_objectSpread({
      elementKind: k.value
    }, (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' && placeMode.elementKind === k.value ? _objectSpread({
      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: "".concat(PREFIX, "-toolbar-preview-card-wrap")
    }, /*#__PURE__*/React.createElement("button", {
      type: "button",
      draggable: true,
      className: classNames("".concat(PREFIX, "-toolbar-preview-card"), !placementLike ? "".concat(PREFIX, "-toolbar-preview-card-deco") : undefined, _defineProperty({}, "".concat(PREFIX, "-toolbar-preview-card-active"), isActive)),
      onClick: function onClick() {
        if (consumeToolbarClickIfTouchDrag !== null && consumeToolbarClickIfTouchDrag !== void 0 && consumeToolbarClickIfTouchDrag()) return;
        handleSelectKind(k);
      },
      onPointerDown: function onPointerDown(e) {
        return onPaletteCardPointerDown === null || onPaletteCardPointerDown === void 0 ? void 0 : onPaletteCardPointerDown(paletteDragPayload, e);
      },
      onDragStart: function onDragStart(e) {
        e.dataTransfer.setData(FLOOR_MAP_PALETTE_DRAG_MIME, JSON.stringify(paletteDragPayload));
        e.dataTransfer.effectAllowed = 'copy';
      },
      title: locales.getText("".concat(I18N_TB, ".palette-card-title")).replace(/\{name\}/g, k.label)
    }, /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-preview-cell"),
      style: {
        width: cellW,
        height: cellH
      }
    }, renderPreviewItem ? /*#__PURE__*/React.createElement("div", {
      className: "".concat(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: "".concat(PREFIX, "-toolbar-preview-fallback")
    }, k.label)), /*#__PURE__*/React.createElement("span", {
      className: "".concat(PREFIX, "-toolbar-preview-card-label")
    }, k.label)));
  };
  var collapseBtn = /*#__PURE__*/React.createElement("button", {
    type: "button",
    className: classNames("".concat(PREFIX, "-toolbar-collapse-handle"), phoneLayout && "".concat(PREFIX, "-toolbar-collapse-handle--in-drawer")),
    onClick: handleToggleCollapsed,
    "aria-label": collapsed ? locales.getText("".concat(I18N_TB, ".expand")) : locales.getText("".concat(I18N_TB, ".collapse")),
    title: collapsed ? locales.getText("".concat(I18N_TB, ".expand")) : locales.getText("".concat(I18N_TB, ".collapse"))
  }, collapsed ? /*#__PURE__*/React.createElement(RightOutlined, null) : /*#__PURE__*/React.createElement(LeftOutlined, null));

  /**
   * 内层容器：实际承载 body / footer，并在动画过程中负责水平裁剪。
   * 桌面：宽度跟随 sidebar（100%）伸缩；手机：antd Drawer 承载内容 + 边缘折叠柄。
   */
  var toolbarInner = /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-toolbar-inner")
  }, /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-toolbar-body")
  }, canCreate && /*#__PURE__*/React.createElement(React.Fragment, null, categories.map(function (cat) {
    var _paletteEntriesByCate;
    var entries = (_paletteEntriesByCate = paletteEntriesByCategory.get(cat.id)) !== null && _paletteEntriesByCate !== void 0 ? _paletteEntriesByCate : [];
    if (!entries.length) return null;
    var visibleEntries = getPaletteSidebarVisibleEntries(entries, paletteSidebarVisibleLimit);
    var showViewAll = shouldShowPaletteViewAll(entries.length, paletteSidebarVisibleLimit);
    return /*#__PURE__*/React.createElement("section", {
      key: cat.id,
      className: "".concat(PREFIX, "-toolbar-section")
    }, /*#__PURE__*/React.createElement("h3", {
      className: "".concat(PREFIX, "-toolbar-section-title")
    }, cat.label), /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-preview-list")
    }, /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-preview-group")
    }, visibleEntries.map(function (entry) {
      return entry.builtinShapeKey && entry.shapeDef ? renderBuiltinShapePaletteCard(entry.kind, entry.shapeDef) : renderKindCard(entry.kind);
    }), showViewAll ? /*#__PURE__*/React.createElement("button", {
      type: "button",
      className: "".concat(PREFIX, "-toolbar-view-all"),
      onClick: function onClick() {
        setViewAllModal({
          categoryLabel: cat.label,
          entries: entries
        });
        collapseToolbarOnPhone();
      }
    }, locales.getText("".concat(I18N_TB, ".view-all"))) : null)));
  })), phoneLayout && onRequestPlaceAtCanvasCenter && (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' ? /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-toolbar-section")
  }, /*#__PURE__*/React.createElement("button", {
    type: "button",
    className: classNames("".concat(PREFIX, "-toolbar-btn"), 'primary'),
    onClick: function onClick() {
      onRequestPlaceAtCanvasCenter();
      collapseToolbarOnPhone();
    }
  }, locales.getText("".concat(I18N_TB, ".add-to-canvas")))) : null), onSave && config.canvasUi.canEdit && /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-toolbar-footer")
  }, layoutDirty ? /*#__PURE__*/React.createElement("span", {
    className: "".concat(PREFIX, "-toolbar-dirty-hint"),
    role: "status"
  }, locales.getText("".concat(I18N_TB, ".layout-dirty-hint"))) : null, saveError && /*#__PURE__*/React.createElement("span", {
    className: "".concat(PREFIX, "-toolbar-error")
  }, typeof saveError === 'string' ? saveError : saveError === null || saveError === void 0 ? void 0 : saveError.message), /*#__PURE__*/React.createElement("button", {
    type: "button",
    className: classNames("".concat(PREFIX, "-toolbar-btn"), 'primary', _defineProperty({}, "".concat(PREFIX, "-toolbar-save-dirty"), layoutDirty)),
    disabled: saving,
    onClick: onSave
  }, saving ? locales.getText("".concat(I18N_TB, ".saving")) : locales.getText("".concat(I18N_TB, ".save")))));
  if (phoneLayout) {
    /**
     * 必须包在 `${PREFIX}-toolbar` 根下，否则 Less 里 `.pisell-floor-map-layout-toolbar &-collapse-handle`
     * 等选择器无法命中，展开态右侧折叠柄会失去定位与样式。
     */
    return /*#__PURE__*/React.createElement("div", {
      className: classNames("".concat(PREFIX, "-toolbar"), className)
    }, paletteViewAllModal, resourcePickerModal, /*#__PURE__*/React.createElement(Drawer, {
      placement: "left",
      open: !collapsed,
      onClose: function onClose() {
        return setCollapsed(true);
      },
      width: "min(320px, 88vw)",
      zIndex: FLOOR_MAP_PHONE_TOOLBAR_DRAWER_Z_INDEX,
      maskClosable: true,
      destroyOnClose: false,
      closable: false,
      forceRender: false,
      rootClassName: "".concat(PREFIX, "-toolbar-phone-drawer-root"),
      classNames: {
        body: "".concat(PREFIX, "-toolbar-phone-drawer-body")
      },
      styles: {
        body: {
          padding: 0,
          /** 由 Less 设为 visible，便于折叠柄伸出面板；列表滚动在 toolbar-inner / body */
          overflow: 'visible',
          display: 'flex',
          flexDirection: 'column',
          height: '100%'
        }
      },
      getContainer: typeof document !== 'undefined' ? function () {
        return document.body;
      } : undefined
    }, /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-phone-drawer-inner")
    }, toolbarInner, collapseBtn)), collapsed ? /*#__PURE__*/React.createElement("button", {
      type: "button",
      className: "".concat(PREFIX, "-toolbar-phone-peek-trigger"),
      onClick: function onClick() {
        return setCollapsed(false);
      },
      "aria-label": locales.getText("".concat(I18N_TB, ".expand")),
      title: locales.getText("".concat(I18N_TB, ".expand"))
    }, /*#__PURE__*/React.createElement(RightOutlined, null)) : null);
  }
  return /*#__PURE__*/React.createElement("div", {
    className: classNames("".concat(PREFIX, "-toolbar"), "".concat(PREFIX, "-toolbar-sidebar"), collapsed && "".concat(PREFIX, "-toolbar-sidebar--collapsed"), className)
  }, paletteViewAllModal, resourcePickerModal, collapseBtn, toolbarInner);
}
export default FloorMapToolbar;