@use 'sass:map';
@use '../utils/constants.scss';
@use '../utils/tokens.scss' as tokens;
@use '../utils/stateLayerVars.scss' as state-layer-vars;
@use '../utils/mixins.scss';
@use './button.vars.scss' as vars;
@use './spinner.vars.scss' as spinner;

@import '@viasat/beam-tokens/components/Button';

%icon-size {
  display: block;
  width: var(#{vars.$buttonIconSizeVarName});
  height: var(#{vars.$buttonIconSizeVarName});
}

.#{vars.$buttonBaseClass} {
  cursor: pointer;
  position: relative;
  display: inline-flex;
  flex-direction: row;
  width: fit-content;
  padding: var(#{vars.$buttonPaddingYVarName}) var(#{vars.$buttonPaddingXVarName});
  justify-content: center;
  align-items: center;
  gap: tokens.$bm-comp-btn-space-gap;
  border: none;
  border-radius: tokens.$bm-comp-btn-radius-container;
  max-width: 100%;

  // Sizes
  $defaultSize: map.get(vars.$sizes, 'md');
  font: #{map.get($defaultSize, 'font')};
  min-width: #{map.get($defaultSize, 'min-width')};
  min-height: #{map.get($defaultSize, 'min-height')};
  #{vars.$buttonPaddingYVarName}: #{map.get($defaultSize, 'padding-y')};
  #{vars.$buttonPaddingXVarName}: #{map.get($defaultSize, 'padding-x')};
  #{vars.$buttonIconSizeVarName}: #{map.get($defaultSize, 'icon')};

  @each $size, $props in vars.$sizes {
    &--#{$size} {
      font: #{map.get($props, 'font')};
      min-width: #{map.get($props, 'min-width')};
      min-height: #{map.get($props, 'min-height')};
      #{vars.$buttonPaddingYVarName}: #{map.get($props, 'padding-y')};
      #{vars.$buttonPaddingXVarName}: #{map.get($props, 'padding-x')};
      #{vars.$buttonIconSizeVarName}: #{map.get($props, 'icon')};
    }
  }

  &--icon-only {
    padding: unset;
  }

  &__label {
    z-index: 1;
    position: relative;
    padding: 0 tokens.$bm-comp-btn-space-label-x;
    text-align: start;
  }

  // Appearance & Kinds
  $defaultAppearance: 'accent';
  $defaultKind: 'filled';
  $defaultProps: map.get(
    map.get(vars.$appearancesAndKinds, $defaultAppearance),
    $defaultKind
  );

  & {
    background: map.get($defaultProps, 'background');
    color: map.get($defaultProps, 'color');
    border-color: map.get($defaultProps, 'border-color');
  }

  @each $appearance, $kinds in vars.$appearancesAndKinds {
    @each $kind, $props in $kinds {
      &--#{$appearance}-#{$kind} {
        background: map.get($props, 'background');
        color: map.get($props, 'color');
        @include mixins.simulated-inset-outline(
          tokens.$bm-comp-btn-border-width,
          solid,
          map.get($props, 'border-color'),
          -0.0625rem
        );

        .#{vars.$buttonLoadingSpinner} {
          .#{spinner.$circleSvgClassBase} {
            stroke: map.get($props, 'color');
          }

          .#{spinner.$circleBgClassBase} {
            stroke: map.get($props, 'color');
            opacity: tokens.$bm-comp-btn-opacity-spinner-track;
          }
        }

        @if ($appearance == 'accent' or $appearance == 'destructive') and
          $kind ==
          'filled'
        {
          #{state-layer-vars.getStateLayerSelector('&', 'hover')} {
            #{state-layer-vars.$background}: tokens.$bm-sem-color-state-layer-hover-strong;
          }

          #{state-layer-vars.getStateLayerSelector('&', 'active')} {
            #{state-layer-vars.$background}: tokens.$bm-sem-color-state-layer-active-strong;
          }
        }

        @if $appearance == 'neutral' and $kind == 'filled' {
          #{state-layer-vars.getStateLayerSelector('&', 'hover')} {
            #{state-layer-vars.$background}: tokens.$bm-sem-color-state-layer-hover-inverse;
          }

          #{state-layer-vars.getStateLayerSelector('&', 'active')} {
            #{state-layer-vars.$background}: tokens.$bm-sem-color-state-layer-active-inverse;
          }
        }

        @if $kind == 'bare' {
          min-height: unset !important;
          min-width: unset !important;
          padding: tokens.$bm-comp-btn-space-bare-y tokens.$bm-comp-btn-space-bare-x;
          border-radius: tokens.$bm-sem-radius-sm;
          gap: tokens.$bm-comp-btn-space-bare-gap;

          display: flex;
          align-items: center;
          justify-content: center;

          .#{vars.$buttonBaseClass}__label {
            padding: 0 tokens.$bm-comp-btn-space-bare-label-x;
          }

          .#{state-layer-vars.$stateLayerBaseClass} {
            $offset: calc(0px - tokens.$bm-sem-size-focus-offset);
            #{state-layer-vars.$top}: $offset;
            #{state-layer-vars.$right}: $offset;
            #{state-layer-vars.$bottom}: $offset;
            #{state-layer-vars.$left}: $offset;
            #{state-layer-vars.$outline-offset}: 0 !important;
          }
        }
      }
    }
  }

  &[class*='filled'] {
    box-shadow: tokens.$bm-comp-btn-shadow;
  }

  // Disabled
  &:disabled {
    cursor: not-allowed;
    opacity: tokens.$bm-sem-opacity-disabled;
  }

  // Loading
  &--loading {
    cursor: not-allowed;
    .#{spinner.$spinnerWrapClassBase} {
      margin: unset;
    }
  }

  // Fluid
  &--fluid {
    width: 100%;
  }

  // With Icon
  &__icon-wrap svg,
  ::slotted([slot='iconBefore']),
  ::slotted([slot='iconAfter']) {
    @extend %icon-size;
  }
}
