@use 'sass:math';

@import '../shared-styles/index';

@mixin make-grid-columns-bem-style(
  $columns: $grid-columns,
  $gutters: $grid-gutter-widths,
  $breakpoints: $grid-breakpoints
) {
  &.nx-grid__column {
    position: relative;
    width: 100%;
    min-height: 1px; // Prevent columns from collapsing when empty

    @include make-gutters($gutters);
  }

  @each $breakpoint in map-keys($breakpoints) {
    $infix: breakpoint-infix($breakpoint, $breakpoints);

    @include media-breakpoint-up($breakpoint, $breakpoints) {
      &.nx-grid__column#{$infix} {
        flex-basis: 0;
        flex-grow: 1;
        max-width: 100%;
      }

      &.nx-grid__column#{$infix}-fit {
        flex: 0 0 auto;
        width: auto;
      }

      @for $i from 1 through $columns {
        &.nx-grid__column#{$infix}-#{$i} {
          @include make-col($i, $columns);
        }
      }

      // `$columns - 1` because offsetting by the width of an entire row isn't possible
      @for $i from 0 through ($columns - 1) {
        @if not($infix == '' and $i == 0) {
          // Avoid emitting useless .offset-xs-0
          &.nx-grid--offset#{$infix}-#{$i} {
            @include make-col-modifier(offset, $i, $columns);
          }
        }
      }
    }
  }
}

@mixin make-grid-columns-bem-style-by-container-query(
  $columns: $grid-columns,
  $gutters: $grid-gutter-widths,
  $breakpoints: $grid-breakpoints
) {
  &.nx-grid__column {
    position: relative;
    width: 100%;
    min-height: 1px; // Prevent columns from collapsing when empty

    @include make-gutters-by-container-query($gutters);
  }

  @each $breakpoint in map-keys($breakpoints) {
    $infix: breakpoint-infix($breakpoint, $breakpoints);

    @include container-breakpoint-up($breakpoint, $breakpoints) {
      &.nx-grid__column#{$infix} {
        flex-basis: 0;
        flex-grow: 1;
        max-width: 100%;
      }

      &.nx-grid__column#{$infix}-fit {
        flex: 0 0 auto;
        width: auto;
      }

      @for $i from 1 through $columns {
        &.nx-grid__column#{$infix}-#{$i} {
          @include make-col($i, $columns);
        }
      }

      // `$columns - 1` because offsetting by the width of an entire row isn't possible
      @for $i from 0 through ($columns - 1) {
        @if not($infix == '' and $i == 0) {
          // Avoid emitting useless .offset-xs-0
          &.nx-grid--offset#{$infix}-#{$i} {
            @include make-col-modifier(offset, $i, $columns);
          }
        }
      }
    }
  }
}

@mixin make-container-by-media-query($gutters: $grid-gutter-widths) {
  position: relative;
  margin-left: auto;
  margin-right: auto;

  @include media-breakpoint-up(xsmall) {
    padding-right: $grid-gutter-width-mobile;
    padding-left: $grid-gutter-width-mobile;
  }

  @include media-breakpoint-up(medium) {
    padding-right: $grid-gutter-width-base;
    padding-left: $grid-gutter-width-base;
  }
}

@mixin make-gutters($gutters: $grid-gutter-widths) {
  @each $breakpoint in map-keys($gutters) {
    @include media-breakpoint-up($breakpoint) {
      $gutter: map-get($gutters, $breakpoint);
      padding-right: ($gutter * 0.5);
      padding-left: ($gutter * 0.5);
    }
  }
}
@mixin make-gutters-by-container-query($gutters: $grid-gutter-widths) {
  @each $breakpoint in map-keys($gutters) {
    @include container-breakpoint-up($breakpoint) {
      $gutter: map-get($gutters, $breakpoint);
      padding-right: ($gutter * 0.5);
      padding-left: ($gutter * 0.5);
    }
  }
}

@mixin make-row($gutters: $grid-gutter-widths) {
  display: flex;
  flex-wrap: wrap;

  @each $breakpoint in map-keys($gutters) {
    @include media-breakpoint-up($breakpoint) {
      $gutter: map-get($gutters, $breakpoint);
      margin-right: math.div($gutter, -2);
      margin-left: math.div($gutter, -2);
      position: relative;
    }
  }
}

@mixin make-row-by-container-query($gutters: $grid-gutter-widths) {
  display: flex;
  flex-wrap: wrap;

  @each $breakpoint in map-keys($gutters) {
    @include container-breakpoint-up($breakpoint) {
      $gutter: map-get($gutters, $breakpoint);
      margin-right: math.div($gutter, -2);
      margin-left: math.div($gutter, -2);
      position: relative;
    }
  }
}

