import React from 'react';
import styled from 'styled-components';

import { CloseIcon } from '@redocly/theme/icons/CloseIcon/CloseIcon';
import { CheckmarkFilledIcon } from '@redocly/theme/icons/CheckmarkFilledIcon/CheckmarkFilledIcon';

type DefaultStatusColor = 'success' | 'processing' | 'error' | 'warning' | 'default';
type ActionStatusColor = 'approved' | 'declined' | 'pending';
type SubjectStatusColor = 'active' | 'draft' | 'deprecated' | 'product';
type HttpColor = 'get' | 'post' | 'put' | 'delete' | 'option' | 'patch' | 'head' | 'hook' | 'link';
type HttpStatusColor = 'http-deprecated';
type StatusColor =
  | DefaultStatusColor
  | ActionStatusColor
  | SubjectStatusColor
  | HttpColor
  | HttpStatusColor;
type Color =
  | 'red'
  | 'green'
  | 'blue'
  | 'grey'
  | 'gold'
  | 'cyan'
  | 'magenta'
  | 'purple'
  | 'lime'
  | 'geekblue'
  | 'yellow';

export type TagProps = {
  className?: string;
  children?: React.ReactNode;
  closable?: boolean;
  color?: StatusColor | Color | string;
  borderless?: boolean;
  withStatusDot?: boolean;
  statusDotColor?: string;
  size?: string;
  icon?: React.ReactNode;
  active?: boolean;
  tabIndex?: number;
  onClick?: (event: React.MouseEvent) => void;
  onKeyDown?: (event: React.KeyboardEvent) => void;
  onClose?: (event: React.MouseEvent) => void;
};

export function Tag({
  children,
  color,
  icon,
  active,
  closable,
  tabIndex,
  onClick,
  onKeyDown,
  onClose,
  size,
  borderless,
  withStatusDot,
  statusDotColor = 'var(--tag-status-dot-color-default)',
  ...otherProps
}: TagProps): JSX.Element {
  return (
    <TagWrapper
      tabIndex={tabIndex}
      data-component-name="Tag/Tag"
      borderless={borderless}
      color={color}
      size={size}
      onClick={onClick}
      onKeyDown={onKeyDown}
      hasCloseButton={closable}
      {...otherProps}
    >
      {withStatusDot ? <StatusDot color={statusDotColor} /> : icon ? icon : null}
      <ContentWrapper>{children}</ContentWrapper>
      {closable && (
        <CloseButton
          onClick={(event) => {
            onClose?.(event);
          }}
        >
          <CloseIcon />
        </CloseButton>
      )}
      {active && <ActiveIcon />}
    </TagWrapper>
  );
}

export const ContentWrapper = styled.div`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-wrap: nowrap;

  padding: var(--tag-content-padding);
  gap: var(--tag-content-gap);
`;

const CloseButton = styled.div`
  display: flex;
  align-items: center;
  justify-content: center;
  align-self: stretch;
  border-radius: 0 var(--tag-border-radius) var(--tag-border-radius) 0;

  &:hover {
    background: var(--tag-close-button-bg-color-hover);
  }
`;

const TagWrapper = styled.div.attrs(({ className, color, size }: TagProps) => ({
  className:
    (className || '') +
    ` tag-default ${color ? `tag-${color}` : ''} ${size ? `tag-size-${size}` : ''}`,
}))<TagProps & { hasCloseButton?: boolean }>`
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-wrap: nowrap;
  position: relative;

  padding: var(--tag-padding);
  ${({ hasCloseButton }) => (hasCloseButton ? 'padding-right: 0;' : '')};
  margin: var(--tag-margin);

  &:last-child {
    margin-right: 0;
  }

  gap: var(--tag-gap);

  font-size: var(--tag-font-size);
  font-family: var(--tag-font-family);
  font-weight: var(--tag-font-weight);
  line-height: var(--tag-line-height);
  box-shadow: var(--tag-box-shadow);
  text-transform: var(--tag-text-transform);

  color: var(--tag-color);
  background-color: var(--tag-bg-color);
  ${({ borderless }) =>
    borderless
      ? ''
      : 'border: var(--tag-border-width) var(--tag-border-style) var(--tag-border-color);'}
  border-radius: var(--tag-border-radius);
`;

const StatusDot = styled.div<{ color: string }>`
  display: inline-block;
  width: var(--tag-badge-size);
  height: var(--tag-badge-size);
  border: var(--tag-badge-border-width) solid var(--tag-badge-border-color);
  border-radius: 50%;
  background-color: ${({ color }) => color};
`;

const ActiveIcon = styled(CheckmarkFilledIcon)`
  width: 12px;
  height: 12px;
  position: absolute;
  right: -4px;
  top: -4px;
`;
