// Section: Layout
// Module: Grid | Grid Inline
// Note: Gap utilities are defined in _spacing.scss

@use "sass:math";
@use "../abstracts/functions" as FN;
@use "../abstracts/config" as VAR;

/**
 * @description Establishes a grid container.
 */
@mixin grid {
  display: grid;
}

/**
 * @description Establishes a inline-grid container.
 */
@mixin grid-inline {
  display: inline-grid;
}

// Grid Template Mixins
@mixin cols($count) {
  grid-template-columns: repeat($count, minmax(0, 1fr));
}
@mixin rows($count) {
  grid-template-rows: repeat($count, minmax(0, 1fr));
}

/**
* @description Establishes a grid container with a specified number of columns.
* @param {number} $count - The number of columns.

/// EXAMPLE USAGE
.custom-grid {
  display: grid;
  @include cols-custom("1fr_auto_1fr");
}

*/

@mixin cols-custom($template) {
  // Convert underscores to spaces so "1fr_auto" becomes "1fr auto"
  $converted: FN.str-replace($template, "_", " ");

  grid-template-columns: $converted;
}

// Auto-fit/fill Mixins
@mixin auto-fit($min-width) {
  grid-template-columns: repeat(auto-fit, minmax($min-width, 1fr));
}
@mixin auto-fill($min-width) {
  grid-template-columns: repeat(auto-fill, minmax($min-width, 1fr));
}

// Grid Flow Mixins
@mixin flow-in-row {
  grid-auto-flow: row;
}
@mixin flow-in-col {
  grid-auto-flow: column;
}
@mixin flow-dense-items {
  grid-auto-flow: dense;
}

// Grid Alignment Mixins

// Alignment Classes
$alignments: (
  "start": start,
  "end": end,
  "center": center,
  "stretch": stretch,
);

/**
 * @description justify-items container.
 * @param {string} $value - The value for the justify-items property.
 */
@mixin justify($value) {
  justify-items: $value;
}

/**
 * @description Establishes a align-items container.
 * @param {string} $value - The value for the align-items property.
 */
@mixin align($value) {
  align-items: $value;
}

/**
 * @description Establishes a place-items container.
 * @param {string} $value - The value for the place-items property.
 */
@mixin place($value) {
  place-items: $value;
}

// Grid Item Placement Mixins
@mixin col-span($span) {
  grid-column: span $span / span $span;
}
@mixin row-span($span) {
  grid-row: span $span / span $span;
}
@mixin col-start($start) {
  grid-column-start: $start;
}
@mixin col-end($end) {
  grid-column-end: $end;
}
@mixin row-start($start) {
  grid-row-start: $start;
}
@mixin row-end($end) {
  grid-row-end: $end;
}

@mixin grid-position($col, $row) {
  grid-column: $col;
  grid-row: $row;
}
@mixin position-col($col) {
  grid-column: $col;
}
@mixin position-row($row) {
  grid-row: $row;
}

@if VAR.$generate-utility-classes {
  // Classes
  #{VAR.$parent-selector} .grid {
    @include grid;
  }

  #{VAR.$parent-selector} .grid.inline {
    @include grid-inline;
  }

  #{VAR.$parent-selector} .grid {
    // Auto-fit/fill Classes
    @each $size, $width in VAR.$grid-item-sizes {
      &.auto-fit-#{$size} {
        @include auto-fit($width);
      }

      &.auto-fill-#{$size} {
        @include auto-fill($width);
      }
    }

    // Flow Classes
    &.flow-row {
      @include flow-in-row;
    }

    &.flow-col {
      @include flow-in-col;
    }

    &.flow-dense {
      @include flow-dense-items;
    }

    @for $i from 1 through VAR.$column-count {
      &.cols-#{$i} {
        @include cols($i);
      }

      &.rows-#{$i} {
        @include rows($i);
      }
    }

    // Grid Template Classes
    @each $breakpoint, $width in VAR.$breakpoints {
      // Responsive grid columns
      @media (min-width: #{$width}) {
        @for $i from 1 through VAR.$column-count {
          &.cols-#{$i}\@#{$breakpoint} {
            @include cols($i);
          }

          &.rows-#{$i}\@#{$breakpoint} {
            @include rows($i);
          }
        }
      }
    }

    // Generate Column Span Classes with Responsive Variants
    @for $i from 1 through VAR.$column-count {
      & .col-span-#{$i} {
        @include col-span($i);
      }

      & .row-span-#{$i} {
        @include row-span($i);
      }

      @each $breakpoint, $width in VAR.$breakpoints {
        @media (min-width: #{$width}) {
          & .col-span-#{$i}\@#{$breakpoint} {
            @include col-span($i);
          }

          & .row-span-#{$i}\@#{$breakpoint} {
            @include row-span($i);
          }
        }
      }
    }

    @each $name, $value in $alignments {
      & .justify-#{$name} {
        @include justify($value);
      }

      & .align-#{$name} {
        @include align($value);
      }

      & .place-#{$name} {
        @include place($value);
      }

      @each $breakpoint, $width in VAR.$breakpoints {
        @media (min-width: #{$width}) {
          & .justify-#{$name}\@#{$breakpoint} {
            @include justify($value);
          }
          & .align-#{$name}\@#{$breakpoint} {
            @include align($value);
          }
          & .place-#{$name}\@#{$breakpoint} {
            @include place($value);
          }
        }
      }
    }
  }
}
