import _defineProperty from "@babel/runtime/helpers/defineProperty";
var _class;
// Copyright 1999-2023. Plesk International GmbH. All rights reserved.

import { render } from 'react-dom';
import { Component, createRef } from 'react';
import { TransitionGroup, CSSTransition } from 'react-transition-group';
import classNames from 'classnames';
import { CLS_PREFIX, Z_INDEX_TOASTER } from '../../constants';
import Toast from '../Toast';
import Layer from '../Layer';
import { jsx as _jsx } from "react/jsx-runtime";
let toastId = 0;
/**
 * `Toaster` is used for notifying about events happened in the system. For example, about results of performed operations.
 * @since 0.0.42
 */
export default class Toaster extends Component {
  constructor() {
    super(...arguments);
    _defineProperty(this, "state", {
      toasts: []
    });
  }
  static getDerivedStateFromProps(_ref) {
    let {
      toasts,
      maxToastsNumber
    } = _ref;
    if (toasts) {
      return {
        toasts: toasts.slice(0, maxToastsNumber)
      };
    }
    return null;
  }
  isControlled() {
    return Boolean(this.props.toasts);
  }

  /**
   * Add a new toast
   *
   * `intent` - Visual intent color to apply to component. (Type: `oneOf` 'info', 'success', 'warning', 'danger'. *Required*.)<br>
   * `accent` - Contrast (light) version of the component. (Type: `boolean`. Default: 'undefined'.)<br>
   * `icon` - Name of icon or [Icon](#!/Icon) component. (Type: `oneOfType` 'string', 'object', 'element'. Default: `undefined`.)<br>
   * `message` - Message to display in the body of the toast. (Type: `any`. Default: `undefined`.)<br>
   * `onClose` - onClose handler. (Type: `func`. Default: `undefined`.)<br>
   * `closable` - Show close control (cross mark). (Type: `boolean`. Default: `true`.)<br>
   * `autoClosable` - Whether call `onClose` after 6 seconds or not.
   * Enabled by default when the position is "top-end" and a toast has "success" intent. (Type: `boolean`. Default: 'undefined'.)<br>
   * ---
   * @param {Object} props **Toast props**:
   * @returns {string} New toast key
   * @public
   */
  add(props) {
    const key = `toast-${toastId++}`;
    this.setState(_ref2 => {
      let {
        toasts
      } = _ref2;
      return {
        toasts: [{
          key,
          ...props
        }, ...toasts].slice(0, this.props.maxToastsNumber)
      };
    });
    return key;
  }

  /**
   * Update toast by key
   *
   * @param {string} key
   * @param {Object} props New props
   * @returns {string} Updated toast key
   * @public
   */
  update(key, props) {
    this.setState(_ref3 => {
      let {
        toasts
      } = _ref3;
      return {
        toasts: toasts.map(toast => toast.key === key ? {
          ...props,
          key
        } : toast)
      };
    });
    return key;
  }

  /**
   * Remove toast by key
   *
   * @param {string} key
   * @public
   */
  remove(key) {
    this.setState(_ref4 => {
      let {
        toasts
      } = _ref4;
      return {
        toasts: toasts.filter(toast => toast.key !== key)
      };
    });
  }

  /**
   * Clear all toasts
   *
   * @public
   */
  clear() {
    this.setState({
      toasts: []
    });
  }
  render() {
    const {
      baseClassName,
      className,
      toasts,
      maxToastsNumber,
      position,
      onToastClose,
      ...props
    } = this.props;
    let stack = this.state.toasts;
    if (position === 'bottom-end') {
      stack = [...stack];
      stack.reverse();
    }
    return /*#__PURE__*/_jsx(Layer, {
      level: Z_INDEX_TOASTER,
      children: /*#__PURE__*/_jsx("div", {
        className: classNames(baseClassName, {
          [`${baseClassName}--${position}`]: position
        }, className),
        ...props,
        children: /*#__PURE__*/_jsx(TransitionGroup, {
          component: "span",
          children: stack.map(toastProps => {
            const {
              intent
            } = toastProps;
            let {
              autoClosable
            } = toastProps;
            if (autoClosable === undefined && intent === 'success' && position === 'top-end') {
              autoClosable = true;
            }
            const toastRef = /*#__PURE__*/createRef();
            return /*#__PURE__*/_jsx(CSSTransition, {
              classNames: `${Toast.defaultProps.baseClassName}-`,
              timeout: {
                enter: 300,
                exit: 300
              },
              nodeRef: toastRef,
              children: /*#__PURE__*/_jsx(Toast, {
                ...toastProps,
                autoClosable: autoClosable,
                onClose: () => {
                  if (!this.isControlled()) {
                    this.remove(toastProps.key);
                  }
                  if (toastProps.onClose) {
                    toastProps.onClose();
                  }
                  if (onToastClose) {
                    onToastClose(toastProps.key);
                  }
                },
                innerRef: toastRef
              })
            }, toastProps.key);
          })
        })
      })
    });
  }
}
_class = Toaster;
// eslint-disable-next-line react/sort-comp
_defineProperty(Toaster, "defaultProps", {
  position: 'top-end',
  baseClassName: `${CLS_PREFIX}toaster`
});
_defineProperty(Toaster, "create", function () {
  let props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
  let container = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : document.body;
  const containerElement = document.createElement('div');
  container.appendChild(containerElement);
  return render( /*#__PURE__*/_jsx(_class, {
    ...props
  }), containerElement);
});