import React, { FC, ButtonHTMLAttributes } from 'react';
import { styled } from '../../styles';
import { Icon } from '../../components/Icon';
import { buttonReset } from '../../styles/utils';
import { getVariant, getIconStyle } from './styles';

type HtmlButtonProps = ButtonHTMLAttributes<HTMLButtonElement>;
export type IconPosition = 'left' | 'right' | 'top' | 'bottom';
export type variants =
  | 'primary'
  | 'secondary'
  | 'ghost'
  | 'ghostSecondary'
  | 'raw'
  | 'gray';

export type Props = HtmlButtonProps & {
  /**
   * Specify the variant of Button you want to create
   */
  variant?: variants;
  fluid?: boolean;
  /**
   * Optionally specify an href for your Button
   */
  href?: string;
  RouterLink?: React.ComponentType<any>;
  iconPosition?: IconPosition;
};

export const defaultProps = {
  onClick: () => {},
  variant: 'primary' as variants,
  fluid: false,
  tabIndex: 0,
  type: 'button' as HtmlButtonProps['type']
};

const ButtonComponent: FC<Props> = (
  { onClick, variant, fluid, RouterLink, iconPosition, href, ...otherProps },
  ref
) => {
  if (RouterLink) {
    return <RouterLink {...otherProps} />;
  } else {
    return (
      <button
        ref={ref}
        onClick={onClick}
        role={href && 'button'}
        {...(href && { type: undefined })}
        {...otherProps}
      />
    );
  }
};

const ButtonWithRef = React.forwardRef(ButtonComponent);

export const Button = styled(ButtonWithRef)<Props>(
  buttonReset,
  ({ theme, fluid, iconPosition }) => ({
    whiteSpace: 'nowrap',
    position: 'relative',
    display: 'inline-flex',
    justifyContent: 'center',
    alignItems: 'center',
    flexShrink: 0,
    textAlign: 'center',
    textDecoration: 'none',
    letterSpacing: '1px',
    border: 'none',
    padding: '0.75rem 1.75rem',
    minHeight: '2.5rem',
    lineHeight: theme.lineHeights.tight,
    fontFamily: theme.fontFamilies.baseText,
    fontSize: theme.fontSizes[1],
    fontWeight: theme.fontWeights.semiBold,
    borderRadius: '8px',
    ...(fluid && { width: '100%' }),

    '&:disabled, &:disabled:hover': {
      backgroundColor: theme.colors.disabled,
      color: theme.colors.inactive,
      boxShadow: 'none',
      cursor: 'not-allowed'
    },

    [Icon]: {
      ...(iconPosition && {
        [`margin${getIconStyle(iconPosition!)}`]: theme.space.s
      })
    }
  }),
  getVariant
);

Button.defaultProps = defaultProps;
