import _createClass from "@babel/runtime/helpers/esm/createClass";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
import React from 'react';
import { CSSTransition } from 'react-transition-group';
import FocusLock from 'react-focus-lock';
import { globalObject } from '@skbkontur/global-object';
import { isNonNullable, isReactUIInstance } from "../../../lib/utils";
import { isKeyEscape } from "../../../lib/events/keyboard/identifiers";
import * as LayoutEvents from "../../../lib/LayoutEvents";
import { stopPropagation } from "../../../lib/events/stopPropagation";
import { HideBodyVerticalScroll } from "../../../internal/HideBodyVerticalScroll";
import { ModalStack } from "../../../lib/ModalStack";
import { RenderContainer } from "../../../internal/RenderContainer";
import { RenderLayer } from "../../../internal/RenderLayer";
import { ZIndex } from "../../../internal/ZIndex";
import { ThemeContext } from "../../../lib/theming/ThemeContext";
import { CommonWrapper } from "../../../internal/CommonWrapper";
import { cx } from "../../../lib/theming/Emotion";
import { isTestEnv } from "../../../lib/currentEnvironment";
import { ResponsiveLayout } from "../../ResponsiveLayout";
import { createPropsGetter } from "../../../lib/createPropsGetter";
import { isInstanceOf } from "../../../lib/isInstanceOf";
import { isThemeGTE } from "../../../lib/theming/ThemeHelpers";
import { SidePageBody } from "../SidePageBody";
import { SidePageContainer } from "../SidePageContainer";
import { SidePageContext } from "../SidePageContext";
import { SidePageFooter } from "../SidePageFooter";
import { SidePageHeader } from "../SidePageHeader";
import { styles } from "../SidePage.styles";
export var SidePageDataTids = {
  root: 'SidePage__root',
  container: 'SidePage__container'
};
var TRANSITION_TIMEOUT = 200;

/**
 * `SidePage` — это модальное окно, которое открывается поверх основной страницы и занимает всю высоту окна браузера.
 *
 * Используйте его, когда нужно сохранить контекст и показать большое количество данных.
 *
 * Содержит в себе три компоненты: `SidePage.Header`, `SidePage.Body` и `SidePage.Footer`.
 *
 * Для отображения серой плашки в футере в компонент `Footer` необходимо передать пропс `panel`.
 */
