import styled from 'styled-components/macro';

import { color, radius, shadow } from '../../theme';
import { assertUnreachable } from '../../utils/assertUnreachable';
import { Icon } from '../Icon/Icon';
import { TriggerButton } from '../TriggerButton/TriggerButton';

import { ButtonAppearance } from './constants';

// Extends TriggerButton because we want to add possibility of using
// Button as trigger in Menu or SelectField.
export const TunedButton = styled(TriggerButton)<{ $appearance: ButtonAppearance }>`
  align-items: center;
  appearance: none;
  background-color: ${(props) => {
    switch (props.$appearance) {
      case ButtonAppearance.Primary:
        return color('comp/button/primary/background/default');
      case ButtonAppearance.Default:
        return color('comp/button/default/background/default');
      case ButtonAppearance.Subtle:
        return color('comp/button/subtle/background/default');
      case ButtonAppearance.SubtlePrimary:
        return color('comp/button/subtlePrimary/background/default');
      case ButtonAppearance.Danger:
        return color('comp/button/danger/background/default');
      /* istanbul ignore next */
      default:
        assertUnreachable(props.$appearance);
    }
  }};
  border: 1px solid transparent;
  border-color: ${(props) => {
    switch (props.$appearance) {
      case ButtonAppearance.Primary:
        return color('comp/button/primary/border/default');
      case ButtonAppearance.Default:
        return color('comp/button/default/border/default');
      case ButtonAppearance.Subtle:
        return color('comp/button/subtle/border/default');
      case ButtonAppearance.SubtlePrimary:
        return color('comp/button/subtlePrimary/border/default');
      case ButtonAppearance.Danger:
        return color('comp/button/danger/border/default');
      /* istanbul ignore next */
      default:
        assertUnreachable(props.$appearance);
    }
  }};
  border-radius: ${radius('sys/radius/form-item')};
  box-sizing: border-box;
  color: ${(props) => {
    switch (props.$appearance) {
      case ButtonAppearance.Primary:
        return color('comp/button/primary/text/default');
      case ButtonAppearance.Default:
        return color('comp/button/default/text/default');
      case ButtonAppearance.Subtle:
        return color('comp/button/subtle/text/default');
      case ButtonAppearance.SubtlePrimary:
        return color('comp/button/subtlePrimary/text/default');
      case ButtonAppearance.Danger:
        return color('comp/button/danger/text/default');
      /* istanbul ignore next */
      default:
        assertUnreachable(props.$appearance);
    }
  }};
  column-gap: 4px;
  cursor: pointer;
  display: flex;
  font-size: 14px;
  font-weight: 600;
  height: 36px;
  justify-content: center;
  outline: none;
  padding: 6px 10px;
  white-space: nowrap;

  :disabled {
    background-color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/background/disabled');
        case ButtonAppearance.Default:
          return color('comp/button/default/background/disabled');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/background/disabled');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/background/disabled');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/background/disabled');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
    border-color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/border/disabled');
        case ButtonAppearance.Default:
          return color('comp/button/default/border/disabled');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/border/disabled');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/border/disabled');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/border/disabled');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
    color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/text/disabled');
        case ButtonAppearance.Default:
          return color('comp/button/default/text/disabled');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/text/disabled');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/text/disabled');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/text/disabled');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
    cursor: not-allowed;
  }

  :hover:not(:disabled) {
    background-color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/background/hover');
        case ButtonAppearance.Default:
          return color('comp/button/default/background/hover');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/background/hover');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/background/hover');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/background/hover');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
    border-color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/border/hover');
        case ButtonAppearance.Default:
          return color('comp/button/default/border/hover');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/border/hover');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/border/hover');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/border/hover');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
    color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/text/hover');
        case ButtonAppearance.Default:
          return color('comp/button/default/text/hover');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/text/hover');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/text/hover');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/text/hover');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
  }

  :active:not(:disabled) {
    background-color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/background/active');
        case ButtonAppearance.Default:
          return color('comp/button/default/background/active');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/background/active');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/background/active');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/background/active');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
    border-color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/border/active');
        case ButtonAppearance.Default:
          return color('comp/button/default/border/active');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/border/active');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/border/active');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/border/active');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
    color: ${(props) => {
      switch (props.$appearance) {
        case ButtonAppearance.Primary:
          return color('comp/button/primary/text/active');
        case ButtonAppearance.Default:
          return color('comp/button/default/text/active');
        case ButtonAppearance.Subtle:
          return color('comp/button/subtle/text/active');
        case ButtonAppearance.SubtlePrimary:
          return color('comp/button/subtlePrimary/text/active');
        case ButtonAppearance.Danger:
          return color('comp/button/danger/text/active');
        /* istanbul ignore next */
        default:
          assertUnreachable(props.$appearance);
      }
    }};
  }

  :focus-visible:not(:disabled) {
    box-shadow: ${shadow('sys/shadow/focus')};
  }
`;

export const TunedButtonIcon = styled(Icon)`
  height: 22px;
  width: 22px;
`;
