"use strict";

var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.useTreeViewFocus = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var React = _interopRequireWildcard(require("react"));
var _useEventCallback = _interopRequireDefault(require("@mui/utils/useEventCallback"));
var _ownerDocument = _interopRequireDefault(require("@mui/utils/ownerDocument"));
var _useInstanceEventHandler = require("../../hooks/useInstanceEventHandler");
var _utils = require("../../utils/utils");
var _tree = require("../../utils/tree");
var _useTreeViewSelection = require("../useTreeViewSelection/useTreeViewSelection.utils");
const useDefaultFocusableItemId = (instance, selectedItems) => {
  let tabbableItemId = (0, _useTreeViewSelection.convertSelectedItemsToArray)(selectedItems).find(itemId => {
    if (!instance.isItemNavigable(itemId)) {
      return false;
    }
    const itemMeta = instance.getItemMeta(itemId);
    return itemMeta && (itemMeta.parentId == null || instance.isItemExpanded(itemMeta.parentId));
  });
  if (tabbableItemId == null) {
    tabbableItemId = (0, _tree.getFirstNavigableItem)(instance);
  }
  return tabbableItemId;
};
const useTreeViewFocus = ({
  instance,
  params,
  state,
  setState,
  models,
  rootRef
}) => {
  const defaultFocusableItemId = useDefaultFocusableItemId(instance, models.selectedItems.value);
  const setFocusedItemId = (0, _useEventCallback.default)(itemId => {
    const cleanItemId = typeof itemId === 'function' ? itemId(state.focusedItemId) : itemId;
    if (state.focusedItemId !== cleanItemId) {
      setState(prevState => (0, _extends2.default)({}, prevState, {
        focusedItemId: cleanItemId
      }));
    }
  });
  const isTreeViewFocused = React.useCallback(() => !!rootRef.current && rootRef.current.contains((0, _utils.getActiveElement)((0, _ownerDocument.default)(rootRef.current))), [rootRef]);
  const isItemFocused = React.useCallback(itemId => state.focusedItemId === itemId && isTreeViewFocused(), [state.focusedItemId, isTreeViewFocused]);
  const isItemVisible = itemId => {
    const itemMeta = instance.getItemMeta(itemId);
    return itemMeta && (itemMeta.parentId == null || instance.isItemExpanded(itemMeta.parentId));
  };
  const innerFocusItem = (event, itemId) => {
    const itemElement = instance.getItemDOMElement(itemId);
    if (itemElement) {
      itemElement.focus();
    }
    setFocusedItemId(itemId);
    if (params.onItemFocus) {
      params.onItemFocus(event, itemId);
    }
  };
  const focusItem = (0, _useEventCallback.default)((event, itemId) => {
    // If we receive an itemId, and it is visible, the focus will be set to it
    if (isItemVisible(itemId)) {
      innerFocusItem(event, itemId);
    }
  });
  const removeFocusedItem = (0, _useEventCallback.default)(() => {
    if (state.focusedItemId == null) {
      return;
    }
    const itemMeta = instance.getItemMeta(state.focusedItemId);
    if (itemMeta) {
      const itemElement = instance.getItemDOMElement(state.focusedItemId);
      if (itemElement) {
        itemElement.blur();
      }
    }
    setFocusedItemId(null);
  });
  const canItemBeTabbed = itemId => itemId === defaultFocusableItemId;
  (0, _useInstanceEventHandler.useInstanceEventHandler)(instance, 'removeItem', ({
    id
  }) => {
    if (state.focusedItemId === id) {
      innerFocusItem(null, defaultFocusableItemId);
    }
  });
  const createRootHandleFocus = otherHandlers => event => {
    otherHandlers.onFocus?.(event);
    if (event.defaultMuiPrevented) {
      return;
    }

    // if the event bubbled (which is React specific) we don't want to steal focus
    if (event.target === event.currentTarget) {
      innerFocusItem(event, defaultFocusableItemId);
    }
  };
  return {
    getRootProps: otherHandlers => ({
      onFocus: createRootHandleFocus(otherHandlers)
    }),
    publicAPI: {
      focusItem
    },
    instance: {
      isItemFocused,
      canItemBeTabbed,
      focusItem,
      removeFocusedItem
    }
  };
};
exports.useTreeViewFocus = useTreeViewFocus;
useTreeViewFocus.getInitialState = () => ({
  focusedItemId: null
});
useTreeViewFocus.params = {
  onItemFocus: true
};