/* top-nav-start.tsx generated by @compiled/babel-plugin v0.38.1 */
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import "./top-nav-start.compiled.css";
import { ax, ix } from "@compiled/react/runtime";
import React, { forwardRef, useContext, useEffect, useLayoutEffect, useRef, useState } from 'react';
import useStableRef from '@atlaskit/ds-lib/use-stable-ref';
import { fg } from '@atlaskit/platform-feature-flags';
import { UNSAFE_useMediaQuery } from '@atlaskit/primitives/compiled';
import { TopNavStartAttachRef } from '../../../context/top-nav-start/top-nav-start-context';
import { useSideNavVisibility } from '../side-nav/use-side-nav-visibility';
import { SideNavVisibilityState } from '../side-nav/visibility-context';

/**
 * Firefox does support these reorder animations, but only partially enabling layout animations would look odd.
 *
 * We are using JS to detect Firefox and disable animations, instead of using CSS, as Compiled currently does not merge duplicate
 * CSS at-rules when at-rules are nested: https://github.com/atlassian-labs/compiled/blob/e04a325915e1d13010205089e4915de0e53bc2d4/packages/css/src/plugins/merge-duplicate-at-rules.ts#L5
 * Avoiding nesting the `@supports` at-rule inside of `@media` means Compiled can remove duplicate styles from the generated CSS.
 */
var isFirefox = typeof navigator !== 'undefined' && navigator.userAgent.toLowerCase().indexOf('firefox') > -1;

// Placed in a variable, as the value is used in the translateX value for the children wrapper animation.
var flexGap = "var(--ds-space-050, 4px)";

/**
 * Styles for the TopNavStart element.
 *
 * When `navx-full-height-sidebar` is enabled this is the styling for the inner element,
 * which re-enables pointer events.
 */
var innerStyles = {
  root: "_zulp1b66 _yyhykb7n _4t3i1osq _4cvr1h6o _1e0c1txw _glte1ris _15ri1mjv _1gs5usvi",
  jiraProductLogoUpdate: "_15rip2n4",
  fullHeightSidebar: "_lcxv1wug",
  fullHeightSidebarExpanded: "_15rin7od _glte1osq"
};

/**
 * Styles for the outer element, that does not have re-enabled pointer events and spans the entire
 * width of the TopNavStart area.
 *
 * This wrapper element is only rendered when `navx-full-height-sidebar` is enabled.
 */
var wrapperStyles = {
  root: "_vchhusvi _bozgutpp _4t3i1osq",
  fullHeightSidebarExpanded: "_glte93mn _exxmpxbi"
};

/**
 * We use a fixed translateX offset for the slide animation (used when the TopNavStart children elements are reordered).
 * This fixed offset makes the elements appear to animate smoothly from the old to the new position.
 * This offset is calculated based on:
 * - 32px (2rem) width of the side nav toggle button (IconButton)
 * - 4px gap ('space.050' token) of the flex container
 *
 * The benefit of hardcoding this offset is that we don't need to calculate it using JS each time the sidebar is toggled.
 * However, it could become out of sync if the width of IconButton changes.
 *
 * The alternative is using JS to store the previous position of the children wrapper element, and calculate the offset based on
 * the new position, and then transforming using that offset. This would prevent the animation from going out of sync.
 */
var childrenWrapperAnimationOffset = "calc(2rem + ".concat(flexGap, ")");
var childrenWrapperStyles = {
  root: "_zulp1kw7 _1e0c1kw7 _1ul9idpf _15yekb7n _65m41mrw",
  animationBaseStyles: "_10t81e03",
  finalPosition: "_mjvcz12g _xrrpfnf5",
  expandAnimationStartPosition: "_mjvcyrjp",
  collapseAnimationStartPosition: "_mjvco0k7"
};

/**
 * We use a fixed translateX offset for the toggle button slide animation (used when the TopNavStart children elements are reordered).
 * The specific value doesn't matter too much for the toggle button animation, so we are using `100%`, which will match the toggle button width.
 *
 * By combining the `translateX` animation with an `opacity` fade, the feel and experience is actually quite similar to animating the
 * element from the exact old position (offset), and it avoids the additional complexity of needing to track and calculate the exact offset.
 */
