@use "breakpoints.scss" as *;
@use "sass:map";

// prettier-ignore
$gridVariants: (
// NAME   MAX-VARIANT COLUMNS GUTTER MARGIN
   "2xs"  none        4       1rem   1rem,
   "xs"   none        8       1rem   1rem,
   "sm"   none        8       1.5rem 2rem,
   "md"   none        12      1.5rem 4rem,
   "lg"   "md"        12      2rem   4rem,
   "xl"   "lg"        12      2rem   4rem,
);

// prettier-ignore
$sideBarGridVariants: (
// NAME MAX-VARIANT COLUMNS GUTTER MARGIN
   "xs" none        1       0.5rem 0.5rem,
   "sm" none        2       1rem   1rem,
   "md" none        4       1rem   1rem,
   "lg" "md"        8       1.5rem 2rem,
   "xl" "lg"        12      1.5rem 4rem,
);

$sidebar-breakpoints: (
  xs: 0px,
  sm: 200px,
  md: 328px,
  lg: 656px,
  xl: 992px,
);

@layer onyx.utility {
  :root {
    --onyx-grid-margin-vertical: var(--onyx-density-3xl);
  }

  /**
  * Grid container base class
  */
  .onyx-grid {
    display: grid;
    grid-template-columns: repeat(var(--onyx-grid-columns), minmax(0, 1fr));
    gap: var(--onyx-grid-gutter);
  }

  /**
  * Grid container classes for "xl" and "lg" breakpoint variants with 16 or 20 columns
  *
  * Needs onyx-grid-* to override the --onyx-grid-columns
  */
  @include container(min, lg) {
    .onyx-grid,
    .onyx-grid-layout,
    .onyx-grid-container {
      &.onyx-grid-xl-20,
      &.onyx-grid-lg-16 {
        --onyx-grid-columns: 16;
      }
    }
  }

  @include container(min, xl) {
    .onyx-grid,
    .onyx-grid-layout,
    .onyx-grid-container {
      &.onyx-grid-xl-20 {
        --onyx-grid-columns: 20;
      }
    }

    .onyx-grid,
    .onyx-grid-layout,
    .onyx-grid-container {
      &.onyx-grid-xl-16 {
        --onyx-grid-columns: 16;
      }
    }
  }

  /**
  * Both `onyx-grid-container` and `onyx-grid-layout` define the grid variables.
  * `onyx-grid-layout` additionally applies padding.
  *
  * Page class to apply padding, max-width and optional centered.
  * Is usually placed at the root element of every page.
  */
  .onyx-grid-layout,
  .onyx-grid-container {
    max-width: var(--onyx-grid-max-width, 100%);
    margin-inline: var(--onyx-grid-margin-inline);
    box-sizing: border-box; // max-width should include the padding
    transition: max-width 1s;
  }
  .onyx-grid-layout {
    // Note: The --onyx-grid-margin is implemented as padding here so that is also included in e.g. custom background colors
    // but the term "margin" comes from UX/Figma so we decided to keep naming it margin to be aligned
    padding: var(--onyx-grid-margin-vertical) var(--onyx-grid-margin);
  }

  /**
  * Utility class to allow optional centering for pages with max width.
  * Requires a "onyx-grid-max-*" class to be set.
  *
  *  Must be placed inside the desired container. E.g. on onyx-grid-layout/onyx-grid-container
  */
  .onyx-grid-center {
    --onyx-grid-margin-inline: auto;
  }

  /**
  * Grid element class for defining how many columns the element spans
  */
  @for $i from 1 through 20 {
    .onyx-grid-span-#{$i} {
      grid-column-end: span min($i, var(--onyx-grid-columns));
    }
  }

  /**
  * Grid element class for spanning the full row width.
  */
  .onyx-grid-span-full {
    grid-column: 1 / span var(--onyx-grid-columns);
  }

  @mixin generate-grid-properties($columns, $gutter, $margin) {
    --onyx-grid-columns: #{$columns};
    --onyx-grid-gutter: #{$gutter};
    --onyx-grid-margin: #{$margin};
  }

  /**
  * Grid element class for defining breakpoint specific column count
  */
  @mixin generate-spans($first, $last, $name) {
    @for $span from $first through $last {
      .onyx-grid-#{$name}-span-#{$span} {
        grid-column-end: span min($span, var(--onyx-grid-columns));
      }
    }
  }

  /**
  * Grid container class for defining breakpoint specific max width
  *
  *  Must be placed inside the desired container. E.g. on onyx-grid-layout/onyx-grid-container
  */
  @mixin generate-grid-max($name, $maxVariant, $breaks: $breakpoints) {
    .onyx-grid-max-#{$maxVariant} {
      --onyx-grid-max-width: #{map.get($breaks, $name) - 1};
    }
  }

  @each $name, $maxVariant, $columns, $gutter, $margin in $gridVariants {
    @if $name == "2xs" {
      :where(:root),
      .onyx-grid,
      .onyx-grid-layout,
      .onyx-grid-container {
        @include generate-grid-properties($columns, $gutter, $margin);
      }
      @include generate-spans(1, $columns, $name);
    } @else {
      @include container(min, $name) {
        .onyx-grid,
        .onyx-grid-layout,
        .onyx-grid-container {
          @include generate-grid-properties($columns, $gutter, $margin);
        }
        @include generate-spans(1, $columns, $name);
        @if $name == "xl" {
          @include generate-spans(17, 20, $name);
        }
      }
      @if $maxVariant != none {
        @include generate-grid-max($name, $maxVariant);
      }
    }
  }

  /**
  * SIDEBAR GRID
  */
  .onyx-sidebar {
    --onyx-grid-margin-vertical: var(--onyx-density-md);
    container-type: inline-size;

    @each $name, $maxVariant, $columns, $gutter, $margin in $sideBarGridVariants {
      @include container(min, $name, 0, $sidebar-breakpoints) {
        .onyx-grid,
        .onyx-grid-layout,
        .onyx-grid-container {
          @include generate-grid-properties($columns, $gutter, $margin);
        }

        @include generate-spans(1, $columns, $name);
      }
      @if $maxVariant != none {
        @include generate-grid-max($name, $maxVariant, $sidebar-breakpoints);
      }
    }
  }

  /**
* Sets grid variables on root based on viewport size,
* providing the properties for elements outside of container-queries e.g. popovers, dialogs
*/
  @each $name, $maxVariant, $columns, $gutter, $margin in $gridVariants {
    @include screen(min, $name) {
      :where(:root) {
        @include generate-grid-properties($columns, $gutter, $margin);
      }
    }
  }
}