@mixin make-col-ready($gutters: $grid-gutter-widths) {
  position: relative;
  // Prevent columns from becoming too narrow when at smaller grid tiers by
  // always setting `width: 100%;`. This works because we use `flex` values
  // later on to override this initial width.
  width: 100%;
  min-height: 1px; // Prevent collapsing

  @each $breakpoint in map-keys($gutters) {
    @include media-breakpoint-up($breakpoint) {
      $gutter: map-get($gutters, $breakpoint);
      padding-right: ($gutter * 0.5);
      padding-left: ($gutter * 0.5);
    }
  }
}

@mixin make-col($size, $columns: $grid-columns) {
  container-name: size-#{$size}-columns-#{$columns};
  flex: 0 0 percentage(math.div($size, $columns));
  // width: percentage($size / $columns);
  // Add a `max-width` to ensure content within each column does not blow out
  // the width of the column. Applies to IE10+ and Firefox. Chrome and Safari
  // do not appear to require this.
  max-width: percentage(math.div($size, $columns));
}

@mixin make-col-modifier($type, $size, $columns) {
  // Work around the lack of dynamic mixin @include support (https://github.com/sass/sass/issues/626)
  @if $type == push {
    @include make-col-push($size, $columns);
  } @else if $type == pull {
    @include make-col-pull($size, $columns);
  } @else if $type == offset {
    @include make-col-offset($size, $columns);
  }
}

@mixin make-col-offset($size, $columns: $grid-columns) {
  margin-left: percentage(math.div($size, $columns));

  [dir='rtl'] & {
    margin-left: initial;
    margin-right: percentage(math.div($size, $columns));
  }
}

@mixin make-col-push($size, $columns: $grid-columns) {
  left: if($size > 0, percentage(math.div($size, $columns)), auto);

  [dir='rtl'] & {
    left: auto;
    right: if($size > 0, percentage(math.div($size, $columns)), auto);
  }
}

@mixin make-col-pull($size, $columns: $grid-columns) {
  right: if($size > 0, percentage(math.div($size, $columns)), auto);

  [dir='rtl'] & {
    right: auto;
    left: if($size > 0, percentage(math.div($size, $columns)), auto);
  }
}

/** ROW VARIATIONS from grid-variations.scss **/
@mixin make-row-variations {
  @each $breakpoint in map-keys($grid-breakpoints) {
    @include media-breakpoint-up($breakpoint) {
      $infix: breakpoint-infix($breakpoint, $grid-breakpoints);

      &.nx-flex#{$infix}-row {
        flex-direction: row !important;
      }
      &.nx-flex#{$infix}-column {
        flex-direction: column !important;
      }
      &.nx-flex#{$infix}-row-reverse {
        flex-direction: row-reverse !important;
      }
      &.nx-flex#{$infix}-column-reverse {
        flex-direction: column-reverse !important;
      }

      &.nx-flex#{$infix}-wrap {
        flex-wrap: wrap !important;
      }
      &.nx-flex#{$infix}-nowrap {
        flex-wrap: nowrap !important;
      }
      &.nx-flex#{$infix}-wrap-reverse {
        flex-wrap: wrap-reverse !important;
      }

      &.nx-justify-content#{$infix}-start {
        justify-content: flex-start !important;
      }
      &.nx-justify-content#{$infix}-end {
        justify-content: flex-end !important;
      }
      &.nx-justify-content#{$infix}-center {
        justify-content: center !important;
      }
      &.nx-justify-content#{$infix}-between {
        justify-content: space-between !important;
      }
      &.nx-justify-content#{$infix}-around {
        justify-content: space-around !important;
      }

      &.nx-align-items#{$infix}-start {
        align-items: flex-start !important;
      }
      &.nx-align-items#{$infix}-end {
        align-items: flex-end !important;
      }
      &.nx-align-items#{$infix}-center {
        align-items: center !important;
      }
      &.nx-align-items#{$infix}-baseline {
        align-items: baseline !important;
      }
      &.nx-align-items#{$infix}-stretch {
        align-items: stretch !important;
      }

      &.nx-align-content#{$infix}-start {
        align-content: flex-start !important;
      }
      &.nx-align-content#{$infix}-end {
        align-content: flex-end !important;
      }
      &.nx-align-content#{$infix}-center {
        align-content: center !important;
      }
      &.nx-align-content#{$infix}-between {
        align-content: space-between !important;
      }
      &.nx-align-content#{$infix}-around {
        align-content: space-around !important;
      }
      &.nx-align-content#{$infix}-stretch {
        align-content: stretch !important;
      }
    }
  }
}

