import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose";
import _inheritsLoose from "@babel/runtime/helpers/esm/inheritsLoose";
var _excluded = ["style", "children", "delta", "priority", "applyZIndex", "coverChildren", "createStackingContext", "wrapperRef", "useWrapper"];
var _class, _ZIndex;
import React from 'react';
import { globalObject, isBrowser } from '@skbkontur/global-object';
import isEqual from 'lodash.isequal';
import warning from 'warning';
import { callChildRef } from "../../../lib/callChildRef/callChildRef";
import { rootNode } from "../../../lib/rootNode";
import { createPropsGetter } from "../../../lib/createPropsGetter";
import { isInstanceOf } from "../../../lib/isInstanceOf";
import { LoaderDataTids } from "../../../components/Loader";
import { PORTAL_INLET_ATTR, PORTAL_OUTLET_ATTR } from "../../RenderContainer";
import { incrementZIndex, removeZIndex, upperBorder, componentPriorities } from "../ZIndexStorage";
var DEFAULT_ZINDEX_CONTEXT = {
  parentLayerZIndex: 0,
  maxZIndex: Infinity
};
var ZIndexContext = /*#__PURE__*/React.createContext(DEFAULT_ZINDEX_CONTEXT);
ZIndexContext.displayName = 'ZIndexContext';
export var ZIndex = rootNode(_class = (_ZIndex = /*#__PURE__*/function (_React$Component) {
  function ZIndex(props) {
    var _this;
    _this = _React$Component.call(this, props) || this;
    _this.state = {
      zIndex: 0,
      DOMZIndexContext: null
    };
    _this.getProps = createPropsGetter(ZIndex.defaultProps);
    _this.zIndexContext = null;
    _this.wrapperRef = function (element) {
      var wrapperRef = _this.props.wrapperRef;
      _this.setRootNode(element);
      wrapperRef && callChildRef(wrapperRef, element);
      element && _this.tryGetContextByDOM(element);
    };
    _this.increment = function () {
      var _this$getProps = _this.getProps(),
        priority = _this$getProps.priority,
        delta = _this$getProps.delta;
      return incrementZIndex(priority, delta);
    };
    _this.tryGetContextByDOM = function (element) {
      if (_this.props.applyZIndex && isEqual(DEFAULT_ZINDEX_CONTEXT, _this.zIndexContext) && _this.state.DOMZIndexContext === null) {
        var _element$parentElemen;
        var DOMZIndexContext = DEFAULT_ZINDEX_CONTEXT;
        var portal = (_element$parentElemen = element.parentElement) == null ? void 0 : _element$parentElemen.closest("[" + PORTAL_OUTLET_ATTR + "]");
        if (isInstanceOf(portal, globalObject.HTMLElement)) {
          var _globalObject$documen, _noscript$parentEleme;
          var portalID = portal.getAttribute(PORTAL_OUTLET_ATTR);
          var noscript = (_globalObject$documen = globalObject.document) == null ? void 0 : _globalObject$documen.querySelector("noscript[" + PORTAL_INLET_ATTR + "=\"" + portalID + "\"]");
          var parent = noscript == null || (_noscript$parentEleme = noscript.parentElement) == null ? void 0 : _noscript$parentEleme.closest('[style*=z-index]');
          if (isInstanceOf(parent, globalObject.HTMLElement)) {
            var _parent$parentElement;
            var newZIndex = Number(parent.style.zIndex || 0);
            var maxZIndex = Infinity;
            if (((_parent$parentElement = parent.parentElement) == null ? void 0 : _parent$parentElement.dataset.tid) === LoaderDataTids.veil) {
              maxZIndex = _this.calcZIndex(newZIndex, maxZIndex);
            }
            DOMZIndexContext = {
              maxZIndex: maxZIndex,
              parentLayerZIndex: newZIndex
            };
          }
        }
        _this.setState({
          DOMZIndexContext: DOMZIndexContext
        });
      }
    };
    _this.state.zIndex = _this.increment();
    return _this;
  }
  _inheritsLoose(ZIndex, _React$Component);
  var _proto = ZIndex.prototype;
  _proto.validateProps = function validateProps(delta) {
    warning((delta || ZIndex.defaultProps.delta) > 0, "[ZIndex]: Prop 'delta' must be greater than 0, received " + delta);
    warning(Math.trunc(delta || ZIndex.defaultProps.delta) === delta, "[ZIndex]: Prop 'delta' must be integer, received " + delta);
  };
  _proto.componentDidUpdate = function componentDidUpdate(prevProps) {
    var props = this.getProps();
    this.validateProps(props.delta);
    if (prevProps.priority !== props.priority || prevProps.delta !== props.delta) {
      removeZIndex(this.state.zIndex);
      this.setState({
        zIndex: this.increment()
      });
    }
  };
  _proto.componentWillUnmount = function componentWillUnmount() {
    removeZIndex(this.state.zIndex);
  };
  _proto.render = function render() {
    var _this2 = this;
    var _this$getProps2 = this.getProps(),
      style = _this$getProps2.style,
      children = _this$getProps2.children,
      delta = _this$getProps2.delta,
      priority = _this$getProps2.priority,
      applyZIndex = _this$getProps2.applyZIndex,
      coverChildren = _this$getProps2.coverChildren,
      createStackingContext = _this$getProps2.createStackingContext,
      wrapperRef = _this$getProps2.wrapperRef,
      useWrapper = _this$getProps2.useWrapper,
      rest = _objectWithoutPropertiesLoose(_this$getProps2, _excluded);
    var wrapperStyle = {};
    return /*#__PURE__*/React.createElement(ZIndexContext.Consumer, null, function (context) {
      _this2.zIndexContext = context;
      var currentZIndexContext = _this2.state.DOMZIndexContext && isEqual(context, DEFAULT_ZINDEX_CONTEXT) ? _this2.state.DOMZIndexContext : context;
      var parentLayerZIndex = currentZIndexContext.parentLayerZIndex,
        maxZIndex = currentZIndexContext.maxZIndex;
      var newZIndexContext = currentZIndexContext;
      var newZIndex = 0;
      if (applyZIndex) {
        newZIndex = _this2.calcZIndex(parentLayerZIndex, maxZIndex);
        wrapperStyle.zIndex = newZIndex;
        newZIndexContext = coverChildren ? {
          parentLayerZIndex: parentLayerZIndex,
          maxZIndex: newZIndex
        } : {
          parentLayerZIndex: newZIndex,
          maxZIndex: Number.isFinite(maxZIndex) ? newZIndex : Infinity
        };
        if (createStackingContext) {
          isBrowser(globalObject) && 'isolation' in globalObject.document.body.style ? wrapperStyle.isolation = 'isolate' : wrapperStyle.transform = 'rotate(0)';
        }
      }
      var child = !useWrapper ? children : /*#__PURE__*/React.createElement("div", _extends({
        style: _extends({}, style, wrapperStyle),
        ref: _this2.wrapperRef
      }, rest), children);
      return /*#__PURE__*/React.createElement(ZIndexContext.Provider, {
        value: newZIndexContext
      }, child);
    });
  };
  _proto.calcZIndex = function calcZIndex(parentLayerZIndex, maxZIndex) {
    var newZIndex = this.state.zIndex;
    if (Number.isFinite(maxZIndex)) {
      var allowedValuesIntervalLength = maxZIndex - parentLayerZIndex;
      var scale = upperBorder / allowedValuesIntervalLength;
      newZIndex = Math.ceil(newZIndex / scale);
    }
    newZIndex += parentLayerZIndex;
    return newZIndex;
  };
  return ZIndex;
}(React.Component), _ZIndex.priorities = componentPriorities, _ZIndex.__KONTUR_REACT_UI__ = 'ZIndex', _ZIndex.displayName = 'ZIndex', _ZIndex.defaultProps = {
  delta: 10,
  priority: 0,
  style: {},
  applyZIndex: true,
  coverChildren: false,
  createStackingContext: false,
  useWrapper: true
}, _ZIndex)) || _class;