import React from 'react'
import classNames from 'classnames'
import { string, bool, object, array, func, node, oneOf, oneOfType } from 'prop-types'

import Loader from '../loader/loader'

const Button = ({
  children,
  className,
  disabled,
  fontSizeClass,
  innerRef,
  loading,
  onClick,
  selected,
  theme,
  loaderTheme = 'primary',
  ...props
}) => (
  <button
    ref={innerRef}
    className={classNames('btn', className, fontSizeClass, `${theme}-btn`, {
      'opacity-40': disabled || loading,
      'cursor-not-allowed': disabled && !loading,
      'h-10 cursor-wait': loading,
      [`selected-${theme}-btn`]: selected
    })}
    disabled={disabled || loading}
    onClick={e => !disabled && onClick(e)}
    {...props}
  >
    {loading ? <Loader size="6" use={loaderTheme} /> : children}
  </button>
)

Button.displayName = 'Button'

Button.propTypes = {
  /** Children wrapped by the component */
  children: node,
  /** CSS classes passed from outside, to be composed with existing internal styles */
  className: oneOfType([string, object, array]),
  /** Disables interaction with the button */
  disabled: bool,
  /**  Determines if the button is in a loading state */
  loading: bool,
  /**  Determines if the button is in a selected state */
  selected: bool,
  /** Determines the button variant rendered (primary, secondary, etc.) */
  theme: oneOf([
    'dashed',
    'primary',
    'primary-light',
    'primary-outline',
    'secondary',
    'secondary-light',
    'secondary-outline',
    'neutral',
    'neutral-outline',
    'neutral-secondary',
    'destructive'
  ]).isRequired,
  /** Callback function that will be called when the button is clicked */
  onClick: func,
  /** used to attach a ref to the button */
  innerRef: oneOfType([string, object, func])
}

Button.defaultProps = {
  disabled: false,
  loading: false,
  selected: false,
  fontSizeClass: 'text-sm'
}

export default Button
