/*
 * Button-specific utilities
 */
@mixin gl-button-theme(
  $color: null,
  $background-color: null,
  $border-color: null,
  $hover-color: null,
  $hover-background-color: null,
  $hover-border-color: null,
  $focus-color: null,
  $focus-background-color: null,
  $focus-border-color: null,
  $active-color: null,
  $active-background-color: null,
  $active-border-color: null
) {
  color: $color;
  background-color: $background-color;
  border-color: $border-color;

  &::before {
    background-color: $border-color;
    transition:
      background-color $gl-transition-duration-medium $gl-easing-out-cubic,
      border-color $gl-transition-duration-medium $gl-easing-out-cubic;
  }

  &:hover {
    color: $hover-color;
    background-color: $hover-background-color;
    border-color: $hover-border-color;
  }

  &:focus {
    color: $focus-color;
    background-color: $focus-background-color;
    border-color: $focus-border-color;
  }

  &:active,
  &.active {
    color: $active-color;
    background-color: $active-background-color;
    border-color: $active-border-color;

    :focus,
    &:focus:active {
      @apply gl-focus;
    }
  }
}

// low specificity so that display can be overridden to hide buttons
.gl-button {
  @apply gl-inline-flex;
}

.gl-button:not(.btn-link) {
  &:focus,
  &:active,
  &:focus:active {
    @apply gl-no-underline;
  }
}

