import styled, {
  css,
  FlattenInterpolation,
  ThemeProps,
  DefaultTheme,
} from 'styled-components';

type Intent =
  | 'primary'
  | 'success'
  | 'danger'
  | 'warning'
  | 'error'
  | 'archived';

type Variant = 'basic' | 'filled' | 'outlined';

type FilledVariant =
  | 'filled-primary'
  | 'filled-success'
  | 'filled-danger'
  | 'filled-warning'
  | 'filled-error'
  | 'filled-archived';

type OutlinedVariant =
  | 'outlined-primary'
  | 'outlined-success'
  | 'outlined-danger'
  | 'outlined-warning'
  | 'outlined-error'
  | 'outlined-archived';

type ThemeVariant = 'basic' | FilledVariant | OutlinedVariant;

const BACKGROUND_INTENTS = {
  primary: 'primaryBackground',
  success: 'successBackground',
  danger: 'dangerBackground',
  warning: 'warningBackground',
  error: 'errorBackground',
  archived: 'archivedBackground',
} as const;

const HOVER_BTN_INTENTS = {
  primary: 'hoverPrimaryCloseBtn',
  success: 'hoverSuccessCloseBtn',
  danger: 'hoverDangerCloseBtn',
  warning: 'hoverWarningCloseBtn',
  error: 'hoverErrorCloseBtn',
} as const;

const ACTIVE_BTN_INTENTS = {
  primary: 'activePrimaryCloseBtn',
  success: 'activeSuccessCloseBtn',
  danger: 'activeDangerCloseBtn',
  warning: 'activeWarningCloseBtn',
  error: 'activeErrorCloseBtn',
} as const;

const genFilledStyles = (
  intent: Intent
): FlattenInterpolation<ThemeProps<DefaultTheme>> => css`
  color: white;
  border-color: ${({ theme }) => theme.colors.tag[intent]};
  background: ${({ theme }) => theme.colors.tag[intent]};
`;

const genOutlinedStyles = (
  intent: Intent
): FlattenInterpolation<ThemeProps<DefaultTheme>> => css`
  color: ${({ theme }) => theme.colors.tag[intent]};
  border-color: ${({ theme }) => theme.colors.tag[intent]};
  background: ${({ theme }) => theme.colors.tag[BACKGROUND_INTENTS[intent]]};
`;

const closeBtnFilledStyles = css`
  color: ${({ theme }) => theme.colors.tag.closeBtn};
  &:hover {
    opacity: 0.4;
  }
  &:active {
    opacity: 0.7;
  }
`;

const genCloseBtnOutlinedStyles = (
  intent: 'primary' | 'danger' | 'success' | 'warning' | 'error'
): FlattenInterpolation<ThemeProps<DefaultTheme>> => css`
  color: ${({ theme }) => theme.colors.tag[intent]};
  &:hover {
    color: ${({ theme }) => theme.colors.tag[HOVER_BTN_INTENTS[intent]]};
  }
  &:active {
    color: ${({ theme }) => theme.colors.tag[ACTIVE_BTN_INTENTS[intent]]};
  }
`;

const CloseButton = styled.button<{ themeVariant: ThemeVariant }>`
  display: flex;
  align-items: center;
  border: none;
  background: transparent;
  margin: 0;
  padding: ${({ theme }) => theme.space.tag.closeBtnPadding};
  font-size: ${({ theme }) => theme.fontSizes.tag.closeBtn};

  &:hover {
    cursor: pointer;
  }

  &:focus {
    outline: none;
  }

  ${({ themeVariant, theme }) => {
    switch (themeVariant) {
      case 'basic':
      case 'outlined-archived':
        return css`
          color: ${theme.colors.tag.basicCloseBtn};
          &:hover {
            color: ${theme.colors.tag.hoverBasicCloseBtn};
          }
          &:active {
            color: ${theme.colors.tag.defaultText};
          }
        `;
      case 'filled-primary':
      case 'filled-success':
      case 'filled-danger':
      case 'filled-warning':
      case 'filled-error':
      case 'filled-archived':
        return closeBtnFilledStyles;
      case 'outlined-primary':
        return genCloseBtnOutlinedStyles('primary');
      case 'outlined-success':
        return genCloseBtnOutlinedStyles('success');
      case 'outlined-danger':
        return genCloseBtnOutlinedStyles('danger');
      case 'outlined-warning':
        return genCloseBtnOutlinedStyles('warning');
      case 'outlined-error':
        return genCloseBtnOutlinedStyles('error');
    }
  }};
`;

const StyledTag = styled.span<{
  themeSize: 'small' | 'medium' | 'large';
  themeVariant: ThemeVariant;
}>`
  display: inline-flex;
  align-items: center;
  box-sizing: border-box;
  border: ${({ theme }) => theme.borderWidths.tag.default} solid;
  border-radius: ${({ theme }) => theme.radii.tag.default};
  font-weight: ${({ theme }) => theme.fontWeights.tag.default};
  line-height: 1;
  margin: 0;
  padding: 0;

  ${({ themeSize, theme }) => {
    switch (themeSize) {
      case 'small':
        return css`
          font-size: ${theme.fontSizes.tag.small};
          padding: ${theme.space.tag.smallPadding};
        `;
      case 'medium':
        return css`
          font-size: ${theme.fontSizes.tag.medium};
          padding: ${theme.space.tag.mediumPadding};
        `;
      case 'large':
        return css`
          font-size: ${theme.fontSizes.tag.large};
          padding: ${theme.space.tag.largePadding};
        `;
    }
  }};

  ${({ themeVariant, theme }) => {
    switch (themeVariant) {
      case 'basic':
        return css`
          color: ${theme.colors.tag.defaultText};
          border-color: ${theme.colors.tag.defaultBorder};
          background: ${theme.colors.tag.defaultBackground};
        `;
      case 'filled-primary':
        return genFilledStyles('primary');
      case 'filled-success':
        return genFilledStyles('success');
      case 'filled-danger':
        return genFilledStyles('danger');
      case 'filled-warning':
        return genFilledStyles('warning');
      case 'filled-error':
        return genFilledStyles('error');
      case 'filled-archived':
        return genFilledStyles('archived');
      case 'outlined-primary':
        return genOutlinedStyles('primary');
      case 'outlined-success':
        return genOutlinedStyles('success');
      case 'outlined-danger':
        return genOutlinedStyles('danger');
      case 'outlined-warning':
        return genOutlinedStyles('warning');
      case 'outlined-error':
        return genOutlinedStyles('error');
      case 'outlined-archived':
        return genOutlinedStyles('archived');
    }
  }};
`;

export {
  StyledTag,
  CloseButton,
  Intent,
  Variant,
  FilledVariant,
  OutlinedVariant,
  ThemeVariant,
};
