"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
exports.__esModule = true;
exports.MultiReferenceEdit = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _react = _interopRequireWildcard(require("react"));
var _designSystem = require("@wix/design-system");
var _patternsFields = require("@wix/patterns-fields");
var _mobxReactLite = require("mobx-react-lite");
var _react2 = require("@wix/bex-core/react");
var _useCloseOnAncestorScroll = require("../../../../hooks/useCloseOnAncestorScroll");
var _useFilterCollectionStates = require("../../../../hooks/useFilterCollectionStates");
var _providers = require("../../../../providers");
var _getImageFieldId = require("../reference/getImageFieldId");
var _openCollectionContext = require("../reference/openCollectionContext");
var _jsxFileName = "/home/builduser/work/843658b9f44192f0/packages/cairo/dist/cjs/components/EditableTable/cellTypes/multiReference/Edit.tsx";
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
function _MultiReferenceEditContent({
  value,
  onChange,
  onCommit,
  typeConfig,
  editTrigger,
  inputRef
}) {
  const config = typeConfig;
  const refSchema = config == null ? void 0 : config.refSchema;
  const acHandle = (0, _react.useRef)(null);
  const wrapperRef = (0, _react.useRef)(null);
  // Opener provided by ReferenceEditWrapper (a stable ancestor) so the
  // navigation + return-to-foreground subscription survive this editor
  // unmounting when the overlay opens.
  const openReferencedCollection = (0, _openCollectionContext.useOpenReferencedCollection)();
  const idField = (refSchema == null ? void 0 : refSchema.idField) ?? '_id';
  const displayField = (refSchema == null ? void 0 : refSchema.displayField) ?? 'title';
  const imageField = (0, _getImageFieldId.getImageFieldId)(refSchema == null ? void 0 : refSchema.fields);
  const collection = (0, _react2.useCollection)({
    queryName: `multi-reference-cell-edit-${(refSchema == null ? void 0 : refSchema.id) ?? 'unknown'}`,
    itemKey: item => item.id,
    itemName: item => item.name,
    fetchData: async query => {
      if (!(config != null && config.fetchReferenceItems)) {
        return {
          items: [],
          total: 0
        };
      }
      return config.fetchReferenceItems(query);
    }
  });
  const initialSearchTextRef = (0, _react.useRef)(editTrigger && typeof editTrigger === 'object' && editTrigger.kind === 'type' ? editTrigger.key : undefined);
  (0, _react.useEffect)(() => {
    const dispose = collection.init();
    if (initialSearchTextRef.current !== undefined) {
      collection.search(initialSearchTextRef.current, {
        clearResult: true
      });
    }
    // Seed editingValue with the current value so a no-op edit commits the same
    // list back instead of `undefined` (which would clear the cell).
    onChange(value ?? []);
    return dispose;
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [collection]);
  const selectedRefs = value ?? [];
  const selectedItems = (0, _react.useMemo)(() => selectedRefs.map((ref, i) => ({
    id: String(ref[idField] ?? i),
    name: String(ref[displayField] ?? ''),
    image: imageField ? ref[imageField] : undefined
  })), [selectedRefs, idField, displayField, imageField]);
  const selectedIds = (0, _react.useMemo)(() => new Set(selectedItems.map(item => item.id)), [selectedItems]);
  const keyedItems = collection.result.keyedItems;
  const fetchedLastPage = collection.fetchedLastPage;
  const searchValue = collection.query.search.value;

  // Exclude already-selected references from the dropdown options.
  const items = (0, _react.useMemo)(() => keyedItems.map(ki => ({
    id: String(ki.key),
    name: ki.item.name,
    image: ki.item.image
  })).filter(item => !selectedIds.has(item.id)), [keyedItems, selectedIds]);
  const handleSelect = (0, _react.useCallback)(item => {
    const next = [...selectedRefs, {
      [idField]: item.id,
      [displayField]: item.name,
      ...(imageField && item.image ? {
        [imageField]: item.image
      } : {})
    }];
    onChange(next);
    collection.clearSearch();
  }, [selectedRefs, idField, displayField, imageField, onChange, collection]);
  const handleRemoveTag = (0, _react.useCallback)(id => {
    const next = selectedRefs.filter(ref => String(ref[idField] ?? '') !== id);
    onChange(next.length ? next : null);
  }, [selectedRefs, idField, onChange]);
  const handleSearchChange = (0, _react.useCallback)(search => {
    if (search) {
      collection.search(search, {
        clearResult: true
      });
    } else {
      collection.clearSearch();
    }
  }, [collection]);
  const handleKeyDown = (0, _react.useCallback)(e => {
    // Production should commit (not revert) on Escape — close the editor and
    // keep the current selection. Stop propagation so the framework's default
    // cancel-on-Escape doesn't also fire.
    if (e.key === 'Escape') {
      e.preventDefault();
      e.stopPropagation();
      onCommit();
    }
  }, [onCommit]);
  const closeDropdown = (0, _react.useCallback)(() => {
    var _acHandle$current;
    return (_acHandle$current = acHandle.current) == null ? void 0 : _acHandle$current.hideOptions();
  }, []);
  (0, _useCloseOnAncestorScroll.useCloseOnAncestorScroll)(wrapperRef, closeDropdown, true);

  // Commit on blur, unless focus moved into the portaled dropdown / popover.
  const handleBlur = (0, _react.useCallback)(() => {
    requestAnimationFrame(() => {
      var _wrapperRef$current;
      const active = document.activeElement;
      if (!active) {
        onCommit();
        return;
      }
      if ((_wrapperRef$current = wrapperRef.current) != null && _wrapperRef$current.contains(active)) {
        return;
      }
      if (active.closest('[role="listbox"], [role="dialog"], [data-hook*="popover"]')) {
        return;
      }
      onCommit();
    });
  }, [onCommit]);

  // Click-outside fallback. Empty cells often never get a focused descendant,
  // so onBlur on the wrapper never fires.
  (0, _react.useEffect)(() => {
    const handleDocMouseDown = e => {
      var _wrapperRef$current2;
      const target = e.target;
      if (!target) {
        return;
      }
      if ((_wrapperRef$current2 = wrapperRef.current) != null && _wrapperRef$current2.contains(target)) {
        return;
      }
      if (target.closest != null && target.closest('[role="listbox"], [role="dialog"], [data-hook*="popover"]')) {
        return;
      }
      onCommit();
    };
    document.addEventListener('mousedown', handleDocMouseDown);
    return () => document.removeEventListener('mousedown', handleDocMouseDown);
  }, [onCommit]);
  const {
    showInitialLoader,
    fixedFooter
  } = (0, _useFilterCollectionStates.useFilterCollectionStates)({
    collection,
    fixedFooter: config == null || config.renderFooter == null ? void 0 : config.renderFooter()
  });

  // Refresh this editor's dropdown options when the overlay closes — force
  // invalidates the shared query cache (keyed by queryName), so even after this
  // editor has unmounted the next open refetches fresh.
  const handleOpenCollection = (0, _react.useMemo)(() => openReferencedCollection ? () => openReferencedCollection(() => collection.clearResultAndMoveToStart({
    force: true
  })) : undefined, [openReferencedCollection, collection]);
  if (!refSchema) {
    return null;
  }
  return /*#__PURE__*/_react.default.createElement(_designSystem.Box, {
    ref: wrapperRef,
    width: "100%",
    height: "100%",
    __self: this,
    __source: {
      fileName: _jsxFileName,
      lineNumber: 233,
      columnNumber: 5
    }
  }, /*#__PURE__*/_react.default.createElement(_patternsFields.CellMultiReferenceInput, {
    ref: acHandle,
    items: items,
    selectedItems: selectedItems,
    value: searchValue,
    onChange: handleSearchChange,
    onSelect: handleSelect,
    onRemoveTag: handleRemoveTag,
    onKeyDown: handleKeyDown,
    onBlur: handleBlur,
    infiniteScroll: true,
    hasMore: !showInitialLoader && !fetchedLastPage,
    loadMore: collection.fetchNextPageIfNeeded,
    fixedFooter: fixedFooter,
    onOpenCollection: handleOpenCollection,
    autoOpen: !!editTrigger,
    inputRef: inputRef,
    dataHook: "multi-reference-edit",
    __self: this,
    __source: {
      fileName: _jsxFileName,
      lineNumber: 234,
      columnNumber: 7
    }
  }));
}
const MultiReferenceEditContent = (0, _mobxReactLite.observer)(_MultiReferenceEditContent);
const MultiReferenceEdit = props => /*#__PURE__*/_react.default.createElement(_providers.FilterTranslationProvider, {
  __self: void 0,
  __source: {
    fileName: _jsxFileName,
    lineNumber: 262,
    columnNumber: 3
  }
}, /*#__PURE__*/_react.default.createElement(MultiReferenceEditContent, (0, _extends2.default)({}, props, {
  __self: void 0,
  __source: {
    fileName: _jsxFileName,
    lineNumber: 263,
    columnNumber: 5
  }
})));
exports.MultiReferenceEdit = MultiReferenceEdit;
//# sourceMappingURL=Edit.js.map