export var SidePage = /*#__PURE__*/function (_React$Component) {
  function SidePage() {
    var _this;
    for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
      args[_key] = arguments[_key];
    }
    _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this;
    _this.state = {
      hasHeader: false,
      hasFooter: false,
      hasPanel: false
    };
    _this.stackSubscription = null;
    _this.layout = null;
    _this.header = null;
    _this.footer = null;
    _this.rootRef = /*#__PURE__*/React.createRef();

    /**
     * Обновляет разметку компонента.
     * @public
     */
    _this.updateLayout = function () {
      var _this$header, _this$footer;
      (_this$header = _this.header) == null || _this$header.update();
      (_this$footer = _this.footer) == null || _this$footer.update();
    };
    _this.getProps = createPropsGetter(SidePage.defaultProps);
    _this.getSidePageContextProps = function () {
      return {
        hasHeader: _this.state.hasHeader,
        hasFooter: _this.state.hasFooter,
        hasPanel: _this.state.hasPanel,
        requestClose: _this.requestClose,
        getWidth: _this.getWidth,
        updateLayout: _this.updateLayout,
        headerRef: _this.headerRef,
        footerRef: _this.footerRef,
        setHasHeader: _this.setHasHeader,
        setHasFooter: _this.setHasFooter,
        setHasPanel: _this.setHasPanel
      };
    };
    _this.getWidth = function () {
      if (!_this.layout) {
        return 'auto';
      }
      return _this.layout.clientWidth;
    };
    _this.handleStackChange = function (stack) {
      var sidePages = stack.filter(function (x) {
        return isReactUIInstance(x, 'SidePage') && x.props.fromLeft === _this.props.fromLeft;
      });
      var currentSidePagePosition = sidePages.indexOf(_this);
      var hasMargin = sidePages.length > 1 && currentSidePagePosition === sidePages.length - 1;
      var hasShadow = sidePages.length < 3 || currentSidePagePosition > sidePages.length - 3;
      var hasBackground = ModalStack.isBlocking(_this);
      _this.setState({
        stackPosition: stack.indexOf(_this),
        hasMargin: hasMargin,
        hasShadow: hasShadow,
        hasBackground: hasBackground
      });
    };
    _this.handleClickOutside = function (e) {
      if (_this.state.stackPosition === 0 && !_this.props.ignoreBackgroundClick) {
        // ignore mousedown on window scrollbar
        if (isInstanceOf(e, globalObject.MouseEvent) && globalObject.document && e.clientX > globalObject.document.documentElement.clientWidth) {
          return;
        }
        _this.requestClose();
      }
    };
    _this.handleKeyDown = function (e) {
      if (_this.state.stackPosition !== 0) {
        return;
      }
      if (isKeyEscape(e)) {
        stopPropagation(e);
        _this.requestClose();
      }
    };
    _this.requestClose = function () {
      if (_this.props.disableClose) {
        return;
      }
      if (_this.props.onClose) {
        _this.props.onClose();
      }
    };
    _this.headerRef = function (ref) {
      _this.header = ref;
    };
    _this.footerRef = function (ref) {
      _this.footer = ref;
    };
    _this.layoutRef = function (ref) {
      _this.layout = ref;
    };
    _this.setHasHeader = function (hasHeader) {
      if (hasHeader === void 0) {
        hasHeader = true;
      }
      _this.state.hasHeader !== hasHeader && _this.setState({
        hasHeader: hasHeader
      });
    };
    _this.setHasFooter = function (hasFooter) {
      if (hasFooter === void 0) {
        hasFooter = true;
      }
      _this.state.hasFooter !== hasFooter && _this.setState({
        hasFooter: hasFooter
      });
    };
    _this.setHasPanel = function (hasPanel) {
      if (hasPanel === void 0) {
        hasPanel = false;
      }
      _this.state.hasPanel !== hasPanel && _this.setState({
        hasPanel: hasPanel
      });
    };
    return _this;
  }
  _inheritsLoose(SidePage, _React$Component);
  var _proto = SidePage.prototype;
  _proto.componentDidMount = function componentDidMount() {
    globalObject.addEventListener == null || globalObject.addEventListener('keydown', this.handleKeyDown);
    this.stackSubscription = ModalStack.add(this, this.handleStackChange);
  };
  _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
    if (prevProps.blockBackground !== this.props.blockBackground) {
      ModalStack.rerender();
      this.setState({
        hasBackground: ModalStack.isBlocking(this)
      });
    }
  };
  _proto.componentWillUnmount = function componentWillUnmount() {
    globalObject.removeEventListener == null || globalObject.removeEventListener('keydown', this.handleKeyDown);
    if (isNonNullable(this.stackSubscription)) {
      this.stackSubscription.remove();
    }
    ModalStack.remove(this);
  };
  _proto.render = function render() {
    var _this2 = this;
    return /*#__PURE__*/React.createElement(ThemeContext.Consumer, null, function (theme) {
      _this2.theme = theme;
      return _this2.renderMain();
    });
  };
  _proto.renderMain = function renderMain() {
    var _this3 = this;
    var _this$props = this.props,
      blockBackground = _this$props.blockBackground,
      onOpened = _this$props.onOpened;
    var disableAnimations = this.getProps().disableAnimations;
    var versionGTE5_2 = isThemeGTE(this.theme, '5.2');
    return /*#__PURE__*/React.createElement(ResponsiveLayout, null, function (_ref) {
      var isMobile = _ref.isMobile;
      return /*#__PURE__*/React.createElement(RenderContainer, null, /*#__PURE__*/React.createElement(CommonWrapper, _this3.props, /*#__PURE__*/React.createElement(ZIndex, {
        priority: 'Sidepage',
        onScroll: LayoutEvents.emit,
        createStackingContext: true,
        style: {
          position: 'absolute'
        }
      }, (versionGTE5_2 || !isMobile) && blockBackground && _this3.renderShadow(), /*#__PURE__*/React.createElement(CSSTransition, {
        "in": true,
        classNames: _this3.getTransitionNames(),
        appear: !disableAnimations,
        enter: !disableAnimations,
        exit: false,
        timeout: {
          enter: TRANSITION_TIMEOUT,
          exit: TRANSITION_TIMEOUT
        },
        nodeRef: _this3.rootRef,
        onEntered: onOpened
      }, _this3.renderContainer(isMobile)), isMobile && /*#__PURE__*/React.createElement(HideBodyVerticalScroll, null))));
    });
  };
  _proto.renderContainer = function renderContainer(isMobile) {
    var _cx, _cx2;
    var _this$props2 = this.props,
      mobileWidth = _this$props2.mobileWidth,
      blockBackground = _this$props2.blockBackground,
      fromLeft = _this$props2.fromLeft,
      ariaLabel = _this$props2['aria-label'];
    var _this$getProps = this.getProps(),
      offset = _this$getProps.offset,
      role = _this$getProps.role;
    var widthDesktop = this.props.width || (blockBackground ? 800 : 500);
    var widthMobile = this.props.mobileWidth || '100%';
    var width = isMobile ? widthMobile : widthDesktop;
    return /*#__PURE__*/React.createElement("div", {
      "aria-modal": true,
      role: role,
      "aria-label": ariaLabel,
      "data-tid": SidePageDataTids.root,
      className: cx((_cx = {}, _cx[styles.root()] = true, _cx)),
      ref: this.rootRef,
      onScroll: LayoutEvents.emit,
      style: isMobile && !isThemeGTE(this.theme, '5.2') ? {
        width: mobileWidth || '100%'
      } : {
        width: width,
        right: fromLeft ? 'auto' : offset,
        left: fromLeft ? offset : 'auto'
      }
    }, /*#__PURE__*/React.createElement(FocusLock, {
      disabled: this.isFocusLockDisabled,
      autoFocus: false,
      className: styles.focusLock()
    }, /*#__PURE__*/React.createElement(RenderLayer, {
      onClickOutside: this.handleClickOutside,
      active: true
    }, /*#__PURE__*/React.createElement("div", {
      "data-tid": SidePageDataTids.container,
      className: cx(styles.wrapper(this.theme), (_cx2 = {}, _cx2[styles.wrapperLeft()] = fromLeft, _cx2[styles.wrapperMarginLeft()] = this.state.hasMargin && fromLeft, _cx2[styles.wrapperMarginRight()] = this.state.hasMargin && !fromLeft, _cx2[styles.shadow(this.theme)] = this.state.hasShadow, _cx2)),
      ref: this.layoutRef
    }, /*#__PURE__*/React.createElement(SidePageContext.Provider, {
      value: this.getSidePageContextProps()
    }, this.props.children)))));
  };
  _proto.renderShadow = function renderShadow() {
    var _cx3;
    return /*#__PURE__*/React.createElement("div", {
      className: styles.overlay(),
      onScroll: LayoutEvents.emit
    }, /*#__PURE__*/React.createElement(HideBodyVerticalScroll, {
      key: "hbvs"
    }), /*#__PURE__*/React.createElement("div", {
      key: "overlay",
      className: cx((_cx3 = {}, _cx3[styles.background()] = true, _cx3[styles.backgroundGray(this.theme)] = this.state.hasBackground, _cx3))
    }));
  };
  _proto.getTransitionNames = function getTransitionNames() {
    var transition = this.props.fromLeft ? styles.transitionRight : styles.transitionLeft;
    return {
      enter: transition(),
      enterActive: styles.transitionActive(),
      exit: styles.transitionLeave(),
      exitActive: styles.transitionLeaveActive(),
      appear: transition(),
      appearActive: styles.transitionActive()
    };
  };
  return _createClass(SidePage, [{
    key: "isFocusLockDisabled",
    get: function get() {
      var _this$getProps2 = this.getProps(),
        disableFocusLock = _this$getProps2.disableFocusLock;
      var blockBackground = this.props.blockBackground;
      if (!blockBackground) {
        return true;
      }
      if (disableFocusLock !== undefined) {
        return disableFocusLock;
      }
      return false;
    }
  }]);
}(React.Component);
SidePage.__KONTUR_REACT_UI__ = 'SidePage';
SidePage.displayName = 'SidePage';
SidePage.Header = SidePageHeader;
SidePage.Body = SidePageBody;
SidePage.Footer = SidePageFooter;
SidePage.Container = SidePageContainer;
SidePage.defaultProps = {
  disableAnimations: isTestEnv,
  offset: 0,
  role: 'dialog'
};