var toggleButtonWrapperStyles = {
  root: "_15yekb7n _65m41mrw _10t81rjc",
  finalPosition: "_mjvcz12g _xrrpfnf5 _bgpzkb7n",
  expandAnimationStartPosition: "_mjvc1p9u _bgpzidpf",
  collapseAnimationStartPosition: "_mjvc1efy _bgpzidpf",
  expandAnimationTimingFunction: "_1xq51ytf",
  collapseAnimationTimingFunction: "_1xq55ucs",
  alignEnd: "_ahbq1wug"
};

/**
 * The consistent key used for the side nav toggle button to ensure it does not get remounted
 * when it is reordered.
 *
 * This ensures we get focus restoration for free.
 */
var sideNavToggleButtonKey = 'side-nav-toggle-button';
var TopNavStartInnerOld = /*#__PURE__*/forwardRef(function TopNavStartInner(_ref, ref) {
  var children = _ref.children,
    testId = _ref.testId;
  return /*#__PURE__*/React.createElement("div", {
    ref: ref,
    "data-testid": testId,
    className: ax([innerStyles.root, fg('team25-eu-jira-logo-updates-csm-jsm') && innerStyles.jiraProductLogoUpdate])
  }, children);
});
var TopNavStartInnerFHS = /*#__PURE__*/forwardRef(function TopNavStartInnerFHS(_ref2, ref) {
  var children = _ref2.children,
    testId = _ref2.testId;
  // This needs the real `defaultCollapsed` state or will not SSR properly
  // TODO: lift `defaultCollapsed` state to `Root` (DSP-23683)
  // then context value will be correct in SSR / from initial render
  var _useSideNavVisibility = useSideNavVisibility({
      defaultCollapsed: true
    }),
    isExpandedOnDesktop = _useSideNavVisibility.isExpandedOnDesktop;
  return /*#__PURE__*/React.createElement("div", {
    className: ax([wrapperStyles.root, isExpandedOnDesktop && wrapperStyles.fullHeightSidebarExpanded])
  }, /*#__PURE__*/React.createElement("div", {
    ref: ref,
    "data-testid": testId,
    className: ax([innerStyles.root, innerStyles.fullHeightSidebar, fg('team25-eu-jira-logo-updates-csm-jsm') && innerStyles.jiraProductLogoUpdate, isExpandedOnDesktop && innerStyles.fullHeightSidebarExpanded])
  }, children));
});

/**
 * __TopNavStart__
 *
 * Wrapper for the top navigation actions on the inline-start (left) side of the top navigation.
 */