.gl-button.gl-button {
  border-radius: var(--gl-button-border-radius);
  @apply gl-px-4;
  background-color: var(--gl-button-default-primary-background-color-default);
  @apply gl-leading-normal;
  color: var(--gl-button-default-primary-foreground-color-default);
  @apply gl-fill-current;
  @apply gl-justify-center;
  @apply gl-items-center;
  @apply gl-text-base;

  @apply gl-py-0;
  border: $gl-border-size-1 solid var(--gl-button-default-primary-border-color-default);
  min-height: $gl-button-medium-size;
  min-width: $gl-button-medium-size;
  transition:
    color $gl-transition-duration-medium $gl-easing-out-cubic,
    background-color $gl-transition-duration-medium $gl-easing-out-cubic,
    border-color $gl-transition-duration-medium $gl-easing-out-cubic,
    box-shadow $gl-transition-duration-medium $gl-easing-out-cubic,
    text-decoration-color $gl-transition-duration-medium $gl-easing-out-cubic;
  @include gl-prefers-reduced-motion-transition;

  &:focus,
  &:focus:active {
    @apply gl-focus;
  }

  .gl-button-text {
    @apply gl-overflow-hidden;
    @apply gl-text-ellipsis;
    @apply gl-whitespace-nowrap;
    // Added to address a FF bug which causes cut off text: https://bugzilla.mozilla.org/show_bug.cgi?id=1406552
    padding-top: 1px;
    padding-bottom: 1px;
    margin-top: -1px;
    margin-bottom: -1px;
  }

  .gl-button-icon {
    @apply gl-h-5;
    @apply gl-w-5;
    @apply gl-shrink-0;
    @apply gl-mr-2;
    top: auto;
  }

  .gl-button-count {
    @apply gl-inline-flex;
    @apply gl-items-center;
    @apply gl-justify-center;
    @apply gl-text-sm;
    @apply gl-font-normal;
    @apply gl-leading-normal;
    @apply gl-ml-2;
    @apply gl-px-2;
    @apply gl-py-0;
    @apply gl-shrink-0;
    @apply gl-border-1;
    @apply gl-border-solid;
    @apply gl-border-transparent;
    @apply gl-rounded-full;
    @apply gl-min-w-3;
    background-color: var(--gl-button-count-background-color);
  }

  gl-emoji {
    @apply gl-mr-2;
    position: relative;
    @apply gl-text-lg;
  }

  &.btn-default,
  &.btn-default-secondary {
    @include gl-button-theme(
      $color: var(--gl-button-default-primary-foreground-color-default),
      $background-color: var(--gl-button-default-primary-background-color-default),
      $border-color: var(--gl-button-default-primary-border-color-default),
      $hover-color: var(--gl-button-default-primary-foreground-color-hover),
      $hover-background-color: var(--gl-button-default-primary-background-color-hover),
      $hover-border-color: var(--gl-button-default-primary-border-color-hover),
      $focus-color: var(--gl-button-default-primary-foreground-color-focus),
      $focus-background-color: var(--gl-button-default-primary-background-color-focus),
      $focus-border-color: var(--gl-button-default-primary-border-color-focus),
      $active-color: var(--gl-button-default-primary-foreground-color-active),
      $active-background-color: var(--gl-button-default-primary-background-color-active),
      $active-border-color: var(--gl-button-default-primary-border-color-active)
    );

    &.selected {
      color: var(--gl-button-selected-foreground-color-default);
      background-color: var(--gl-button-selected-background-color-default);

      &::before {
        width: $gl-border-size-2 !important;
      }

      &::before,
      + .gl-button::before {
        background-color: var(--gl-button-selected-border-color-default);
      }

      border-width: $gl-border-size-1;
      border-color: var(--gl-button-selected-border-color-default);
      box-shadow: inset 0 0 0 $gl-border-size-1 var(--gl-button-selected-border-color-default);

      &:hover {
        color: var(--gl-button-selected-foreground-color-hover);
        background-color: var(--gl-button-selected-background-color-hover);
        border-color: var(--gl-button-selected-border-color-hover);
        box-shadow: inset 0 0 0 $gl-border-size-1 var(--gl-button-selected-border-color-hover);
      }

      &:hover::before,
      &:hover + .gl-button::before {
        background-color: var(--gl-button-selected-border-color-hover);
      }

      &:focus {
        color: var(--gl-button-selected-foreground-color-focus);
        background-color: var(--gl-button-selected-background-color-focus);
        @apply gl-focus;
        border-color: var(--gl-button-selected-border-color-focus);
      }

      &:focus::before,
      &:focus + .gl-button::before {
        background-color: var(--gl-button-selected-border-color-focus);
      }

      &:active,
      &.active {
        color: var(--gl-button-selected-foreground-color-active);
        background-color: var(--gl-button-selected-background-color-active);
        box-shadow: inset 0 0 0 $gl-border-size-1 var(--gl-button-selected-border-color-active);
        border-color: var(--gl-button-selected-border-color-active);
      }

      &:active::before,
      &.active::before,
      &:active + .gl-button::before,
      &.active + .gl-button::before {
        background-color: var(--gl-button-selected-border-color-active);
      }
    }
  }

  &.btn-reset {
    &::before {
      background-color: var(--gl-button-default-primary-border-color-default);
    }
  }

  &.btn-default-tertiary {
    @include gl-button-theme(
      $color: var(--gl-button-default-tertiary-foreground-color-default),
      $background-color: var(--gl-button-default-tertiary-background-color-default),
      $border-color: var(--gl-button-default-tertiary-border-color-default),
      $hover-color: var(--gl-button-default-tertiary-foreground-color-hover),
      $hover-background-color: var(--gl-button-default-tertiary-background-color-hover),
      $hover-border-color: var(--gl-button-default-tertiary-border-color-hover),
      $focus-color: var(--gl-button-default-tertiary-foreground-color-focus),
      $focus-background-color: var(--gl-button-default-tertiary-background-color-focus),
      $focus-border-color: var(--gl-button-default-tertiary-border-color-focus),
      $active-color: var(--gl-button-default-tertiary-foreground-color-active),
      $active-background-color: var(--gl-button-default-tertiary-background-color-active),
      $active-border-color: var(--gl-button-default-tertiary-border-color-active)
    );
  }

  &.btn-confirm {
    @include gl-button-theme(
      $color: var(--gl-button-confirm-primary-foreground-color-default),
      $background-color: var(--gl-button-confirm-primary-background-color-default),
      $border-color: var(--gl-button-confirm-primary-border-color-default),
      $hover-color: var(--gl-button-confirm-primary-foreground-color-hover),
      $hover-background-color: var(--gl-button-confirm-primary-background-color-hover),
      $hover-border-color: var(--gl-button-confirm-primary-border-color-hover),
      $focus-color: var(--gl-button-confirm-primary-foreground-color-focus),
      $focus-background-color: var(--gl-button-confirm-primary-background-color-focus),
      $focus-border-color: var(--gl-button-confirm-primary-border-color-focus),
      $active-color: var(--gl-button-confirm-primary-foreground-color-active),
      $active-background-color: var(--gl-button-confirm-primary-background-color-active),
      $active-border-color: var(--gl-button-confirm-primary-border-color-active)
    );
  }

  &.btn-confirm-secondary {
    @include gl-button-theme(
      $color: var(--gl-button-confirm-secondary-foreground-color-default),
      $background-color: var(--gl-button-confirm-secondary-background-color-default),
      $border-color: var(--gl-button-confirm-secondary-border-color-default),
      $hover-color: var(--gl-button-confirm-secondary-foreground-color-hover),
      $hover-background-color: var(--gl-button-confirm-secondary-background-color-hover),
      $hover-border-color: var(--gl-button-confirm-secondary-border-color-hover),
      $focus-color: var(--gl-button-confirm-secondary-foreground-color-focus),
      $focus-background-color: var(--gl-button-confirm-secondary-background-color-focus),
      $focus-border-color: var(--gl-button-confirm-secondary-border-color-focus),
      $active-color: var(--gl-button-confirm-secondary-foreground-color-active),
      $active-background-color: var(--gl-button-confirm-secondary-background-color-active),
      $active-border-color: var(--gl-button-confirm-secondary-border-color-active)
    );
  }

  &.btn-confirm-tertiary {
    @include gl-button-theme(
      $color: var(--gl-button-confirm-tertiary-foreground-color-default),
      $background-color: var(--gl-button-confirm-tertiary-background-color-default),
      $border-color: var(--gl-button-confirm-tertiary-border-color-default),
      $hover-color: var(--gl-button-confirm-tertiary-foreground-color-hover),
      $hover-background-color: var(--gl-button-confirm-tertiary-background-color-hover),
      $hover-border-color: var(--gl-button-confirm-tertiary-border-color-hover),
      $focus-color: var(--gl-button-confirm-tertiary-foreground-color-focus),
      $focus-background-color: var(--gl-button-confirm-tertiary-background-color-focus),
      $focus-border-color: var(--gl-button-confirm-tertiary-border-color-focus),
      $active-color: var(--gl-button-confirm-tertiary-foreground-color-active),
      $active-background-color: var(--gl-button-confirm-tertiary-background-color-active),
      $active-border-color: var(--gl-button-confirm-tertiary-border-color-active)
    );
  }

  &.btn-danger {
    @include gl-button-theme(
      $color: var(--gl-button-danger-primary-foreground-color-default),
      $background-color: var(--gl-button-danger-primary-background-color-default),
      $border-color: var(--gl-button-danger-primary-border-color-default),
      $hover-color: var(--gl-button-danger-primary-foreground-color-hover),
      $hover-background-color: var(--gl-button-danger-primary-background-color-hover),
      $hover-border-color: var(--gl-button-danger-primary-border-color-hover),
      $focus-color: var(--gl-button-danger-primary-foreground-color-focus),
      $focus-background-color: var(--gl-button-danger-primary-background-color-focus),
      $focus-border-color: var(--gl-button-danger-primary-border-color-focus),
      $active-color: var(--gl-button-danger-primary-foreground-color-active),
      $active-background-color: var(--gl-button-danger-primary-background-color-active),
      $active-border-color: var(--gl-button-danger-primary-border-color-active)
    );
  }

  &.btn-danger-secondary {
    @include gl-button-theme(
      $color: var(--gl-button-danger-secondary-foreground-color-default),
      $background-color: var(--gl-button-danger-secondary-background-color-default),
      $border-color: var(--gl-button-danger-secondary-border-color-default),
      $hover-color: var(--gl-button-danger-secondary-foreground-color-hover),
      $hover-background-color: var(--gl-button-danger-secondary-background-color-hover),
      $hover-border-color: var(--gl-button-danger-secondary-border-color-hover),
      $focus-color: var(--gl-button-danger-secondary-foreground-color-focus),
      $focus-background-color: var(--gl-button-danger-secondary-background-color-focus),
      $focus-border-color: var(--gl-button-danger-secondary-border-color-focus),
      $active-color: var(--gl-button-danger-secondary-foreground-color-active),
      $active-background-color: var(--gl-button-danger-secondary-background-color-active),
      $active-border-color: var(--gl-button-danger-secondary-border-color-active)
    );
  }

  &.btn-danger-tertiary {
    @include gl-button-theme(
      $color: var(--gl-button-danger-tertiary-foreground-color-default),
      $background-color: var(--gl-button-danger-tertiary-background-color-default),
      $border-color: var(--gl-button-danger-tertiary-border-color-default),
      $hover-color: var(--gl-button-danger-tertiary-foreground-color-hover),
      $hover-background-color: var(--gl-button-danger-tertiary-background-color-hover),
      $hover-border-color: var(--gl-button-danger-tertiary-border-color-hover),
      $focus-color: var(--gl-button-danger-tertiary-foreground-color-focus),
      $focus-background-color: var(--gl-button-danger-tertiary-background-color-focus),
      $focus-border-color: var(--gl-button-danger-tertiary-border-color-focus),
      $active-color: var(--gl-button-danger-tertiary-foreground-color-active),
      $active-background-color: var(--gl-button-danger-tertiary-background-color-active),
      $active-border-color: var(--gl-button-danger-tertiary-border-color-active)
    );
  }

  &.btn-default-secondary,
  &.btn-confirm-secondary,
  &.btn-danger-secondary,
  &.btn-reset-secondary,
  &.btn-reset-tertiary {
    @media (forced-colors: active) {
      color: LinkText; // stylelint-disable-line scale-unlimited/declaration-strict-value
      border: 1px solid LinkText; // stylelint-disable-line scale-unlimited/declaration-strict-value
    }
  }

  &.btn-default-tertiary,
  &.btn-confirm-tertiary,
  &.btn-danger-tertiary {
    @media (forced-colors: active) {
      color: LinkText; // stylelint-disable-line scale-unlimited/declaration-strict-value
      mix-blend-mode: initial;
      border: 0;
    }
  }

  &.btn-sm {
    @apply gl-px-3;
    @apply gl-leading-normal;
    @apply gl-text-base;
    min-height: $gl-button-small-size;
    min-width: $gl-button-small-size;

    gl-emoji {
      @apply gl-text-sm;
    }
  }

  &.btn-icon {
    @apply gl-leading-normal;
    @apply gl-p-0;

    .gl-button-icon {
      @apply gl-mr-0;
    }
  }

  &.button-ellipsis-horizontal,
  &.button-ellipsis-horizontal.btn-sm {
    @apply gl-px-2;
    min-height: auto;
    min-width: auto;

    svg {
      @apply gl-h-5;
      @apply gl-w-5;
      @apply gl-m-0;
    }
  }

  &.btn-label,
  &.btn-label:hover,
  &.btn-label:focus,
  &.btn-label:active {
    @apply gl-bg-subtle;
    @apply gl-cursor-default;
    user-select: text;
  }

  &.btn-link {
    @apply gl-bg-transparent;
    @apply gl-border-0;
    @apply gl-text-base;
    @apply gl-leading-normal;
    @apply gl-px-0;
    border-radius: var(--gl-button-link-border-radius);
    color: var(--gl-button-link-text-color-default);
    min-height: auto;
    min-width: auto;
    text-decoration-thickness: auto;
    text-decoration-style: solid;
    text-decoration-color: transparent;

    &:hover {
      @apply gl-bg-transparent;
      color: var(--gl-button-link-text-color-hover);
      text-decoration-color: var(--gl-button-link-text-color-hover);
    }

    &:active {
      color: var(--gl-button-link-text-color-active);
      text-decoration-color: var(--gl-button-link-text-color-active);
    }

    &:active,
    &:focus,
    &:focus:active {
      @apply gl-bg-transparent;
    }

    &.disabled,
    &[disabled] {
      @apply gl-bg-transparent;
      @apply gl-shadow-none;
    }

    @media (forced-colors: active) {
      color: LinkText; // stylelint-disable-line scale-unlimited/declaration-strict-value
    }
  }

  &.btn-block {
    @apply gl-w-full;

    // Vertically space out multiple block buttons
    + .btn-block {
      @apply gl-mt-2;
    }
  }

  &.disabled,
  &.disabled:hover,
  &.disabled:focus,
  &.disabled:active,
  &.disabled.selected,
  &[disabled],
  &[disabled]:hover,
  &[disabled]:focus,
  &[disabled]:active,
  &[disabled].selected {
    background-color: var(--gl-button-disabled-background-color);
    color: var(--gl-button-disabled-foreground-color);
    border-color: var(--gl-button-disabled-border-color);
    opacity: 1;
    cursor: not-allowed !important;

    &::before {
      background-color: var(--gl-button-disabled-border-color);
    }
  }

  &.disabled[class*="-tertiary"],
  &[disabled][class*="-tertiary"] {
    @apply gl-bg-transparent;
    @apply gl-shadow-none;
  }
}

// fixes sr-only elements positioning issue
// when positioned inside a drawer the visually hidden element might stick to the very bottom of the drawer
// extending the drawer size and introducing scrolling
// context: https://gitlab.com/gitlab-org/gitlab-services/design.gitlab.com/-/merge_requests/4866
.gl-button-text:has(.gl-sr-only) {
  position: relative;
}
