import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
// Copyright 1999-2020. Plesk International GmbH. All rights reserved.
import { render } from 'react-dom';
import React, { 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 OnDarkContext from '../OnDarkContext';
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(...args) {
    super(...args);

    _defineProperty(this, "state", {
      toasts: []
    });
  }

  static getDerivedStateFromProps({
    toasts,
    maxToastsNumber
  }) {
    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>
   * `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-".concat(toastId++);
    this.setState(({
      toasts
    }) => ({
      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(({
      toasts
    }) => ({
      toasts: toasts.map(toast => toast.key === key ? { ...props,
        key
      } : toast)
    }));
    return key;
  }
  /**
   * Remove toast by key
   *
   * @param {string} key
   * @public
   */


  remove(key) {
    this.setState(({
      toasts
    }) => ({
      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__*/React.createElement(OnDarkContext.Provider, {
      value: true
    }, /*#__PURE__*/React.createElement(Layer, {
      level: Z_INDEX_TOASTER
    }, /*#__PURE__*/React.createElement("div", _extends({
      className: classNames(baseClassName, {
        ["".concat(baseClassName, "--").concat(position)]: position
      }, className)
    }, props), /*#__PURE__*/React.createElement(TransitionGroup, {
      component: "span"
    }, 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__*/React.createElement(CSSTransition, {
        key: toastProps.key,
        classNames: "".concat(Toast.defaultProps.baseClassName, "-"),
        timeout: {
          enter: 300,
          exit: 300
        },
        nodeRef: toastRef
      }, /*#__PURE__*/React.createElement(Toast, _extends({}, toastProps, {
        autoClosable: autoClosable,
        onClose: () => {
          if (!this.isControlled()) {
            this.remove(toastProps.key);
          }

          if (toastProps.onClose) {
            toastProps.onClose();
          }

          if (onToastClose) {
            onToastClose(toastProps.key);
          }
        },
        innerRef: toastRef
      })));
    })))));
  }

}

_defineProperty(Toaster, "defaultProps", {
  position: 'top-end',
  baseClassName: "".concat(CLS_PREFIX, "toaster")
});

_defineProperty(Toaster, "create", (props = {}, container = document.body) => {
  const containerElement = document.createElement('div');
  container.appendChild(containerElement);
  return render( /*#__PURE__*/React.createElement(Toaster, props), containerElement);
});