@use 'sass:meta';
@import './../../functions', './../../mixins', './../../variables';
@import './icons', './mixins';

@layer base {
  button,
  .button {
    @include transition(background color border-color text-decoration-color);

    background: get-map($theme, 'button_primary_bg');
    padding: px-to-rem(get-map($button-medium, 'padding-top'))
      px-to-rem(get-map($button-medium, 'padding-horizontal'))
      px-to-rem(get-map($button-medium, 'padding-bottom'))
      px-to-rem(get-map($button-medium, 'padding-horizontal'));
    position: relative;
    text-align: center;
    font-size: px-to-rem(get-map($button-medium, 'font-size'));
    font-weight: 700;
    text-decoration: none;
    border-radius: 360rem; // Completely round corners. This could be any large number but 360 evokes a circle well!
    border: none;
    cursor: pointer;
    box-sizing: border-box;
    display: inline-block;

    &,
    &:hover,
    &:active,
    &:focus,
    &:focus-visible {
      color: get-map($theme, 'button_primary');
    }

    &:hover {
      background: get-map($theme, 'button_primary_bg_hover');
    }

    &:active,
    &.active {
      background: get-map($theme, 'button_primary_bg_active');
    }

    &:focus,
    &:focus-visible {
      background: get-map($theme, 'button_primary_bg_focus');
    }

    // TODO: remove when we have new styling
    &.new {
      background: get-map($theme, 'button_new_primary_bg');
      padding: px-to-rem(get-map($button-medium, 'padding-top_new'))
        px-to-rem(get-map($button-medium, 'padding-horizontal_new'))
        px-to-rem(get-map($button-medium, 'padding-bottom_new'))
        px-to-rem(get-map($button-medium, 'padding-horizontal_new'));
      color: get-map($theme, 'button_primary');

      &:hover,
      &:focus,
      &:focus-visible,
      &:active {
        background: get-map($theme, 'button_new_primary_bg_hover');
      }
    }

    @each $size, $styles in $sizes {
      &.#{$size} {
        padding: px-to-rem(get-map($styles, 'padding-top'))
          px-to-rem(get-map($styles, 'padding-horizontal'))
          px-to-rem(get-map($styles, 'padding-bottom'))
          px-to-rem(get-map($styles, 'padding-horizontal'));
        font-size: px-to-rem(get-map($styles, 'font-size'));

        // TODO: remove `new` styling when we switch to new styling everywhere
        &.new {
          padding: px-to-rem(get-map($styles, 'padding-top_new'))
            px-to-rem(get-map($styles, 'padding-horizontal_new'))
            px-to-rem(get-map($styles, 'padding-bottom_new'))
            px-to-rem(get-map($styles, 'padding-horizontal_new'));
        }

        &.icon {
          margin-top: px-to-rem(get-map($styles, 'icon-offset'));

          &.left::before {
            margin-right: px-to-rem(get-map($styles, 'icon-gutter'));
          }

          &.right::before {
            margin-left: px-to-rem(get-map($styles, 'icon-gutter'));
          }
        }
      }
    }

    &.full-width {
      width: 100%;
    }

    &.destructive {
      &,
      &:hover,
      &:active,
      &:focus,
      &:focus-visible {
        background: get-map($theme, 'button_primary_destructive_bg');
        color: get-map($theme, 'button_primary_destructive');
      }

      &:hover,
      &:active {
        background: get-map($theme, 'button_primary_destructive_bg_hover');
      }

      &:focus,
      &:focus-visible {
        box-shadow: $outline get-map($theme, 'button_primary_destructive_box-shadow');
      }
    }

    &.secondary {
      background: get-map($theme, 'button_secondary_bg');
      border: px-to-rem(get-map($secondary, 'border')) solid
        get-map($theme, 'button_secondary_border');

      &,
      &:hover {
        color: get-map($theme, 'button_secondary');
      }

      &:hover {
        background: get-map($theme, 'button_secondary_bg_hover');
      }

      &:active,
      &:focus,
      &:focus-visible {
        color: get-map($theme, 'button_secondary_focus');
        border-color: get-map($theme, 'button_secondary_border_focus');
      }

      &:active {
        background: get-map($theme, 'button_secondary_bg_active');
      }

      &:focus,
      &:focus-visible {
        background: get-map($theme, 'button_secondary_bg_focus');
      }

      &.muted {
        border-color: get-map($theme, 'button_secondary_border_muted');

        &,
        &:active {
          background: get-map($theme, 'button_secondary_bg_muted');
          color: get-map($theme, 'button_secondary_muted');
        }

        &:hover,
        &:focus,
        &:focus-visible {
          background: get-map($theme, 'button_secondary_bg_muted_hover');
          color: get-map($theme, 'button_secondary_muted_hover');
          border-color: get-map($theme, 'button_secondary_border_muted_hover');
        }
      }

      &.destructive {
        &,
        &:hover,
        &:active,
        &:focus,
        &:focus-visible {
          background: get-map($theme, 'button_secondary_bg_destructive');
          color: get-map($theme, 'button_secondary_destructive');
          border-color: get-map($theme, 'button_secondary_border_destructive');
        }
      }

      &.disabled {
        &,
        &:hover,
        &:active,
        &:focus,
        &:focus-visible {
          background: get-map($theme, 'button_secondary_bg_disabled');
          color: get-map($theme, 'button_secondary_disabled');
          border-color: get-map($theme, 'button_secondary_border_disabled');
        }
      }

      // TODO: remove when we have new styling
      &.new {
        border: none;

        &,
        &:hover,
        &:active,
        &:focus,
        &:focus-visible {
          color: get-map($theme, 'button_new_secondary');
        }

        &:hover,
        &:active,
        &:focus,
        &:focus-visible {
          background: get-map($theme, 'button_new_secondary_bg_hover');
        }
      }
    }

    &.tertiary {
      &:not(.new) {
        padding: px-to-rem(get-map($tertiary, 'padding-top'))
          px-to-rem(get-map($tertiary, 'padding-horizontal'))
          px-to-rem(get-map($tertiary, 'padding-bottom'))
          px-to-rem(get-map($tertiary, 'padding-horizontal'));
        bottom: px-to-rem(get-map($tertiary, 'padding-top'));
        right: px-to-rem(get-map($tertiary, 'padding-horizontal'));
      }

      text-decoration: underline;
      text-decoration-color: transparent;

      &,
      &:focus,
      &:focus-visible {
        background: get-map($theme, 'button_tertiary_bg');
        color: get-map($theme, 'button_tertiary');
        text-decoration-color: get-map($theme, 'button_tertiary_text-decoration');
      }

      &:hover,
      &:active {
        text-decoration-color: currentcolor;
      }

      &:hover {
        color: get-map($theme, 'button_tertiary_hover');
      }

      &:active {
        color: get-map($theme, 'button_tertiary_active');
      }

      &.muted {
        color: get-map($theme, 'button_tertiary_muted');

        &:hover,
        &:focus,
        &:focus-visible {
          color: get-map($theme, 'button_tertiary_muted_hover');
        }
      }

      &.disabled {
        &,
        &:hover,
        &:active,
        &:focus,
        &:focus-visible {
          background: get-map($theme, 'button_tertiary_disabled_bg');
          color: get-map($theme, 'button_tertiary_disabled');
          text-decoration-color: get-map(
            $theme,
            'button_tertiary_disabled_text-decoration'
          );
        }
      }

      &.full-width {
        right: 0;
      }

      // TODO: remove when we have new styling
      &.new {
        color: get-map($theme, 'button_new_tertiary');
        text-decoration-color: currentcolor;

        &:hover,
        &:active,
        &:focus,
        &:focus-visible {
          background: get-map($theme, 'button_new_secondary_bg_hover');
          color: get-map($theme, 'button_new_secondary');
        }
      }
    }

    &.icon {
      display: inline-flex;
      align-items: center;
      flex-flow: row;
      place-content: center;

      &::before {
        content: '';
        background: currentcolor;
        width: px-to-rem(get-map($button-medium, 'icon-width'));
        height: px-to-rem(get-map($button-medium, 'icon-width'));
        display: inline-block;
        vertical-align: middle;
      }

      &.left {
        &::before {
          margin-right: px-to-rem(get-map($button-medium, 'icon-gutter'));
        }

        &.no-text::before {
          margin-right: 0;
        }
      }

      &.right {
        &::before {
          margin-left: px-to-rem(get-map($button-medium, 'icon-gutter'));
          order: 2;
        }

        &.no-text::before {
          margin-left: 0;
        }
      }

      @each $icon, $large-icon, $medium-icon, $small-icon in $icons {
        $icon-sizes: ('large', $large-icon), ('medium', $medium-icon),
          ('small', $small-icon);

        @at-root {
          %icon-#{$icon} {
            @include icon-styling($icon, $icon-sizes);
          }
        }

        &.#{$icon} {
          @extend %icon-#{$icon};
        }

        &.hover_#{$icon} {
          &:hover,
          &:focus,
          &:focus-visible {
            @extend %icon-#{$icon};
          }
        }
      }

      &.animate {
        &::before {
          @include transition(transform, #{get-map($animation, 'duration')}s, ease);

          transform: none;
        }

        &.bounce {
          @include animate {
            @keyframes bounce {
              0%,
              100% {
                transform: scale(1);
              }

              70% {
                transform: scale(#{get-map($animation-bounce, 'scale')});
              }
            }

            &:focus,
            &:active,
            &.do-animation {
              &::before {
                animation: bounce #{get-map($animation-bounce, 'duration')}s #{get-map(
                    $animation-bounce,
                    'iteration'
                  )};
              }
            }
          }
        }

        &.rotate-180::before {
          transform: rotate(180deg);
        }
      }
    }

    &.disabled {
      cursor: not-allowed;
      opacity: 0.3;
    }

    &[data-hover-text] {
      position: relative;

      &::before,
      .text {
        @include transition(opacity);

        opacity: 1;
      }

      &::after {
        @include transition(
          width height opacity right,
          0s 0s 0.2s 0.2s,
          ease-in-out,
          0s 0s 0.1s 0.1s
        );

        content: '';
        width: 0;
        height: 0;
        position: absolute;
        top: px-to-rem(get-map($secondary-destruction, 'offset'));
        right: get-map($secondary-destruction, 'right');
        display: flex;
        align-items: center;
        justify-content: center;
        opacity: 0;
      }

      &:hover,
      &:focus {
        &::before,
        .text {
          opacity: 0;
        }

        &::after {
          content: attr(data-hover-text);
          width: 100%;
          height: 100%;
          right: 0;
          opacity: 1;
        }
      }
    }
  }
}
