import React, { MouseEvent } from "react";
import classNames from "classnames";
import { Box, BoxProps } from "../Box";
import { Flex } from "../Flex";
import { Icon, ICON_TYPE } from "../Icon";
import { Text } from "../Text";
import { bem } from "../../utilities/bem";
import isUndefined from "../../utilities/isUndefined";

const cn = "Token";

export enum TOKEN_STATUS {
  DANGER = "danger",
  DEFAULT = "default",
}

interface TokenProps extends BoxProps {
  /**
   * Label for the token, precedes child text
   */
  label?: string;
  /**
   * If true, an "X" button will be shown on the right of the token
   */
  removable?: boolean;
  /**
   * Callback to execute when the remove button is clicked
   */
  onRemove?: (event: MouseEvent<HTMLButtonElement>) => void;
  /**
   * Changes styles based on status
   */
  variant?: TOKEN_STATUS;
}

const TokenGroup = ({ className, ...rest }: BoxProps) => {
  return <Box className={classNames(bem(`${cn}Group`), className)} {...rest} />;
};

export const Token = ({
  children,
  label,
  className,
  onRemove,
  removable = false,
  variant = TOKEN_STATUS.DEFAULT,
  ...rest
}: TokenProps) => {
  const handleClick = (event: MouseEvent<HTMLButtonElement>): void => {
    if (!isUndefined(onRemove)) {
      onRemove(event);
    }
  };

  return (
    <Box
      className={classNames(bem(cn), bem(cn, { m: variant }), className)}
      {...rest}
    >
      <Flex className={bem(cn, { e: "textWrapper" })}>
        {variant === TOKEN_STATUS.DANGER && (
          <Icon
            icon={ICON_TYPE.EXCLAMATION_TRIANGLE}
            className={bem(cn, { e: "icon" })}
          />
        )}

        {label && (
          <Text as="span" className={bem(cn, { e: "label" })}>
            {label}
          </Text>
        )}

        <Text as="span" className={bem(cn, { e: "value" })}>
          {children}
        </Text>

        {removable && (
          <button
            onClick={handleClick}
            type="button"
            className={bem(cn, { e: "removeBtn" })}
          >
            <Icon icon={ICON_TYPE.TIMES} />
          </button>
        )}
      </Flex>
    </Box>
  );
};

Token.Group = TokenGroup;
