import React, { forwardRef } from 'react';
import { bem } from 'utils/bem';
import { ICON_DISPLAY_NAME } from 'common/components/icon';
import { IconColor } from 'common/components/icon/types';
import { SButton } from './s-button';

export type ButtonVariant =
  | 'primary-cta'
  | 'secondary-cta'
  | 'secondary-gray'
  | 'secondary-white'
  | 'dark'
  | 'transparent'
  | 'black';

export type ButtonSize = 'small' | 'big';

export type ButtonType = 'submit' | 'button';

export interface Props {
  children: React.ReactNode;
  disabled?: boolean;
  type?: ButtonType;
  variant?: ButtonVariant;
  className?: string;
  size?: ButtonSize;
  iconColor?: IconColor;
  dataSelector?: string;
  onClick?: (e: React.MouseEvent) => void;
  dataId?: string;
}

const isElementIcon = (el: React.ReactElement) => {
  return (el?.type as React.SFC)?.displayName === ICON_DISPLAY_NAME;
};

const classes = bem('button');

export const Button = React.memo(
  forwardRef<HTMLButtonElement, Props>(
    (
      {
        type = 'button',
        disabled = false,
        variant = 'secondary-gray',
        size = 'small',
        className,
        children,
        iconColor,
        dataSelector,
        onClick,
        dataId,
      },
      ref
    ) => {
      const childrenArray = React.Children.toArray(children) as React.ReactElement[];
      const isIconButton = childrenArray.length === 1 && isElementIcon(childrenArray[0]);
      const buttonWithLeftIcon = childrenArray.length === 2 && isElementIcon(childrenArray[0]);
      const buttonWithRightIcon = childrenArray.length === 2 && isElementIcon(childrenArray[1]);
      const buttonWithBothIcons =
        childrenArray.length === 3 && isElementIcon(childrenArray[0]) && isElementIcon(childrenArray[2]);

      return (
        <SButton
          ref={ref}
          type={type}
          variant={variant}
          size={size}
          className={className}
          disabled={disabled}
          onClick={onClick}
          data-selector={dataSelector}
          icon={isIconButton}
          iconColor={iconColor}
          iconLeft={buttonWithLeftIcon}
          iconRight={buttonWithRightIcon}
          iconBoth={buttonWithBothIcons}
          data-id={dataId}
        >
          <span className={classes('inner')}>
            {children &&
              React.Children.map(children, el => {
                if (typeof el === 'string') return <span className={classes('text')}>{el}</span>;
                if (React.isValidElement(el)) {
                  return React.cloneElement(el, {
                    // proxy icon properties in case of using dropdowns
                    color: isElementIcon(el) ? iconColor || el.props.color : undefined,
                  });
                }
                return null;
              })}
          </span>
        </SButton>
      );
    }
  )
);
