// Global mixins.
@use 'sass:math';

// Sets font styles.
@mixin fontSetup($size, $height, $weight: false, $rem: true) {
  @if $rem {
    font-size: pxRem($size);
  } @else {
    font-size: pxEm($size);
  }

  line-height: math.div($height, $size);
  @if $weight {
    font-weight: $weight;
  }
}

// Sets a flexible font size
//
// @param {length()} $sm - List of lengths, in px, representing font size and line height of the smallest size
// @param {length()} $md - List of lengths, in px, representing font size and line height of the medium size
// @param {length()} $lg - List of lengths, in px, representing font size and line height of the largest size
// @param {number | boolean} $weight - Font weight, or false
@mixin flexFont($sm, $md, $lg, $weight: false) {
  // Determine scaling factor so that the large font size is reached at 1440px
  $font-scale: math.div(nth($lg, 1), 14.4px) * 1cqw;
  // Set up clamp function
  $font-clamp: clamp(pxEm(nth($sm, 1)), $font-scale, pxEm(nth($lg, 1)));
  // Setup basic font styling from medium size
  @include fontSetup(nth($md, 1), nth($md, 2), $weight);

  // Check for support for clamp function
  @supports (font-size: $font-clamp) {
    // Set font size to clamp
    font-size: $font-clamp;
    // Set line height to ratio of largest line height to font size (unitless number)
    line-height: math.div(nth($lg, 2), nth($lg, 1));
  }
}

// Sets elevation styles.
@mixin elevationSetup(
  $key-offset-y,
  $key-spread,
  $ambient-offset-y,
  $ambient-spread,
  $ambient-blur
) {
  $shadow-color: rgba(map-get($google-colors, 'grey-800'), 0.3);
  $ambient-color: rgba(map-get($google-colors, 'grey-800'), 0.15);
  box-shadow:
    0 $key-offset-y $key-spread 0 $shadow-color,
    0 $ambient-offset-y $ambient-spread $ambient-blur $ambient-color;
}

// Sets styles for a specific level of elevation (between 0-5).
@mixin elevation($level) {
  @if ($level == 1) {
    @include elevationSetup(1px, 2px, 1px, 3px, 1px);
  } @else if ($level == 2) {
    @include elevationSetup(1px, 2px, 2px, 6px, 2px);
  } @else if ($level == 3) {
    @include elevationSetup(1px, 3px, 4px, 8px, 3px);
  } @else if ($level == 4) {
    @include elevationSetup(2px, 3px, 6px, 10px, 4px);
  } @else if ($level == 5) {
    @include elevationSetup(4px, 4px, 8px, 12px, 6px);
  } @else {
    // Elevation level 0 is just a border
    border: 1px solid map-get($google-colors, 'grey-300');
  }
}

// Sets different breakpoints based on language.
//   $map: (
//     key {string} <language code>: value {number, px} <min-width breakpoint>
//   )
//   $max: {boolean} Whether to use a max-width breakpoint
@mixin langmq($map, $max: false) {
  @each $lang, $bkpt in $map {
    [lang='#{$lang}'] & {
      @if $max {
        $maxbkpt: $bkpt - 1px;
        @include mq(max-width $maxbkpt) {
          @content;
        }
      } @else {
        @include mq($bkpt) {
          @content;
        }
      }
    }
  }
}

// DX mixin for max-width lang media queries
@mixin maxLangMQ($map) {
  @include langmq($map, true) {
    @content;
  }
}

// DX mixin for min-width lang media queries
@mixin minLangMQ($map) {
  @include langmq($map, false) {
    @content;
  }
}

// Expanding Nav styling
@mixin expandingNav($bkpt, $class, $small-space, $large-space) {
  @extend %expanding-nav;

  @include mq($bkpt) {
    background-color: transparent;
  }

  &[open] {
    @include mq($bkpt) {
      background: unset;
    }
  }

  &__summary {
    @extend %expanding-nav__summary;

    @include mq($bkpt) {
      background-color: unset;
      padding: unset;
    }
  }

  &__title {
    @extend %expanding-nav__title;
  }

  &__nav {
    @extend %expanding-nav__nav;

    @include mq($bkpt) {
      padding: 0;
    }
  }

  &--expand {
    @extend %expanding-nav--expand;

    .#{$class}[open] & {
      transform: scale(0.75) rotate(180deg);
    }
  }

  &__link {
    --space: #{$small-space};
    --bkg: var(--blue-50);
    --padding: 0.75rem;
    @extend %expanding-nav__link;

    @include mq($bkpt) {
      --space: #{$large-space};
    }

    &::after {
      // Because this is a CSS custom property, we need to include the unit
      --scoot: 0rem; /* stylelint-disable-line length-zero-no-unit */
      left: calc(var(--space) * -1 - var(--scoot));
      width: calc(100% + (var(--space) * 2) - 4px + var(--scoot));
    }

    /* stylelint-disable selector-max-compound-selectors */
    // Need to use tags selectors because ToC plugin doesn't allow for class customization
    // Will only go to a max depth of 4 because we start at H2s.
    ol ol &::after {
      --scoot: 1rem;
    }

    ol ol ol &::after {
      --scoot: 2rem;
    }

    ol ol ol ol &::after {
      --scoot: 3rem;
    }

    ol ol ol ol ol &::after {
      --scoot: 4rem;
    }
    /* stylelint-enable selector-max-compound-selectors */
  }
}

@mixin statsCircle($min-diameter, $diameter, $max-diameter) {
  align-items: center;
  background: var(--blue-600);
  border-radius: 50%;
  color: var(--white);
  display: flex;
  flex-direction: column;
  height: $diameter;
  justify-content: center;
  text-align: center;
  width: $diameter;

  @supports (height: clamp($min-diameter, 15.625vw, $max-diameter)) {
    $min: $min-diameter;
    $max: $min * 2;
    $factor: math.div($max-diameter, 10.24px) * 1vw;
    height: clamp($min, $factor, $max);
    width: clamp($min, $factor, $max);
  }
}

@mixin visuallyHidden {
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  height: 1px;
  overflow: hidden;
  position: absolute;
  white-space: nowrap;
  width: 1px;
}

// Sets top, left, width, and height as percentage values from a common divisor for a psuedo element shape.
//
// @param {length()} $params - List of lengths, in px, representing the top, left, width, and height dividends, respectively.
// @param {length} $size - px value to be used as the divisor.
@mixin pseudoShape($params, $size) {
  $measurements: (
    'top': nth($params, 1),
    'left': nth($params, 2),
    'width': nth($params, 3),
    'height': nth($params, 4),
  );

  @each $prop, $value in $measurements {
    #{$prop}: math.percentage(math.div($value, $size));
  }
}
