import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import React, { useEffect, useLayoutEffect, useMemo, useState } from 'react';
import { createPortal } from 'react-dom';
import { PortalBucket } from './PortalBucket';
import { PortalManager } from './PortalManager';
export function createPortalRendererComponent(portalManager) {
  return function PortalRenderer() {
    var _useState = useState(portalManager.getBuckets()),
      _useState2 = _slicedToArray(_useState, 2),
      buckets = _useState2[0],
      setBuckets = _useState2[1];
    useLayoutEffect(function () {
      portalManager.registerPortalRenderer(setBuckets);
      return function () {
        portalManager.unregisterPortalRenderer();
      };
    }, []);
    var portalsElements = useMemo(function () {
      return buckets.map(function (_, i) {
        return /*#__PURE__*/React.createElement(PortalBucket, {
          key: i,
          id: i,
          portalManager: portalManager
        });
      });
    }, [buckets]);
    return /*#__PURE__*/React.createElement(React.Fragment, null, portalsElements);
  };
}

/**
 * Creates a portal provider for managing multiple React portals. The provider
 * facilitates rendering, removing, and destroying portals managed by a given
 * PortalManager.
 *
 * @param {PortalManager} portalManager - An instance of a PortalManager which
 * is responsible for registering, managing, and destroying portals.
 * @returns {PortalProviderAPI} An object containing methods to render, remove, and destroy
 * portals.
 *  - `render(children, container, key)` Renders a new React portal with the given
 *    children, mounts it into the specified DOM container, and registers it
 *    with the PortalManager using a unique key.
 *  - `remove(key)` Removes a previously rendered portal identified by its key
 *    and deregisters it from the PortalManager.
 *  - `destroy()` Clears all portals managed by this provider and invokes the
 *    destroy method on the PortalManager to clean up any resources.
 *
 */
export var getPortalProviderAPI = function getPortalProviderAPI(portalManager) {
  var portalsMap = new Map();
  return {
    render: function render(children, container, key) {
      var portal = /*#__PURE__*/createPortal(children(), container, key);
      portalsMap.set(key, portalManager.registerPortal(key, portal));
    },
    remove: function remove(key) {
      var _portalsMap$get;
      (_portalsMap$get = portalsMap.get(key)) === null || _portalsMap$get === void 0 || _portalsMap$get();
      portalsMap.delete(key);
    },
    destroy: function destroy() {
      portalsMap.clear();
      portalManager.destroy();
    }
  };
};

/**
 * Initializes PortalManager and creates PortalRendererComponent. Offers an API (portalProviderAPI) for managing portals.
 * @returns {[PortalProviderAPI, PortalRendererComponent]} An array containing two elements:
 *         1. portalProviderAPI: An object providing an API for rendering and removing portals.
 *         2. PortalRenderer: A React component responsible for rendering the portal content.
 */
export function usePortalProvider() {
  var portalManager = useMemo(function () {
    return new PortalManager();
  }, []);
  var PortalRenderer = useMemo(function () {
    return createPortalRendererComponent(portalManager);
  }, [portalManager]);
  var portalProviderAPI = useMemo(function () {
    return getPortalProviderAPI(portalManager);
  }, [portalManager]);

  // Cleanup on unmount
  useEffect(function () {
    return function () {
      portalProviderAPI.destroy();
    };
  }, [portalManager, portalProviderAPI]);
  return [portalProviderAPI, PortalRenderer];
}