export function TopNavStart(_ref3) {
  var children = _ref3.children,
    testId = _ref3.testId,
    sideNavToggleButton = _ref3.sideNavToggleButton;
  var ref = useContext(TopNavStartAttachRef);
  var elementRef = useRef(null);

  // FIXME: unsafe pattern with Suspense, should use callback ref / store in state
  // Should handle the underlying HTMLElement changing without a remount
  useEffect(function () {
    ref(elementRef.current);
  }, [elementRef, ref]);

  // This needs the real `defaultCollapsed` state or will not SSR properly
  // TODO: lift `defaultCollapsed` state to `Root` (DSP-23683)
  // then context value will be correct in SSR / from initial render
  var _useSideNavVisibility2 = useSideNavVisibility({
      defaultCollapsed: true
    }),
    isExpandedOnDesktop = _useSideNavVisibility2.isExpandedOnDesktop;

  // For SSR assume desktop
  var _useState = useState(true),
    _useState2 = _slicedToArray(_useState, 2),
    isDesktop = _useState2[0],
    setIsDesktop = _useState2[1];
  // Set state to real value on client
  // This could result in some visible shift on mobile when hydrating SSR
  // TODO: review and improve SSR behavior as necessary (DSP-23817)
  useLayoutEffect(function () {
    // Checking this to avoid breaking tests when `matchMedia` is not mocked
    // Ideally we wouldn't cater to test environments, but this avoids introducing unnecessary friction
    if (typeof window !== 'undefined' && typeof window.matchMedia === 'function') {
      setIsDesktop(window.matchMedia('(min-width: 64rem)').matches);
    }
  }, []);
  UNSAFE_useMediaQuery('above.md', function (event) {
    setIsDesktop(event.matches);
  });
  var _useState3 = useState({
      type: 'idle'
    }),
    _useState4 = _slicedToArray(_useState3, 2),
    animationState = _useState4[0],
    setAnimationState = _useState4[1];

  // Used to prevent the reorder animations from running on the initial render.
  var isFirstRenderRef = useRef(true);
  var sideNavState = useContext(SideNavVisibilityState);
  useEffect(function () {
    if (!fg('navx-full-height-sidebar')) {
      return;
    }

    // Ignore renders until the side nav state is initialized
    // So that apps using the legacy API for setting side nav default state do not see
    // animations when they shouldn't
    if (sideNavState === null) {
      return;
    }
    if (isFirstRenderRef.current) {
      isFirstRenderRef.current = false;
    }
  }, [sideNavState]);

  // Using a stable ref to avoid re-running the animation layout effect when the toggle button prop value changes, which
  // can happen a lot (e.g. if the parent re-renders)
  var sideNavToggleButtonStableRef = useStableRef(sideNavToggleButton);
  useLayoutEffect(function () {
    if (!fg('navx-full-height-sidebar')) {
      return;
    }

    /**
     * This layout effect is used to animate the TopNavStart children elements to their new position after being reordered.
     * It is called when the sidebar's desktop expansion state changes.
     *
     * It works by first setting a translateX offset on the elements, used as the start position of the slide animation.
     * - For the toggle button, it's a fixed offset. It's combined with an opacity, so the exact offset doesn't matter too much.
     * - For the children wrapper (wrapping everything except the toggle button), an offset was chosen to make the animation
     * start position the exact same as the element's old position. See comments for `childrenWrapperStyles` for more details.
     *
     * On the next frame, the translateX offset is cleared, triggering the animation to the new position.
     */

    if (isFirstRenderRef.current) {
      // No animations on initial render.
      return;
    }
    if (!sideNavToggleButtonStableRef.current) {
      // If there is no toggle button, there should be no re-order animations.
      return;
    }

    // Set the translateX offsets so elements are ready to animate to their actual new position after being reordered
    setAnimationState({
      type: isExpandedOnDesktop ? 'expand' : 'collapse'
    });
    requestAnimationFrame(function () {
      // Clear translateX offsets on next frame to trigger animation to new position in a re-render
      setAnimationState({
        type: 'idle'
      });
    });

    // This layout effect is called when the sidebar's desktop expansion state changes.
  }, [isExpandedOnDesktop, sideNavToggleButtonStableRef]);
  var TopNavStartInner = fg('navx-full-height-sidebar') ? TopNavStartInnerFHS : TopNavStartInnerOld;
  return /*#__PURE__*/React.createElement(TopNavStartInner, {
    ref: elementRef,
    testId: testId
  }, !fg('navx-full-height-sidebar') && sideNavToggleButton, sideNavToggleButton && (!isDesktop || !isExpandedOnDesktop) && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement("div", {
    key: sideNavToggleButtonKey,
    className: ax([!isFirefox && toggleButtonWrapperStyles.root, !isFirefox && animationState.type === 'idle' && toggleButtonWrapperStyles.finalPosition, !isFirefox &&
    // Timing function is applied when the browser animates to the idle position.
    animationState.type === 'idle' && toggleButtonWrapperStyles.collapseAnimationTimingFunction, !isFirefox && animationState.type === 'collapse' && toggleButtonWrapperStyles.collapseAnimationStartPosition])
  }, sideNavToggleButton), fg('navx-full-height-sidebar') ? /*#__PURE__*/React.createElement("div", {
    className: ax([childrenWrapperStyles.root, !isFirefox && childrenWrapperStyles.animationBaseStyles, !isFirefox && animationState.type === 'idle' && childrenWrapperStyles.finalPosition, !isFirefox && animationState.type === 'expand' && childrenWrapperStyles.expandAnimationStartPosition, !isFirefox && animationState.type === 'collapse' && childrenWrapperStyles.collapseAnimationStartPosition])
  }, children) : children, sideNavToggleButton && isDesktop && isExpandedOnDesktop && fg('navx-full-height-sidebar') && /*#__PURE__*/React.createElement("div", {
    key: sideNavToggleButtonKey,
    className: ax([!isFirefox && toggleButtonWrapperStyles.root, toggleButtonWrapperStyles.alignEnd, !isFirefox && animationState.type === 'idle' && toggleButtonWrapperStyles.finalPosition, !isFirefox &&
    // Timing function is applied when the browser animates to the idle position.
    animationState.type === 'idle' && toggleButtonWrapperStyles.expandAnimationTimingFunction, !isFirefox && animationState.type === 'expand' && toggleButtonWrapperStyles.expandAnimationStartPosition])
  }, sideNavToggleButton));
}