@use "sass:map";

@use "../../00-base/00-config/00-variables" as *;
@use "../../00-base/01-helpers" as *;

////////////////////////////////////////////////////////////////////////////////
// *
// * Buttons (in forms and text)
// *
////////////////////////////////////////////////////////////////////////////////

// * Mixins
// =============================================================================

// ** Button mixins: use this for buttons used on the site
// -- OPTIONS:
//    - background: the background-color you want (will darken on hover), default from config = spot color
//    - color: the text color you want (no change on hover by default), default from config = white
//    - border: a border around your button, will darken on hover
//    - size: default is false (normal size), it references another mixin to set more sizes (@mixin button-size)
// -- NOTE: remove what doesn't apply to the buttons used on the site or edit to your needs

@mixin button-size($size) {
  @if ($size == "sm") {
    padding: rem(9) rem(14);
    font-size: rem(12);
    line-height: rem(14);
  }

  @if ($size == "md") {
    padding: rem(11) rem(30);
    font-size: var(--fs-base);
    line-height: var(--lh-base);
  }

  @if ($size == "lg") {
    // padding: rem(18) rem(25) rem(15) rem(25);
  }
}

@mixin button($settings: null) {
  // Some defaults, used in case no $settings were given
  // or when either of the settings is omitted.
  $color-default: var(--clr-button);
  $background-default: var(--clr-button-bg);
  $border-default: false;
  $border-width-default: rem(2);
  $hover-default: var(--clr-button);
  $hover-bg-default: var(--clr-button-hover-bg);
  $hover-border-default: false;
  $size-default: "md";
  $border-radius-default: rem(5);
  $box-shadow-default: false;

  // set up the actual variables that will be used
  $color: null;
  $background: null;
  $border: null;
  $border-width: null;
  $hover: null;
  $hover-bg: null;
  $hover-border: null;
  $size: null;
  $border-radius: null;
  $box-shadow: null;

  // map the variables to the settings if actual settings are passed
  @if ($settings != null) {
    $color: map.get($settings, color);
    $background: map.get($settings, background);
    $border: map.get($settings, border);
    $border-width: map.get($settings, border-width);
    $hover: map.get($settings, hover);
    $hover-bg: map.get($settings, hover-bg);
    $hover-border: map.get($settings, hover-border);
    $size: map.get($settings, size);
    $border-radius: map.get($settings, border-radius);
    $box-shadow: map.get($settings, box-shadow);
  }

  // if any are not filled in, fall back to defaults
  @if ($background == null) {
    $background: $background-default;
  }
  @if ($border == null) {
    $border: $border-default;
  }
  @if ($border-width == null) {
    $border-width: $border-width-default;
  }
  @if ($color == null) {
    $color: $color-default;
  }
  @if ($hover == null) {
    $hover: $hover-default;
  }
  @if ($hover-bg == null) {
    $hover-bg: $hover-bg-default;
  }
  @if ($hover-border == null) {
    $hover-border: $hover-border-default;
  }
  @if ($size == null) {
    $size: $size-default;
  }
  @if ($border-radius == null) {
    $border-radius: $border-radius-default;
  }
  @if ($box-shadow == null) {
    $box-shadow: $box-shadow-default;
  }

  cursor: pointer;
  display: inline-block;
  border: 0 none;
  border-radius: $border-radius;
  // Load what defines the size: font-size + line-height, padding, ….
  @include button-size($size);
  font-weight: var(--fw-normal);
  text-align: center;
  text-decoration: none;
  text-transform: uppercase;

  @if ($background == transparent) {
    background: transparent;
  } @else {
    background: hsl($background);
  }
  background-repeat: no-repeat;
  transition-property: background, color, box-shadow;
  transition-duration: $duration;
  transition-timing-function: $easing;

  // Add border via box-shadow, so we don't have to mess with changes in
  // padding when there is none also keep into account that there might already
  // be a box-shadow, so you have to combine the 2.

  // Shadow + border.
  @if ($box-shadow != false and $border != false) {
    box-shadow: 0 rem(3) rem(20) hsla(var(--clr-black), 0.2),
      inset 0 0 0 $border-width hsl($border);
  }
  // Only shadow.
  @else if ($box-shadow != false) {
    box-shadow: 0 rem(3) rem(20) hsla(var(--clr-black), 0.2);
  }
  // Only border.
  @else if ($border != false) {
    box-shadow: inset 0 0 0 $border-width hsl($border);
  }

  // We can't use `&`, because of the linting complaining on multiple
  // selectors.
  // There is currently a ticking regarding this issue.
  // @todo: check of issue is resolved.
  // https://github.com/stylelint/stylelint/issues/7893#issuecomment-2541920579
  &, /* stylelint-disable-line */
  &:visited {
    color: hsl($color);
  }

  &:is(:hover, :focus-visible, :active) {
    border: 0 none;
    color: hsl($hover);
    background: hsl($hover-bg);

    // Shadow + hover border.
    @if ($box-shadow != false and $hover-border != false) {
      box-shadow: 0 rem(3) rem(20) hsla(var(--clr-black), 0.2),
        inset 0 0 0 $border-width hsl($hover-border);
    }
    // Only shadow.
    @else if ($box-shadow != false and $hover-border == false) {
      // If normal state has border, let's animate to that.
      @if ($border != false) {
        box-shadow: 0 rem(3) rem(20) hsla(var(--clr-black), 0.2),
          inset 0 0 0 $border-width hsla($border, 0);
      }
      // Otherwise, just leave the shadow.
      @else {
        box-shadow: 0 rem(3) rem(20) hsla(var(--clr-black), 0.2);
      }
    }
    // Only hover border.
    @else if ($box-shadow == false and $hover-border != false) {
      box-shadow: inset 0 0 0 $border-width hsl($hover-border);
    }
    // No hover borders && no shadow.
    @else {
      // Normal state does have border, so we need to animate to 0% opacity.
      @if ($border != false) {
        box-shadow: inset 0 0 0 $border-width hsla($border, 0);
      }
    }
  }

  &:is(.disabled, :disabled, [disabled]) {
    pointer-events: none;
    cursor: default;
    opacity: 0.5;
  }
}

// ** Example of use: to make a specific button
//
// -- Need a gradient background instead of a color? Just use the gradient property.
//    E.g. background: linear-gradient(to right, red, yellow).
//    E.g. hover-bg: linear-gradient(to right, yellow, red).
//
@mixin button-primary($size: "md") {
  $settings-button-primary: (
    size: $size
  );
  @include button($settings-button-primary);
}

@mixin button-secondary($size: "md") {
  $settings-button-secondary: (
    color: var(--clr-button-bg),
    border: var(--clr-button-bg),
    background: transparent,
    hover: var(--clr-white),
    hover-bg: var(--clr-button-bg),
    hover-border: false,
    size: $size
  );
  @include button($settings-button-secondary);
}

@mixin button-negative($size: "md") {
  $settings-button-negative: (
    color: var(--clr-spot-2),
    background: var(--clr-white),
    hover: var(--clr-button-hover),
    hover-bg: var(--clr-button-hover-bg),
    size: $size
  );
  @include button($settings-button-negative);
}

@mixin button-negative-secondary($size: "md") {
  $settings-button-negative-secondary: (
    color: var(--clr-white),
    border: var(--clr-white),
    background: transparent,
    hover: var(--clr-white),
    hover-bg: var(--clr-button-hover-bg),
    hover-border: false,
    size: $size
  );
  @include button($settings-button-negative-secondary);
}