@mixin make-row-variations-by-container-query {
  @each $breakpoint in map-keys($grid-breakpoints) {
    @include container-breakpoint-up($breakpoint) {
      $infix: breakpoint-infix($breakpoint, $grid-breakpoints);

      &.nx-flex#{$infix}-row {
        flex-direction: row !important;
      }
      &.nx-flex#{$infix}-column {
        flex-direction: column !important;
      }
      &.nx-flex#{$infix}-row-reverse {
        flex-direction: row-reverse !important;
      }
      &.nx-flex#{$infix}-column-reverse {
        flex-direction: column-reverse !important;
      }

      &.nx-flex#{$infix}-wrap {
        flex-wrap: wrap !important;
      }
      &.nx-flex#{$infix}-nowrap {
        flex-wrap: nowrap !important;
      }
      &.nx-flex#{$infix}-wrap-reverse {
        flex-wrap: wrap-reverse !important;
      }

      &.nx-justify-content#{$infix}-start {
        justify-content: flex-start !important;
      }
      &.nx-justify-content#{$infix}-end {
        justify-content: flex-end !important;
      }
      &.nx-justify-content#{$infix}-center {
        justify-content: center !important;
      }
      &.nx-justify-content#{$infix}-between {
        justify-content: space-between !important;
      }
      &.nx-justify-content#{$infix}-around {
        justify-content: space-around !important;
      }

      &.nx-align-items#{$infix}-start {
        align-items: flex-start !important;
      }
      &.nx-align-items#{$infix}-end {
        align-items: flex-end !important;
      }
      &.nx-align-items#{$infix}-center {
        align-items: center !important;
      }
      &.nx-align-items#{$infix}-baseline {
        align-items: baseline !important;
      }
      &.nx-align-items#{$infix}-stretch {
        align-items: stretch !important;
      }

      &.nx-align-content#{$infix}-start {
        align-content: flex-start !important;
      }
      &.nx-align-content#{$infix}-end {
        align-content: flex-end !important;
      }
      &.nx-align-content#{$infix}-center {
        align-content: center !important;
      }
      &.nx-align-content#{$infix}-between {
        align-content: space-between !important;
      }
      &.nx-align-content#{$infix}-around {
        align-content: space-around !important;
      }
      &.nx-align-content#{$infix}-stretch {
        align-content: stretch !important;
      }
    }
  }
}

@mixin make-col-variations {
  @each $breakpoint in map-keys($grid-breakpoints) {
    @include media-breakpoint-up($breakpoint) {
      $infix: breakpoint-infix($breakpoint, $grid-breakpoints);

      &.nx-flex#{$infix}-first {
        order: -1;
      }
      &.nx-flex#{$infix}-last {
        order: 1;
      }
      &.nx-flex#{$infix}-unordered {
        order: 0;
      }

      &.nx-align-self#{$infix}-auto {
        align-self: auto !important;
      }
      &.nx-align-self#{$infix}-start {
        align-self: flex-start !important;
      }
      &.nx-align-self#{$infix}-end {
        align-self: flex-end !important;
      }
      &.nx-align-self#{$infix}-center {
        align-self: center !important;
      }
      &.nx-align-self#{$infix}-baseline {
        align-self: baseline !important;
      }
      &.nx-align-self#{$infix}-stretch {
        align-self: stretch !important;
      }
    }
  }
}

@mixin make-col-variations-by-container-query {
  @each $breakpoint in map-keys($grid-breakpoints) {
    @include container-breakpoint-up($breakpoint) {
      $infix: breakpoint-infix($breakpoint, $grid-breakpoints);

      &.nx-flex#{$infix}-first {
        order: -1;
      }
      &.nx-flex#{$infix}-last {
        order: 1;
      }
      &.nx-flex#{$infix}-unordered {
        order: 0;
      }

      &.nx-align-self#{$infix}-auto {
        align-self: auto !important;
      }
      &.nx-align-self#{$infix}-start {
        align-self: flex-start !important;
      }
      &.nx-align-self#{$infix}-end {
        align-self: flex-end !important;
      }
      &.nx-align-self#{$infix}-center {
        align-self: center !important;
      }
      &.nx-align-self#{$infix}-baseline {
        align-self: baseline !important;
      }
      &.nx-align-self#{$infix}-stretch {
        align-self: stretch !important;
      }
    }
  }
}
