import classnames from 'classnames/bind';
import { SilkeIcon, SilkeIcons } from '../silke-icon';
import { SilkeSkeleton } from '../silke-skeleton';
import * as React from 'react';
import { BoxButtonProps, SilkeBox } from '../silke-box';
import { useButtonContext } from './context';
import styles from './silke-button.scss';

const cl = classnames.bind(styles);
export type SilkeButtonKind = 'primary' | 'secondary' | 'danger' | 'ghost' | 'upgrade';
export type SilkeButtonSize = 'base' | 's';

export type SilkeButtonProps = {
  label?: React.ReactNode;
  kind?: SilkeButtonKind;
  size?: SilkeButtonSize;
  loading?: boolean;
  /** Disable button */
  disabled?: boolean;
  /** Selected */
  selected?: boolean;
  /** Show button as in focus state */
  focus?: boolean;
  /** Show button as in hover state */
  hover?: boolean;
  icon?: SilkeIcons | React.ReactElement;
  leftIcon?: SilkeIcons | React.ReactElement;
  link?: string;
  target?: string;
} & Omit<BoxButtonProps, 'children' | 'size'>;

export const SilkeButton = React.forwardRef(
  (
    {
      label,
      link,
      kind,
      size,
      icon,
      leftIcon,
      focus,
      hover,
      className,
      loading,
      type = 'button',
      selected,
      ...rest
    }: SilkeButtonProps,
    ref,
  ) => {
    const context = useButtonContext();
    const iconOnly = icon && !label;

    if (!size) size = context.size || 'base';

    className = cl(
      'button',
      className,
      kind || context.kind || 'primary',
      size || context.size || 'base',
      {
        iconOnly,
        focus,
        hover,
        selected,
      },
    );
    if (loading) rest.disabled = true;
    if (type === 'submit' && context.disableSubmit) rest.disabled = true;

    return (
      <SilkeBox
        rounded={size === 's' ? 'tiny' : 'small'}
        {...(rest as any)}
        type={type}
        className={className}
        ref={ref}
        rel="button"
        tag={link ? 'link' : 'button'}
        to={link}
        gap="s"
      >
        {loading && (
          <SilkeSkeleton
            style={{
              position: 'absolute',
              top: 0,
              right: 0,
              left: 0,
              bottom: 0,
              overflow: 'hidden',
              borderRadius: 'inherit',
            }}
          />
        )}
        {leftIcon && (
          <span className={styles.leftIcon}>
            <SilkeIcon icon={leftIcon} />
          </span>
        )}
        {label}
        {icon && (
          <span className={styles.icon}>
            <SilkeIcon icon={icon} />
          </span>
        )}
      </SilkeBox>
    );
  },
);

SilkeButton.displayName = 'SilkeButton';
