import { clsx } from 'clsx';
import { Breakpoint } from '@transferwise/neptune-tokens';

import { Size, SizeSmall, SizeMedium } from '../common';
import { useScreenSize } from '../common/hooks/useScreenSize';
import NavigationOption from '../navigationOption';
import Tile from '../tile';

interface DecisionOption {
  'aria-label'?: string;
  description?: React.ReactNode;
  disabled?: boolean;
  href?: string;
  target?: React.HTMLAttributeAnchorTarget;
  media: {
    block: React.ReactNode;
    list: React.ReactNode;
  };
  onClick?: (event?: React.MouseEvent<HTMLElement>) => void;
  title: React.ReactNode;
}

export enum DecisionPresentation {
  LIST = 'LIST',
  LIST_BLOCK = 'LIST_BLOCK',
  LIST_BLOCK_GRID = 'LIST_BLOCK_GRID',
}

export enum DecisionType {
  NAVIGATION = 'NAVIGATION',
}

export interface DecisionProps {
  /**  A list of elements to be rendered */
  options: readonly DecisionOption[];
  /**  Handles the display mode of the component */
  presentation?: `${DecisionPresentation}`;
  /** Size currently affects only Tile dimension */
  size?: SizeSmall | SizeMedium;
  /** Decide which kind of element type needs to be rendered ex: Navigation Options or in the future Radio or Checkbox Options */
  type?: `${DecisionType}`;

  /** Display media in a circle in list presentation */
  showMediaCircleInList?: boolean;

  /** Sets navigation options to be aligned with the parent container */
  isContainerAligned?: boolean;
}

const Decision = ({
  options,
  presentation = DecisionPresentation.LIST,
  size = Size.MEDIUM,
  type = DecisionType.NAVIGATION,
  showMediaCircleInList = true,
  isContainerAligned = false,
}: DecisionProps) => {
  const screenXs = useScreenSize(Breakpoint.EXTRA_SMALL);
  const screenSm = useScreenSize(Breakpoint.SMALL);

  if (type === DecisionType.NAVIGATION) {
    const renderedOptions = options.map(
      (
        {
          'aria-label': ariaLabel,
          title,
          description,
          disabled,
          href,
          target,
          media: { list },
          onClick,
        },
        key,
      ) => (
        <NavigationOption
          // eslint-disable-next-line react/no-array-index-key
          key={`nav-${key}`}
          aria-label={ariaLabel}
          complex={false}
          content={description}
          disabled={disabled}
          href={href}
          target={target}
          media={list}
          showMediaAtAllSizes
          showMediaCircle={showMediaCircleInList}
          isContainerAligned={isContainerAligned}
          title={title}
          onClick={onClick}
        />
      ),
    );

    if (
      presentation === DecisionPresentation.LIST_BLOCK ||
      presentation === DecisionPresentation.LIST_BLOCK_GRID
    ) {
      const isSmall = size === Size.SMALL;
      const breakpoint = isSmall ? screenXs : screenSm;

      const isGrid = presentation === DecisionPresentation.LIST_BLOCK_GRID;

      return (
        <div
          className={clsx(
            'np-decision d-flex',
            {
              'np-decision--small': isSmall,
              'np-decision--grid': isGrid,
            },
            breakpoint ? isGrid && 'flex-wrap' : 'flex-column',
          )}
        >
          {breakpoint
            ? options.map(
                (
                  {
                    'aria-label': ariaLabel,
                    description,
                    disabled,
                    href,
                    target,
                    media: { block },
                    onClick,
                    title,
                  },
                  key,
                ) => (
                  <Tile
                    // eslint-disable-next-line react/no-array-index-key
                    key={`tile-${key}`}
                    className={clsx(`np-decision__tile${isSmall ? '--small' : ''}`, {
                      'np-decision__tile--fixed-width': isGrid,
                    })}
                    aria-label={ariaLabel}
                    description={description}
                    disabled={disabled}
                    href={href}
                    target={target}
                    media={block}
                    size={isSmall ? Size.SMALL : Size.MEDIUM}
                    title={title}
                    onClick={onClick}
                  />
                ),
              )
            : renderedOptions}
        </div>
      );
    }
    // LIST
    return <>{renderedOptions}</>;
  }
  return null;
};

export default Decision;
