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

/* eslint-disable react/no-deprecated */
import React, { cloneElement, isValidElement, useContext, useState } from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import { CLS_PREFIX } from '../../constants';
import Icon from '../Icon';
import Spinner from '../Spinner';
import Tooltip from '../Tooltip';
const oldIconNames = {
  "customize-order": "arrows-four-directions",
  download: "arrow-down-tray",
  edit: "pencil",
  folder: "folder-closed",
  "globe-alt": "globe",
  "import": "arrow-down-in",
  invisible: "eye-closed",
  link: "chain",
  lock: "lock-closed",
  "ok-circle": "check-mark-circle",
  "question-circle": "question-mark-circle",
  "security-scan": "shield",
  settings: "sliders",
  suspend: "sleep",
  unlock: "lock-open",
  upload: "arrow-up-tray",
  visible: "eye"
};
import ResponsiveContext from '../ResponsiveContext';
import OnDarkContext from '../OnDarkContext';

const renderIcon = ({
  baseClassName,
  icon,
  size,
  empty
}) => Icon.create(oldIconNames[icon] || icon, {
  className: `${baseClassName}__icon`,
  size: size === 'lg' || empty ? '16' : '12'
});

const renderCaret = ({
  baseClassName,
  size,
  caret
}) => {
  let caretElement;

  if (typeof caret === 'boolean' && caret) {
    caretElement = /*#__PURE__*/React.createElement(Icon, {
      name: "chevron-down",
      size: size === 'lg' ? '16' : '12'
    });
  } else {
    caretElement = caret;
  }

  if ( /*#__PURE__*/isValidElement(caretElement)) {
    caretElement = /*#__PURE__*/cloneElement(caretElement, {
      className: classNames(`${baseClassName}__caret`, caretElement.props.className)
    });
  }

  return caretElement;
};
/**
 * `Button` component is used for executing actions, changing the application state, opening forms or dialog windows, and submitting data.
 * As a rule, you should not use buttons for navigation between individual pages (use `Link` instead).
 * @since 0.0.37
 */


const Button = ({
  baseClassName,
  className,
  component: Tag,
  size,
  intent,
  ghost,
  selected: selectedProp,
  onToggle,
  state,
  icon,
  caret,
  fill,
  tooltip,
  children,
  arrow,
  disabled,
  ...props
}) => {
  const [selectedState, setSelectedState] = useState(false);

  const handleToggle = () => {
    setSelectedState(!selectedState);
    return !selectedState;
  };

  const isCollapsed = useContext(ResponsiveContext);
  const componentProps = {};

  if (Tag === 'button') {
    componentProps.type = 'button';
  } else if (Tag === 'a') {
    componentProps.role = 'button';
    componentProps.tabIndex = 0;

    if (disabled) {
      props.href = undefined;
    }
  }

  if (props.onClick && disabled) {
    props.onClick = e => {
      e.preventDefault();
    };
  }

  let childrenElement = children;
  let tooltipElement = tooltip;

  if (isCollapsed && icon && children) {
    childrenElement = null;

    if (!tooltip) {
      tooltipElement = children;
    }
  }

  if (!props.onClick && onToggle) {
    props.onClick = e => {
      e.preventDefault();
      onToggle(handleToggle());
    };
  }

  const selected = selectedProp === undefined ? selectedState : selectedProp;

  if (selectedProp !== undefined || onToggle) {
    componentProps['aria-pressed'] = String(selected);
  }

  const isArrowButton = arrow === 'forward' || arrow === 'backward';
  const hasAriaDisabled = Tag === 'button' && disabled && tooltip;
  let button = /*#__PURE__*/React.createElement(Tag, _extends({
    className: classNames(baseClassName, {
      [`${baseClassName}--${size}`]: size,
      [`${baseClassName}--${intent}`]: intent && !ghost,
      [`${baseClassName}--ghost`]: ghost,
      [`${baseClassName}--${state}`]: state,
      [`${baseClassName}--selected`]: selected,
      [`${baseClassName}--disabled`]: disabled,
      [`${baseClassName}--empty`]: !childrenElement,
      [`${baseClassName}--caret`]: caret,
      [`${baseClassName}--fill`]: fill,
      [`${baseClassName}--arrow ${baseClassName}--arrow-${arrow}`]: isArrowButton && !ghost,
      [`${baseClassName}--on-dark`]: useContext(OnDarkContext)
    }, className),
    disabled: hasAriaDisabled ? undefined : disabled,
    "aria-disabled": hasAriaDisabled ? 'true' : undefined
  }, componentProps, props), /*#__PURE__*/React.createElement("span", {
    className: `${baseClassName}__inner`
  }, state === 'loading' ? /*#__PURE__*/React.createElement(Spinner, {
    className: `${baseClassName}__spinner`
  }) : renderIcon({
    baseClassName,
    icon,
    size,
    empty: !childrenElement
  }), /*#__PURE__*/React.createElement("span", null, childrenElement), renderCaret({
    baseClassName,
    size,
    caret
  })), isArrowButton && !ghost && /*#__PURE__*/React.createElement("span", {
    className: `${baseClassName}__arrow`
  }));

  if (tooltipElement) {
    button = /*#__PURE__*/React.createElement(Tooltip, {
      title: tooltipElement
    }, button);
  }

  return button;
};

