'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var React = require('react');
var useIsomorphicLayoutEffect = require('../../../../utilities/use-isomorphic-layout-effect.js');
var css = require('../../../../utilities/css.js');
var context = require('../../context.js');
var Navigation = require('../../Navigation.scss.js');
var Secondary = require('./components/Secondary/Secondary.js');
var hooks = require('../../../../utilities/i18n/hooks.js');
var hooks$1 = require('../../../../utilities/media-query/hooks.js');
var hooks$2 = require('../../../../utilities/unique-id/hooks.js');
var Indicator = require('../../../Indicator/Indicator.js');
var Icon = require('../../../Icon/Icon.js');
var Badge = require('../../../Badge/Badge.js');
var Tooltip = require('../../../Tooltip/Tooltip.js');
var UnstyledLink = require('../../../UnstyledLink/UnstyledLink.js');
var UnstyledButton = require('../../../UnstyledButton/UnstyledButton.js');

function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }

var React__default = /*#__PURE__*/_interopDefaultLegacy(React);

const MAX_SECONDARY_ACTIONS = 2;
const TOOLTIP_HOVER_DELAY = 1000;
var MatchState;

(function (MatchState) {
  MatchState[MatchState["MatchForced"] = 0] = "MatchForced";
  MatchState[MatchState["MatchUrl"] = 1] = "MatchUrl";
  MatchState[MatchState["MatchPaths"] = 2] = "MatchPaths";
  MatchState[MatchState["Excluded"] = 3] = "Excluded";
  MatchState[MatchState["NoMatch"] = 4] = "NoMatch";
})(MatchState || (MatchState = {}));

