'use strict';

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

var _rollupPluginBabelHelpers = require('../../_virtual/_rollupPluginBabelHelpers.js');
var React = require('react');
var ModalContext = require('../Modal/ModalContext.js');
var ClientOnlyPortal = require('./ClientOnlyPortal.js');
var Popup_styles = require('./Popup.styles.js');
var react = require('../../utils/react.js');
var canUseDOM = require('../../utils/canUseDOM.js');
var Portal = require('../Portal/Portal.js');

function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }

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

var POPUP_PORTAL_ID = 'plasma-popup-root';

/**
 * INFO:
 * Глобальный координатор overflow для нескольких экземпляров PopupProvider.
 * Каждый PopupProvider независимо управляет своими items, но overflow на body — общий ресурс.
 * Используется Set с ID провайдеров вместо счётчика — Set.add/delete идемпотентны,
 * поэтому повторные вызовы при ремаунте (hydration mismatch, Strict Mode) не ломают состояние.
 * Overflow сохраняется при ∅→1 и восстанавливается при 1→∅.
 */
var globalOverflowState = {
  activeProviders: /*#__PURE__*/new Set(),
  savedOverflowY: ''
};
var lockBodyOverflow = function lockBodyOverflow(providerId) {
  if (globalOverflowState.activeProviders.has(providerId)) {
    return;
  }
  if (globalOverflowState.activeProviders.size === 0) {
    globalOverflowState.savedOverflowY = document.body.style.overflowY;
  }
  globalOverflowState.activeProviders.add(providerId);
  document.body.style.overflowY = 'hidden';
};
var unlockBodyOverflow = function unlockBodyOverflow(providerId) {
  var wasActive = globalOverflowState.activeProviders["delete"](providerId);
  if (wasActive && globalOverflowState.activeProviders.size === 0) {
    document.body.style.overflowY = globalOverflowState.savedOverflowY;
  }
};
var initialItems = /*#__PURE__*/new Map();
var PopupContext = /*#__PURE__*/React.createContext({
  items: initialItems,
  rootId: POPUP_PORTAL_ID,
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  register: function register(_info) {
    throw new Error('Function not implemented. Add PopupProvider');
  },
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  unregister: function unregister(_id) {
    throw new Error('Function not implemented. Add PopupProvider');
  }
});
var usePopupContext = function usePopupContext() {
  return React.useContext(PopupContext);
};

// TODO: #1599
var PopupProvider = function PopupProvider(_ref) {
  var _StyledPortal, _StyledPortal2, _StyledPortal3;
  var children = _ref.children,
    providerFrame = _ref.providerFrame,
    UNSAFE_SSR_ENABLED = _ref.UNSAFE_SSR_ENABLED;
  var _useState = React.useState(initialItems),
    _useState2 = _rollupPluginBabelHelpers.slicedToArray(_useState, 2),
    items = _useState2[0],
    setItems = _useState2[1];
  var uuid = react.safeUseId();
  var rootId = "".concat(POPUP_PORTAL_ID, "-").concat(uuid);
  React.useEffect(function () {
    if (!canUseDOM.canUseDOM) {
      return;
    }
    var currentHasModals = ModalContext.hasModals(Array.from(items.values()));
    if (currentHasModals) {
      lockBodyOverflow(rootId);
    } else {
      unlockBodyOverflow(rootId);
    }
  }, [items, rootId]);

  /**
   * INFO:
   * Cleanup при unmount: если PopupProvider размонтируется с открытой модалкой
   * (например, при смене роута или hydration mismatch), провайдер удаляется из Set
   * и overflow восстанавливается, если активных провайдеров не осталось.
   * Выделен в отдельный эффект, чтобы не срабатывать при каждой смене items.
   */
  React.useEffect(function () {
    return function () {
      unlockBodyOverflow(rootId);
    };
  }, [rootId]);
  var register = function register(info) {
    if (!canUseDOM.canUseDOM) {
      return;
    }
    setItems(function (prevItems) {
      var newItems = new Map(prevItems);
      newItems.set(info.id, info);
      return newItems;
    });
  };
  var unregister = function unregister(id) {
    if (!canUseDOM.canUseDOM) {
      return;
    }
    setItems(function (prevItems) {
      if (!prevItems.has(id)) {
        return prevItems;
      }
      var newItems = new Map(prevItems);
      newItems["delete"](id);
      return newItems;
    });
  };
  var context = {
    items: items,
    rootId: rootId,
    register: register,
    unregister: unregister
  };
  var getDefaultPortal = function getDefaultPortal() {
    if (typeof providerFrame !== 'string' && providerFrame && providerFrame.current && canUseDOM.canUseDOM) {
      return /*#__PURE__*/React__default.default.createElement(Portal.Portal, {
        container: providerFrame.current
      }, _StyledPortal || (_StyledPortal = /*#__PURE__*/React__default.default.createElement(Popup_styles.StyledPortal, {
        id: rootId
      })));
    }
    var withFrameId = typeof providerFrame === 'string' && providerFrame !== 'document';
    var containerElement = withFrameId && canUseDOM.canUseDOM && document.getElementById(providerFrame);
    if (containerElement) {
      return /*#__PURE__*/React__default.default.createElement(Portal.Portal, {
        container: containerElement
      }, _StyledPortal2 || (_StyledPortal2 = /*#__PURE__*/React__default.default.createElement(Popup_styles.StyledPortal, {
        id: rootId
      })));
    }
    return /*#__PURE__*/React__default.default.createElement(Portal.Portal, {
      container: document.body
    }, _StyledPortal3 || (_StyledPortal3 = /*#__PURE__*/React__default.default.createElement(Popup_styles.StyledPortal, {
      id: rootId
    })));
  };
  return /*#__PURE__*/React__default.default.createElement(PopupContext.Provider, {
    value: context
  }, children, UNSAFE_SSR_ENABLED ? /*#__PURE__*/React__default.default.createElement(ClientOnlyPortal.ClientOnlyPortal, null, /*#__PURE__*/React__default.default.createElement(Popup_styles.StyledPortal, {
    id: rootId
  })) : getDefaultPortal());
};

exports.POPUP_PORTAL_ID = POPUP_PORTAL_ID;
exports.PopupProvider = PopupProvider;
exports.usePopupContext = usePopupContext;
