import { useCallback } from 'react';
import cc from 'classcat';

import './Button.css';

export interface ButtonOwnProps<
  E extends React.ElementType = React.ElementType
> {
  as?: E;
  size?: 's' | 'm' | 'l';
  buttonType?: string;
  color?: 'blue' | 'red' | 'gray';
  block?: boolean;
  className?: string;
  autoFocus?: boolean;
}

export type ButtonProps<E extends React.ElementType> = ButtonOwnProps<E> &
  Omit<React.ComponentProps<E>, keyof ButtonOwnProps>;

export const defaultElement = 'button';

export const Button = <E extends React.ElementType = typeof defaultElement>({
  as,
  size = 'm',
  buttonType = 'rounded3',
  color = 'blue',
  block,
  className,
  autoFocus,
  ...props
}: ButtonProps<E>) => {
  const Element = as || defaultElement;

  const cn = cc([
    {
      fz16: size === 'l',
      fz14: size === 'm',
      fz12: size === 's',

      [size]: size,
      [buttonType]: buttonType,
      [color]: color,

      block: block === true,
      w100: block === true,
    },

    size === 'l' ? 'paddingX5' : '',
    size === 'm' ? 'paddingX4' : '',
    size === 's' ? 'paddingX3' : '',

    // size === 'l' ? 'paddingY2' : '',
    // size === 'm' ? 'paddingY2' : '',
    // size === 's' ? 'paddingY1' : '',

    'button tac tdn medium paddingY0 cup',
    className,
  ]);

  const focus = useCallback((ref) => {
    if (ref) ref.focus();
  }, []);

  const elementProps: React.ComponentProps<typeof Element> = props;
  if (as === 'button') elementProps.type = props.type || 'button';
  if (autoFocus) elementProps.ref = focus;

  return <Element className={cn} {...elementProps} />;
};

export default Button;