function Item({
  url,
  icon,
  label,
  subNavigationItems = [],
  secondaryAction,
  secondaryActions,
  displayActionsOnHover,
  disabled,
  onClick,
  accessibilityLabel,
  selected: selectedOverride,
  badge,
  new: isNew,
  matches,
  exactMatch,
  matchPaths,
  excludePaths,
  external,
  onToggleExpandedState,
  expanded,
  shouldResizeIcon,
  truncateText
}) {
  const i18n = hooks.useI18n();
  const {
    isNavigationCollapsed
  } = hooks$1.useMediaQuery();
  const secondaryNavigationId = hooks$2.useUniqueId('SecondaryNavigation');
  const {
    location,
    onNavigationDismiss
  } = React.useContext(context.NavigationContext);
  const navTextRef = React.useRef(null);
  const [isTruncated, setIsTruncated] = React.useState(false);
  React.useEffect(() => {
    if (!isNavigationCollapsed && expanded) {
      onToggleExpandedState === null || onToggleExpandedState === void 0 ? void 0 : onToggleExpandedState();
    }
  }, [expanded, isNavigationCollapsed, onToggleExpandedState]);
  useIsomorphicLayoutEffect.useIsomorphicLayoutEffect(() => {
    const navTextNode = navTextRef.current;

    if (truncateText && navTextNode) {
      setIsTruncated(navTextNode.scrollHeight > navTextNode.clientHeight);
    }
  }, [truncateText]);
  const tabIndex = disabled ? -1 : 0;
  const hasNewChild = subNavigationItems.filter(subNavigationItem => subNavigationItem.new).length > 0;
  const indicatorMarkup = hasNewChild ? /*#__PURE__*/React__default["default"].createElement("span", {
    className: Navigation["default"].Indicator
  }, /*#__PURE__*/React__default["default"].createElement(Indicator.Indicator, {
    pulse: true
  })) : null;
  const iconMarkup = icon ? /*#__PURE__*/React__default["default"].createElement("div", {
    className: css.classNames(Navigation["default"].Icon, shouldResizeIcon && Navigation["default"]['Icon-resized'])
  }, /*#__PURE__*/React__default["default"].createElement(Icon.Icon, {
    source: icon
  })) : null;
  let badgeMarkup = null;

  if (isNew) {
    badgeMarkup = /*#__PURE__*/React__default["default"].createElement(Badge.Badge, {
      status: "new"
    }, i18n.translate('Polaris.Badge.STATUS_LABELS.new'));
  } else if (typeof badge === 'string') {
    badgeMarkup = /*#__PURE__*/React__default["default"].createElement(Badge.Badge, {
      status: "new"
    }, badge);
  } else {
    badgeMarkup = badge;
  }

  const wrappedBadgeMarkup = badgeMarkup == null ? null : /*#__PURE__*/React__default["default"].createElement("div", {
    className: Navigation["default"].Badge
  }, badgeMarkup);
  const itemLabelMarkup = /*#__PURE__*/React__default["default"].createElement("span", {
    className: css.classNames(Navigation["default"].Text, truncateText && Navigation["default"]['Text-truncated']),
    ref: navTextRef
  }, label, indicatorMarkup);

  if (url == null) {
    const className = css.classNames(Navigation["default"].Item, disabled && Navigation["default"]['Item-disabled'], selectedOverride && Navigation["default"]['Item-selected']);
    return /*#__PURE__*/React__default["default"].createElement("li", {
      className: Navigation["default"].ListItem
    }, /*#__PURE__*/React__default["default"].createElement("div", {
      className: Navigation["default"].ItemWrapper
    }, /*#__PURE__*/React__default["default"].createElement("div", {
      className: css.classNames(Navigation["default"].ItemInnerWrapper, disabled && Navigation["default"].ItemInnerDisabled)
    }, /*#__PURE__*/React__default["default"].createElement("button", {
      type: "button",
      className: className,
      disabled: disabled,
      "aria-disabled": disabled,
      "aria-label": accessibilityLabel,
      onClick: getClickHandler(onClick)
    }, iconMarkup, itemLabelMarkup, wrappedBadgeMarkup))));
  }

  if (secondaryAction && process.env.NODE_ENV === 'development') {
    // eslint-disable-next-line no-console
    console.warn('Deprecation: The `secondaryAction` prop on the `Navigation.Item` has been deprecated. Use `secondaryActions` instead.');
  }

  const actions = secondaryActions || secondaryAction && [secondaryAction];

  if (actions && actions.length > MAX_SECONDARY_ACTIONS) {
    actions.length = MAX_SECONDARY_ACTIONS;

    if (process.env.NODE_ENV === 'development') {
      // eslint-disable-next-line no-console
      console.warn(`secondaryActions must have a maximum of ${MAX_SECONDARY_ACTIONS} actions. Only the first ${MAX_SECONDARY_ACTIONS} actions will be rendered.`);
    }
  }

  const secondaryActionMarkup = actions !== null && actions !== void 0 && actions.length ? /*#__PURE__*/React__default["default"].createElement("span", {
    className: Navigation["default"].SecondaryActions
  }, actions.map(action => /*#__PURE__*/React__default["default"].createElement(ItemSecondaryAction, Object.assign({
    key: action.accessibilityLabel
  }, action, {
    tabIndex: tabIndex,
    disabled: disabled
  })))) : null;
  const itemContentMarkup = /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, iconMarkup, itemLabelMarkup, secondaryActionMarkup ? null : wrappedBadgeMarkup);
  const outerContentMarkup = /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, secondaryActionMarkup ? wrappedBadgeMarkup : null);
  const matchState = matchStateForItem({
    url,
    matches,
    exactMatch,
    matchPaths,
    excludePaths
  }, location);
  const matchingSubNavigationItems = subNavigationItems.filter(item => {
    const subMatchState = matchStateForItem(item, location);
    return subMatchState === MatchState.MatchForced || subMatchState === MatchState.MatchUrl || subMatchState === MatchState.MatchPaths;
  });
  const childIsActive = matchingSubNavigationItems.length > 0;
  const selected = selectedOverride == null ? matchState === MatchState.MatchForced || matchState === MatchState.MatchUrl || matchState === MatchState.MatchPaths : selectedOverride;
  const showExpanded = selected || expanded || childIsActive;
  const canBeActive = subNavigationItems.length === 0 || !childIsActive;
  const itemClassName = css.classNames(Navigation["default"].Item, disabled && Navigation["default"]['Item-disabled'], selected && canBeActive && Navigation["default"]['Item-selected'], showExpanded && Navigation["default"].subNavigationActive, childIsActive && Navigation["default"]['Item-child-active']);
  let secondaryNavigationMarkup = null;

  if (subNavigationItems.length > 0) {
    const longestMatch = matchingSubNavigationItems.sort(({
      url: firstUrl
    }, {
      url: secondUrl
    }) => secondUrl.length - firstUrl.length)[0];
    const SecondaryNavigationClassName = css.classNames(Navigation["default"].SecondaryNavigation, !icon && Navigation["default"]['SecondaryNavigation-noIcon']);
    secondaryNavigationMarkup = /*#__PURE__*/React__default["default"].createElement("div", {
      className: SecondaryNavigationClassName
    }, /*#__PURE__*/React__default["default"].createElement(Secondary.Secondary, {
      expanded: showExpanded,
      id: secondaryNavigationId
    }, subNavigationItems.map(item => {
      const {
        label,
        ...rest
      } = item;

      const onClick = () => {
        if (onNavigationDismiss) {
          onNavigationDismiss();
        }

        if (item.onClick && item.onClick !== onNavigationDismiss) {
          item.onClick();
        }
      };

      return /*#__PURE__*/React__default["default"].createElement(Item, Object.assign({
        key: label
      }, rest, {
        label: label,
        matches: item === longestMatch,
        onClick: onClick,
        truncateText: truncateText
      }));
    })));
  }

  const className = css.classNames(Navigation["default"].ListItem, Boolean(actions && actions.length) && Navigation["default"]['ListItem-hasAction']);

  const itemLinkMarkup = () => {
    const linkMarkup = /*#__PURE__*/React__default["default"].createElement(UnstyledLink.UnstyledLink, Object.assign({
      url: url,
      className: itemClassName,
      external: external,
      tabIndex: tabIndex,
      "aria-disabled": disabled,
      "aria-label": accessibilityLabel,
      onClick: getClickHandler(onClick)
    }, normalizeAriaAttributes(secondaryNavigationId, subNavigationItems.length > 0, showExpanded)), itemContentMarkup);
    return isTruncated ? /*#__PURE__*/React__default["default"].createElement(Tooltip.Tooltip, {
      hoverDelay: TOOLTIP_HOVER_DELAY,
      content: label,
      preferredPosition: "above"
    }, linkMarkup) : linkMarkup;
  };

  return /*#__PURE__*/React__default["default"].createElement("li", {
    className: className
  }, /*#__PURE__*/React__default["default"].createElement("div", {
    className: Navigation["default"].ItemWrapper
  }, /*#__PURE__*/React__default["default"].createElement("div", {
    className: css.classNames(Navigation["default"].ItemInnerWrapper, selected && canBeActive && Navigation["default"]['ItemInnerWrapper-selected'], displayActionsOnHover && Navigation["default"]['ItemInnerWrapper-display-actions-on-hover'], disabled && Navigation["default"].ItemInnerDisabled)
  }, displayActionsOnHover && secondaryActionMarkup && wrappedBadgeMarkup ? /*#__PURE__*/React__default["default"].createElement("span", {
    className: Navigation["default"].ItemWithFloatingActions
  }, itemLinkMarkup(), secondaryActionMarkup) : /*#__PURE__*/React__default["default"].createElement(React__default["default"].Fragment, null, itemLinkMarkup(), secondaryActionMarkup), outerContentMarkup)), secondaryNavigationMarkup);

  function getClickHandler(onClick) {
    return event => {
      const {
        currentTarget
      } = event;

      if (currentTarget.getAttribute('href') === location) {
        event.preventDefault();
      }

      if (subNavigationItems && subNavigationItems.length > 0 && isNavigationCollapsed) {
        event.preventDefault();
        onToggleExpandedState === null || onToggleExpandedState === void 0 ? void 0 : onToggleExpandedState();
      } else if (onNavigationDismiss) {
        onNavigationDismiss();

        if (onClick && onClick !== onNavigationDismiss) {
          onClick();
        }

        return;
      }

      if (onClick) {
        onClick();
      }
    };
  }
}
function ItemSecondaryAction({
  url,
  icon,
  accessibilityLabel,
  tooltip,
  onClick,
  disabled,
  tabIndex
}) {
  const markup = url ? /*#__PURE__*/React__default["default"].createElement(UnstyledLink.UnstyledLink, {
    external: true,
    url: url,
    className: Navigation["default"].SecondaryAction,
    tabIndex: tabIndex,
    "aria-disabled": disabled,
    "aria-label": accessibilityLabel,
    onClick: onClick
  }, /*#__PURE__*/React__default["default"].createElement(Icon.Icon, {
    source: icon
  })) : /*#__PURE__*/React__default["default"].createElement(UnstyledButton.UnstyledButton, {
    className: Navigation["default"].SecondaryAction,
    tabIndex: tabIndex,
    disabled: disabled,
    accessibilityLabel: accessibilityLabel,
    onClick: onClick
  }, /*#__PURE__*/React__default["default"].createElement(Icon.Icon, {
    source: icon
  }));
  return tooltip ? /*#__PURE__*/React__default["default"].createElement(Tooltip.Tooltip, tooltip, " ", markup, " ") : markup;
}
function isNavigationItemActive(navigationItem, currentPath) {
  const matchState = matchStateForItem(navigationItem, currentPath);
  const matchingSubNavigationItems = navigationItem.subNavigationItems && navigationItem.subNavigationItems.filter(item => {
    const subMatchState = matchStateForItem(item, currentPath);
    return subMatchState === MatchState.MatchForced || subMatchState === MatchState.MatchUrl || subMatchState === MatchState.MatchPaths;
  });
  const childIsActive = matchingSubNavigationItems && matchingSubNavigationItems.length > 0;
  const selected = matchState === MatchState.MatchForced || matchState === MatchState.MatchUrl || matchState === MatchState.MatchPaths;
  return selected || childIsActive;
}