Button.propTypes = {
  /**
   * Button size.
   * @since 2.5.0
   */
  size: PropTypes.oneOf(['md', 'lg']),

  /**
   * Visual intent color to apply to component.
   * @since 0.0.42
   */
  intent: PropTypes.oneOf(['primary', 'secondary', 'success', 'warning', 'danger', 'info']),

  /**
   * Display button with transparent background.
   * @since 2.1.0
   */
  ghost: PropTypes.bool,

  /**
   * Arrow button.
   * @since 2.6.0
   */
  arrow: PropTypes.oneOf(['forward', 'backward']),

  /**
   * Selected state of toggle button. Used in controlled component mode.
   * @since 0.0.68
   */
  selected: PropTypes.bool,

  /**
   * Toggle button callback. Used in uncontrolled component mode.
   * @since 0.0.68
   */
  onToggle: PropTypes.func,

  /**
   * State of the button
   * @since 0.0.42
   */
  state: PropTypes.oneOf(['active', 'loading', 'hovered', 'focused']),

  /**
   * Is button disabled?
   * @since 0.0.42
   */
  disabled: PropTypes.bool,

  /**
   * Tooltip for component
   * @since 0.0.42
   */
  tooltip: PropTypes.node,

  /**
   * Name of icon or [Icon](#!/Icon) component
   * @since 0.0.42
   */
  icon: PropTypes.oneOfType([PropTypes.string, PropTypes.object, PropTypes.element]),

  /**
   * Show caret
   * @since 0.0.42
   */
  caret: PropTypes.oneOfType([PropTypes.bool, PropTypes.element]),

  /**
   * Dynamically expand the button to fill out the whole available width of its parent container.
   * @since 1.8.0
   */
  fill: PropTypes.bool,

  /**
   * Content of the button
   * @since 0.0.37
   */
  children: PropTypes.node,

  /**
   * Component to render as the root element. Useful when rendering a `Button` as `<a>` or `<Link>`.
   * @since 0.0.42
   */
  component: PropTypes.elementType,

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

  /**
   * @ignore
   */
  baseClassName: PropTypes.string
};
Button.defaultProps = {
  size: undefined,
  intent: undefined,
  ghost: false,
  selected: undefined,
  onToggle: undefined,
  state: undefined,
  disabled: false,
  tooltip: undefined,
  icon: undefined,
  caret: undefined,
  fill: false,
  children: undefined,
  component: 'button',
  className: undefined,
  baseClassName: `${CLS_PREFIX}button`,
  arrow: undefined
};
export default Button;