import _extends from "@babel/runtime/helpers/extends";
// Copyright 1999-2021. Plesk International GmbH. All rights reserved.

/* eslint-disable react/no-deprecated */
import React, { isValidElement, useEffect, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { CLS_PREFIX } from '../../constants';
import Overlay from '../Overlay';
import { useClosingConfirmation } from '../ClosingConfirmation';
import Form from '../Form';
import Button from '../Button';
import Heading from '../Heading';
import Text from '../Text';
import Translate, { isLikeText } from '../Translate';
import { safeInvoke } from '../utils';

const isProps = value => value && typeof value === 'object' && ! /*#__PURE__*/isValidElement(value);
/**
 * `Dialog` is a modal window that asks users to make a decision or enter additional information.
 * @since 0.0.68
 */


const Dialog = ({
  baseClassName,
  className,
  children,
  actions,
  isOpen,
  banner,
  image,
  title,
  subtitle,
  cancelTitle,
  cancelButton,
  buttons,
  form,
  size,
  closable,
  onClose,
  closingConfirmation,
  canClose,
  ...props
}) => {
  const [isVisible, setIsVisible] = useState(isOpen);
  const {
    onCloseWithConfirmation,
    closingConfirmationDialog
  } = useClosingConfirmation({
    onClose: () => {
      setIsVisible(false);
      safeInvoke(onClose);
    },
    closingConfirmation
  });
  useEffect(() => {
    setIsVisible(isOpen);
  }, [isOpen]);

  const renderImage = (image, block) => {
    const classPrefix = `${baseClassName}__${block}`;

    if ( /*#__PURE__*/isValidElement(image)) {
      return /*#__PURE__*/React.createElement("div", {
        className: classPrefix
      }, image);
    }

    if (typeof image === 'string') {
      return /*#__PURE__*/React.createElement("div", {
        className: classPrefix
      }, /*#__PURE__*/React.createElement("img", {
        className: `${classPrefix}-inner`,
        src: image
      }));
    }

    return /*#__PURE__*/React.createElement("div", {
      className: classPrefix
    }, /*#__PURE__*/React.createElement("img", _extends({
      className: `${classPrefix}-inner`
    }, image)));
  };

  const getCancelButtonProps = () => {
    if (!closable) {
      return false;
    }

    if (cancelButton === false || form && form.cancelButton === false) {
      return false;
    }

    let props = {
      onClick: onCloseWithConfirmation,
      children: cancelTitle || /*#__PURE__*/React.createElement(Translate, {
        content: "Dialog.cancelButton",
        fallback: "Cancel"
      })
    };

    if (form && isProps(form.cancelButton)) {
      props = { ...props,
        ...form.cancelButton
      };
    }

    if (isProps(cancelButton)) {
      props = { ...props,
        ...cancelButton
      };
    }

    return props;
  };

  const renderButtons = () => {
    if (form) {
      return null;
    }

    let cancel;
    const cancelButtonProps = getCancelButtonProps();

    if (cancelButtonProps) {
      cancel = /*#__PURE__*/React.createElement(Button, cancelButtonProps);
    }

    if (buttons || cancel) {
      return /*#__PURE__*/React.createElement("div", {
        className: `${baseClassName}__buttons`
      }, buttons, cancel);
    }

    return null;
  };

  let childrenElement;

  if (form) {
    form.cancelButton = getCancelButtonProps();
    form.footerClassName = classNames(form.footerClassName, `${baseClassName}__form-footer`);
    form.applyButton = form.applyButton || false;
    childrenElement = /*#__PURE__*/React.createElement(Form, form, children);
  } else {
    childrenElement = children;
  }

  return /*#__PURE__*/React.createElement(Overlay, _extends({
    className: classNames(baseClassName, className),
    isOpen: isVisible,
    onClose: onCloseWithConfirmation,
    canCloseOnBackdropClick: canClose && closable,
    canCloseOnEscapePress: canClose && closable,
    size: size
  }, props), (title || subtitle || actions) && /*#__PURE__*/React.createElement("header", {
    className: `${baseClassName}__header`
  }, banner && renderImage(banner, 'banner'), /*#__PURE__*/React.createElement("div", {
    className: `${baseClassName}__header-inner`
  }, /*#__PURE__*/React.createElement("div", {
    className: `${baseClassName}__header-body`
  }, /*#__PURE__*/React.createElement("div", {
    className: `${baseClassName}__header-content`
  }, isLikeText(title) ? /*#__PURE__*/React.createElement(Heading, {
    level: "2",
    className: `${baseClassName}__title`
  }, title) : /*#__PURE__*/React.createElement("div", {
    className: `${baseClassName}__title`
  }, title), subtitle && /*#__PURE__*/React.createElement("div", {
    className: `${baseClassName}__subtitle`
  }, isLikeText(subtitle) ? /*#__PURE__*/React.createElement(Text, {
    intent: "muted"
  }, subtitle) : subtitle)), (actions || closable) && /*#__PURE__*/React.createElement("div", {
    className: `${baseClassName}__header-actions`
  }, actions, closable && /*#__PURE__*/React.createElement(Button, {
    className: `${baseClassName}__header-close`,
    disabled: !canClose,
    ghost: true,
    size: "lg",
    icon: "cross-mark",
    onClick: onCloseWithConfirmation
  }))))), /*#__PURE__*/React.createElement("div", {
    className: `${baseClassName}__content`
  }, image && renderImage(image, 'image'), childrenElement, renderButtons()), closingConfirmationDialog);
};

Dialog.propTypes = {
  /**
   * Toggles visibility.
   * @since 0.0.68
   */
  isOpen: PropTypes.bool,

  /**
   * Banner. Renders in front of content as wide as dialog.
   * @since 0.0.68
   */
  banner: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.element]),

  /**
   * Block with an image, placed at the side of the component
   * @since 3.25.0
   */
  sideBanner: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.element]),

  /**
   * Additional properties for the sideBanner
   * @since 3.25.0
   */
  sideBannerContainer: PropTypes.shape({
    /**
     * Values for css background property
     */
    background: PropTypes.string,

    /**
     * One of: center, flex-start, flex-end
     */
    align: PropTypes.oneOf(['center', 'flex-start', 'flex-end'])
  }),

  /**
   * Image. Renders into content.
   * @since 0.0.68
   */
  image: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.element]),

  /**
   * Title
   * @since 0.0.68
   */
  title: PropTypes.node,

  /**
   * The subtitle of the `Dialog`.
   * @since 4.0.0
   */
  subtitle: PropTypes.node,

  /**
   * Title of "cancel" button
   * @since 0.0.68
   * @deprecated Use `cancelButton` instead.
   */
  cancelTitle: PropTypes.node,

  /**
   * Cancel button visibility or custom configuration. It accepts all props of the `Button` component.
   * @since 3.13.0
   */
  cancelButton: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]),

  /**
   * Buttons except "cancel" button
   * @since 0.0.68
   */
  buttons: PropTypes.node,

  /**
   * Actions which will be shown in Dialog header
   * @since 1.2.0
   */
  actions: PropTypes.node,

  /**
   * Wraps children into [Form](#!/Form) if not empty.
   * @since 0.0.68
   */
  form: PropTypes.object,

  /**
   * Dialog width
   * @since 0.0.68
   */
  size: PropTypes.oneOf(['xs', 'sm', 'md', 'lg']),

  /**
   * If the value is false, the dialog cannot be closed and the Close button is hidden.
   * @since 1.2.0
   */
  closable: PropTypes.bool,

  /**
   * Disable close dialog button
   * @since 4.0.0
   */
  canClose: PropTypes.bool,

  /**
   * On close event handler. Called immediately after dialog closed by "cancel" button or "Esc" key.
   * @since 0.0.68
   */
  onClose: PropTypes.func,

  /**
   * Whether show or not a confirmation dialog on close.
   * @since 3.21.0
   */
  closingConfirmation: PropTypes.bool,

  /**
   * Content of the `DialogWindow`.
   * @since 0.0.68
   */
  children: PropTypes.node,

  /**
   * @ignore
   */
  className: PropTypes.string,

  /**
   * @ignore
   */
  baseClassName: PropTypes.string
};
Dialog.defaultProps = {
  isOpen: false,
  banner: undefined,
  sideBanner: undefined,
  sideBannerContainer: undefined,
  image: undefined,
  title: undefined,
  subtitle: undefined,
  cancelTitle: undefined,
  cancelButton: undefined,
  buttons: undefined,
  actions: undefined,
  form: undefined,
  size: 'md',
  closable: true,
  canClose: true,
  onClose: undefined,
  closingConfirmation: undefined,
  children: undefined,
  className: undefined,
  baseClassName: `${CLS_PREFIX}dialog`
};
export default Dialog;