function normalizePathname(pathname) {
  const barePathname = pathname.split('?')[0].split('#')[0];
  return barePathname.endsWith('/') ? barePathname : `${barePathname}/`;
}

function safeEqual(location, path) {
  return normalizePathname(location) === normalizePathname(path);
}

function safeStartsWith(location, path) {
  return normalizePathname(location).startsWith(normalizePathname(path));
}

function matchStateForItem({
  url,
  matches,
  exactMatch,
  matchPaths,
  excludePaths
}, location) {
  if (url == null) {
    return MatchState.NoMatch;
  }

  if (matches) {
    return MatchState.MatchForced;
  }

  if (matches === false || excludePaths && excludePaths.some(path => safeStartsWith(location, path))) {
    return MatchState.Excluded;
  }

  if (matchPaths && matchPaths.some(path => safeStartsWith(location, path))) {
    return MatchState.MatchPaths;
  }

  const matchesUrl = exactMatch ? safeEqual(location, url) : safeStartsWith(location, url);
  return matchesUrl ? MatchState.MatchUrl : MatchState.NoMatch;
}

function normalizeAriaAttributes(controlId, hasSubMenu, expanded) {
  return hasSubMenu ? {
    'aria-expanded': expanded,
    'aria-controls': controlId
  } : undefined;
}

exports.Item = Item;
exports.ItemSecondaryAction = ItemSecondaryAction;
exports.MAX_SECONDARY_ACTIONS = MAX_SECONDARY_ACTIONS;
exports.isNavigationItemActive = isNavigationItemActive;
