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 _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 _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 _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 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 } from 'react';
import classNames from 'classnames';
import { Select } from 'antd';
import { FLOOR_MAP_IMAGE_ELEMENT_KIND, FLOOR_MAP_STAGE_ELEMENT_KIND } from "../types";
import { resolveDataBindingPolicy } from "../utils/floorMapElementKindUtils";
import { FLOOR_MAP_PALETTE_DRAG_MIME } from "../utils/floorMapDropUtils";
import { formatDataRecordOptionLabel } from "../utils/floorMapDataRecordLabel";
import { locales } from '@pisell/utils';
import "./FloorMapToolbar.less";
var PREFIX = 'pisell-floor-map-layout';
var I18N_TB = 'pisell-floor-map-layout.toolbar';
var I18N_EP_DS = 'pisell-floor-map-layout.edit-panel.ph-data-source';
var DEFAULT_PLACEMENT_SIZE = {
  width: 180,
  height: 120
};
var DEFAULT_DECORATION_SIZE = 48;
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) {
  var el = _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: ''
  } : {});
  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
};
export function FloorMapToolbar(props) {
  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;
  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 handleSelectKind = function handleSelectKind(kind) {
    var policy = resolveDataBindingPolicy(kind);
    var next = {
      type: 'scene',
      elementKind: kind.value,
      /** 不预锁单一数据源，由用户在工具栏「数据源」中选择；落点时用 allowedKeys[0] 作兜底 */
      dataSourceKey: undefined,
      recordId: undefined
    };
    var isSame = (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' && placeMode.elementKind === kind.value;
    onPlaceModeChange(isSame ? null : next);
    void policy;
  };
  var handleDsChange = function handleDsChange(mode, key) {
    onPlaceModeChange(_objectSpread(_objectSpread({}, mode), {}, {
      dataSourceKey: key,
      recordId: undefined,
      recordIds: undefined
    }));
  };
  var handleRecordsChange = function handleRecordsChange(mode, ids) {
    var _ids$filter;
    var list = (_ids$filter = ids === null || ids === void 0 ? void 0 : ids.filter(Boolean)) !== null && _ids$filter !== void 0 ? _ids$filter : [];
    onPlaceModeChange(_objectSpread(_objectSpread({}, mode), {}, {
      recordIds: list.length > 0 ? list : undefined,
      recordId: undefined
    }));
  };
  var cancelPlaceMode = function cancelPlaceMode() {
    return onPlaceModeChange(null);
  };
  var renderKindCard = function renderKindCard(k) {
    var _k$allowedDataSourceK;
    var policy = resolveDataBindingPolicy(k);
    var isStage = k.value === FLOOR_MAP_STAGE_ELEMENT_KIND;
    var isImageKind = k.value === FLOOR_MAP_IMAGE_ELEMENT_KIND;
    var placementLike = policy !== 'none' && !isStage || isImageKind;
    var size = isStage ? STAGE_PREVIEW_SIZE : placementLike ? isImageKind ? IMAGE_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;
    var item = buildScenePreviewMergedItem(k, activeDs, size);
    var isActive = (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' && placeMode.elementKind === k.value;
    var cellW = isStage ? 92 : placementLike ? 80 : decorationPreviewSize;
    var cellH = isStage ? 40 : placementLike ? 54 : decorationPreviewSize;
    var previewW = isImageKind ? IMAGE_PREVIEW_SIZE.width : placementPreviewSize.width;
    var previewH = isImageKind ? IMAGE_PREVIEW_SIZE.height : placementPreviewSize.height;
    var placeScale = placementLike ? Math.min(cellW / previewW, cellH / previewH) : 1;
    var stageScale = isStage ? Math.min(cellW / item.width, cellH / item.height, 1) : 1;
    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({
      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
    } : {}) : {});
    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: placementLike ? {
        width: previewW,
        height: previewH,
        transform: "scale(".concat(placeScale, ")"),
        transformOrigin: 'top left'
      } : isStage ? {
        width: item.width,
        height: item.height,
        transform: "scale(".concat(stageScale, ")"),
        transformOrigin: 'top left'
      } : undefined
    }, 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)), isActive && policy !== 'none' && /*#__PURE__*/React.createElement(React.Fragment, null, allowedKeys.length >= 1 && /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-record-pick")
    }, /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-record-pick-label")
    }, locales.getText("".concat(I18N_TB, ".data-binding-optional"))), /*#__PURE__*/React.createElement(Select, {
      placeholder: locales.getText(I18N_EP_DS),
      allowClear: true,
      value: placeMode.type === 'scene' ? placeMode.dataSourceKey : undefined,
      options: allowedKeys.map(function (key) {
        var _dataSourceLabels$key;
        return {
          value: key,
          label: (_dataSourceLabels$key = dataSourceLabels[key]) !== null && _dataSourceLabels$key !== void 0 ? _dataSourceLabels$key : key
        };
      }),
      onChange: function onChange(v) {
        if ((placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene') handleDsChange(placeMode, v);
      },
      size: "large",
      style: {
        width: '100%'
      }
    }), function () {
      var mode = (placeMode === null || placeMode === void 0 ? void 0 : placeMode.type) === 'scene' ? placeMode : null;
      var key = mode === null || mode === void 0 ? void 0 : mode.dataSourceKey;
      if (!key) {
        return /*#__PURE__*/React.createElement("div", {
          className: "".concat(PREFIX, "-toolbar-record-pick-hint")
        }, locales.getText("".concat(I18N_TB, ".hint-after-select-ds")));
      }
      var unplaced = getUnplacedRecordsForKey(key, dataSources, sceneElements);
      if (unplaced.length === 0) {
        return /*#__PURE__*/React.createElement("div", {
          className: "".concat(PREFIX, "-toolbar-record-pick-hint")
        }, locales.getText("".concat(I18N_TB, ".hint-no-unplaced-rows")));
      }
      var recordValue = mode !== null && mode !== void 0 && mode.recordIds && mode.recordIds.length > 0 ? mode.recordIds : mode !== null && mode !== void 0 && mode.recordId ? [mode.recordId] : undefined;
      return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Select, {
        mode: "multiple",
        placeholder: locales.getText("".concat(I18N_TB, ".ph-select-records")),
        allowClear: true,
        maxTagCount: "responsive",
        value: recordValue,
        options: unplaced.map(function (r) {
          return {
            value: r.id,
            label: formatDataRecordOptionLabel(r)
          };
        }),
        onChange: function onChange(v) {
          if (mode) handleRecordsChange(mode, v);
        },
        size: "large",
        style: {
          width: '100%',
          marginTop: 4
        }
      }), /*#__PURE__*/React.createElement("div", {
        className: "".concat(PREFIX, "-toolbar-record-pick-hint")
      }, locales.getText("".concat(I18N_TB, ".hint-multi-drop"))));
    }()), allowedKeys.length === 0 && /*#__PURE__*/React.createElement("div", {
      className: "".concat(PREFIX, "-toolbar-record-hint")
    }, locales.getText("".concat(I18N_TB, ".no-data-sources"))), /*#__PURE__*/React.createElement("button", {
      type: "button",
      className: "".concat(PREFIX, "-toolbar-btn cancel-inline"),
      onClick: cancelPlaceMode
    }, locales.getText("".concat(I18N_TB, ".cancel-place")))), isActive && policy === 'none' && /*#__PURE__*/React.createElement("button", {
      type: "button",
      className: "".concat(PREFIX, "-toolbar-btn cancel-inline"),
      onClick: cancelPlaceMode
    }, locales.getText("".concat(I18N_TB, ".cancel-place"))));
  };
  return /*#__PURE__*/React.createElement("div", {
    className: classNames("".concat(PREFIX, "-toolbar"), "".concat(PREFIX, "-toolbar-sidebar"), className)
  }, /*#__PURE__*/React.createElement("div", {
    className: "".concat(PREFIX, "-toolbar-body")
  }, canCreate && /*#__PURE__*/React.createElement(React.Fragment, null, categories.map(function (cat) {
    var _kindsByCategory$get;
    var kinds = (_kindsByCategory$get = kindsByCategory.get(cat.id)) !== null && _kindsByCategory$get !== void 0 ? _kindsByCategory$get : [];
    if (!kinds.length) return null;
    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")
    }, kinds.map(function (k) {
      return renderKindCard(k);
    }))));
  }))), 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")))));
}
export default FloorMapToolbar;