import clsx from 'clsx';
import React from 'react';
import { Link } from 'react-router-dom';
import { noop } from '../../../helpers/utils';
import { IconName, Icons } from '../../Icons';
import { ButtonContext } from '../Button.model';
import {
  CompositeButtonProps,
  CompositeJsButtonProps,
  CompositeNavigationButtonProps,
} from './CompositeButton.model';
import classes from './CompositeButton.scss';

/**
 * Button which can render an text together with an icon.
 * @example
 *   // Rendered as button
 *   <CompositeButton type="button" text="Click me!" />
 *
 *   // Rendered as link
 *   <CompositeButton path="/home" text="Click me!" />
 */
export const CompositeButton: React.FC<CompositeButtonProps> = ({
  className,
  customIcon,
  dataTestId,
  disabled,
  height,
  icon,
  iconPosition,
  path,
  text = '',
  width,
  openInNewTab,
  ...rest
}) => {
  const commonProps = {
    className,
    customIcon,
    dataTestId,
    disabled,
    height,
    icon,
    iconPosition,
    text,
    width,
  };
  return path ? (
    <CompositeNavigationButton
      {...commonProps}
      path={path}
      openInNewTab={openInNewTab}
    />
  ) : (
    <CompositeContextButton {...commonProps} {...rest} />
  );
};

const CompositeContextButton: React.FC<CompositeJsButtonProps> = ({
  buttonContext = ButtonContext.Context,
  className,
  customIcon,
  dataTestId = undefined,
  disabled = false,
  height,
  icon,
  iconPosition,
  text = '',
  type = 'button',
  width,
  onButtonClicked = noop,
}) => {
  return (
    <button
      className={clsx(
        classes.container,
        {
          [classes.context]: buttonContext === ButtonContext.Context,
          [classes.active]: buttonContext === ButtonContext.Active,
        },
        'composite-button-container',
        className,
      )}
      type={type}
      style={{
        height,
        width,
        direction: iconPosition === 'left' ? 'rtl' : 'ltr',
      }}
      onClick={onButtonClicked}
      disabled={disabled}
      data-test-id={dataTestId ?? 'text-button'}
    >
      <div>{text}</div>
      <div className={classes.icon}>
        {customIcon ||
          (icon !== null && icon !== undefined ? (
            <Icons icon={icon} />
          ) : undefined)}
      </div>
    </button>
  );
};

const CompositeNavigationButton: React.FC<CompositeNavigationButtonProps> = ({
  className,
  customIcon,
  dataTestId = undefined,
  disabled = false,
  height,
  icon,
  iconPosition,
  path,
  text = '',
  width,
  openInNewTab,
}) => {
  const defaultIcon = openInNewTab ? IconName.External : IconName.ChevronRight;

  return (
    <Link
      to={path}
      className={clsx(
        classes.container,
        classes.navigation,
        { [classes.disabled]: disabled },
        'composite-button-container',
        className,
      )}
      style={{
        height,
        width,
        direction: iconPosition === 'left' ? 'rtl' : 'ltr',
      }}
      data-test-id={dataTestId ?? 'text-button'}
    >
      <div>{text}</div>
      <div className={classes.icon}>
        {customIcon ? customIcon : <Icons icon={icon ? icon : defaultIcon} />}
      </div>
    </Link>
  );
};
