/*
 * Space component
 *
 * TODO: Set spacing in the theme file, as theme comes later in the stack
 *
 */

@use 'sass:string';
@use '../../../style/core/utilities.scss' as utilities;
@use './responsive-spacing.scss';

@mixin marginDirection($direction) {
  // Get the first letter for the custom property name (top -> t, left -> l, etc.)
  $short: string.slice($direction, 1, 1);

  &--xx-small {
    margin-#{$direction}: var(--spacing-xx-small);
  }
  // 0.5rem
  &--x-small {
    margin-#{$direction}: var(--spacing-x-small);
  }
  // 1rem
  &--small {
    margin-#{$direction}: var(--spacing-small);
  }
  // 1.5rem
  &--medium {
    margin-#{$direction}: var(--spacing-medium);
  }
  // 2rem
  &--large {
    margin-#{$direction}: var(--spacing-large);
  }
  // 2.5rem
  &--large#{&}--x-small {
    margin-#{$direction}: calc(
      var(--spacing-large) + var(--spacing-x-small)
    );
  }
  // 3rem
  &--x-large {
    margin-#{$direction}: var(--spacing-x-large);
  }
  // 3.5rem
  &--xx-large {
    margin-#{$direction}: var(--spacing-xx-large);
  }
  // 4rem
  &--xx-large#{&}--x-small {
    margin-#{$direction}: calc(
      var(--spacing-large) + var(--spacing-large)
    );
  }
  // 4.5rem
  &--xx-large#{&}--small {
    margin-#{$direction}: calc(
      var(--spacing-x-large) + var(--spacing-medium)
    );
  }
  // 5rem
  &--xx-large#{&}--medium {
    margin-#{$direction}: calc(
      var(--spacing-x-large) + var(--spacing-large)
    );
  }
  // 5.5rem
  &--xx-large#{&}--large {
    margin-#{$direction}: calc(
      var(--spacing-x-large) + var(--spacing-large) +
        var(--spacing-x-small)
    );
  }
  // 6rem
  &--xx-large#{&}--large#{&}--x-small {
    margin-#{$direction}: calc(
      var(--spacing-x-large) + var(--spacing-large) + var(--spacing-small)
    );
  }
  // 6.5rem
  &--xx-large#{&}--x-large {
    margin-#{$direction}: calc(
      var(--spacing-xx-large) + var(--spacing-x-large)
    );
  }
  // 7rem
  &--xx-large-x2 {
    margin-#{$direction}: calc(
      var(--spacing-x-large) + var(--spacing-large) + var(--spacing-large)
    );
  }
  // 7.5rem
  &--xx-large-x2#{&}--x-small {
    margin-#{$direction}: calc(
      var(--spacing-xx-large) + var(--spacing-large) + var(--spacing-large)
    );
  }
  // 8rem
  &--xx-large-x2#{&}--small {
    margin-#{$direction}: calc(
      var(--spacing-x-large) + var(--spacing-x-large) +
        var(--spacing-large)
    );
  }
  // 8.5rem
  &--xx-large-x2#{&}--medium {
    margin-#{$direction}: calc(
      var(--spacing-xx-large) + var(--spacing-x-large) +
        var(--spacing-large)
    );
  }
  // 9rem
  &--xx-large-x2#{&}--large {
    margin-#{$direction}: calc(
      var(--spacing-x-large) + var(--spacing-x-large) +
        var(--spacing-x-large)
    );
  }
  // 9.5rem
  &--xx-large-x2#{&}--large#{&}--x-small {
    margin-#{$direction}: calc(
      var(--spacing-xx-large) + var(--spacing-x-large) +
        var(--spacing-x-large)
    );
  }
  // 10rem
  &--xx-large-x2#{&}--x-large {
    margin-#{$direction}: calc(
      var(--spacing-xx-large) + var(--spacing-xx-large) +
        var(--spacing-x-large)
    );
  }

  // Apply responsive custom property overrides for all modifiers above
  &--xx-small,
  &--x-small,
  &--small,
  &--medium,
  &--large,
  &--x-large,
  &--xx-large,
  &--xx-large-x2 {
    &[style*='--margin-#{$short}-'] {
      @include utilities.allBelow(medium) {
        margin-#{$direction}: var(--margin-#{$short}-s);
      }
      @include utilities.allBetween(small, medium) {
        margin-#{$direction}: var(--margin-#{$short}-m);
      }
      @include utilities.allAbove(medium) {
        margin-#{$direction}: var(--margin-#{$short}-l);
      }
    }
  }

  // 0rem
  &--zero {
    margin-#{$direction}: 0;
  }
}

/** NB: Because CSS specificity ".dnb-core-style .dnb-space"
    has to come before the next ".dnb-space"
  */
.dnb-core-style .dnb-space {
  &__top {
    @include marginDirection(top);
  }
  &__right {
    @include marginDirection(right);
  }
  &__bottom {
    @include marginDirection(bottom);
  }
  &__left {
    @include marginDirection(left);
  }
}

/* stylelint-disable-next-line no-descending-specificity */
.dnb-space {
  &--no-collapse {
    display: flow-root;
  }
  &--stretch {
    width: 100%;
  }
  &--inline {
    display: inline-block;
  }
  /* stylelint-disable-next-line no-descending-specificity */
  &__top {
    @include marginDirection(top);
  }
  /* stylelint-disable-next-line no-descending-specificity */
  &__right {
    @include marginDirection(right);
  }
  /* stylelint-disable-next-line no-descending-specificity */
  &__bottom {
    @include marginDirection(bottom);
  }
  /* stylelint-disable-next-line no-descending-specificity */
  &__left {
    @include marginDirection(left);
  }
  &__reset {
    @include utilities.spaceReset();
  }

  // innerSpace
  &[style*='--padding-t-'] {
    padding-top: var(--padding-top, 0);
  }
  &[style*='--padding-r-'] {
    padding-right: var(--padding-right, 0);
  }
  &[style*='--padding-b-'] {
    padding-bottom: var(--padding-bottom, 0);
  }
  &[style*='--padding-l-'] {
    padding-left: var(--padding-left, 0);
  }

  @include utilities.allBelow(medium) {
    --padding-right: var(--padding-r-s);
    --padding-left: var(--padding-l-s);
    --padding-top: var(--padding-t-s);
    --padding-bottom: var(--padding-b-s);
  }
  @include utilities.allBetween(small, medium) {
    --padding-right: var(--padding-r-m);
    --padding-left: var(--padding-l-m);
    --padding-top: var(--padding-t-m);
    --padding-bottom: var(--padding-b-m);
  }
  @include utilities.allAbove(medium) {
    --padding-right: var(--padding-r-l);
    --padding-left: var(--padding-l-l);
    --padding-top: var(--padding-t-l);
    --padding-bottom: var(--padding-b-l);
  }

  // Responsive modifiers
  // A single --responsive-spacing-tier variable controls the active tier.
  // Each --responsive-spacing-* is computed from its basis value + tier × 0.5rem.
  // Default mapping: small viewport = -1, medium = 0, large = +1.
  // Shifting the breakpoint shifts the tier integers accordingly.

  &-responsive {
    --responsive-spacing-tier: 0;

    // Compute responsive spacing values
    --responsive-spacing-xx-small: max(
      0.25rem,
      calc(0.5rem + var(--responsive-spacing-tier) * 0.5rem)
    );
    --responsive-spacing-x-small: max(
      0.25rem,
      calc(1rem + var(--responsive-spacing-tier) * 0.5rem)
    );
    --responsive-spacing-small: calc(
      1.5rem + var(--responsive-spacing-tier) * 0.5rem
    );
    --responsive-spacing-medium: calc(
      2rem + var(--responsive-spacing-tier) * 0.5rem
    );
    --responsive-spacing-large: calc(
      2.5rem + var(--responsive-spacing-tier) * 0.5rem
    );
    --responsive-spacing-x-large: calc(
      3rem + var(--responsive-spacing-tier) * 0.5rem
    );
    --responsive-spacing-xx-large: calc(
      3.5rem + var(--responsive-spacing-tier) * 0.5rem
    );

    // Map spacing tokens to responsive spacing values
    --spacing-xx-small: var(--responsive-spacing-xx-small);
    --spacing-x-small: var(--responsive-spacing-xx-small);
    --spacing-small: var(--responsive-spacing-x-small);
    --spacing-medium: var(--responsive-spacing-small);
    --spacing-large: var(--responsive-spacing-medium);
    --spacing-x-large: var(--responsive-spacing-large);
    --spacing-xx-large: var(--responsive-spacing-x-large);

    // Default viewport mapping (medium = basis)
    @include utilities.allBelow(small) {
      --responsive-spacing-tier: -1;
    }
    @include utilities.allAbove(medium) {
      --responsive-spacing-tier: 1;
    }
  }

  // Breakpoint overrides – shift which viewport gets the "basis" tier
  &-responsive--breakpoint-small {
    @include utilities.allBelow(small) {
      --responsive-spacing-tier: 0;
    }
    @include utilities.allBetween(small, medium) {
      --responsive-spacing-tier: 1;
    }
    @include utilities.allAbove(medium) {
      --responsive-spacing-tier: 2;
    }
  }

  &-responsive--breakpoint-large {
    @include utilities.allBelow(small) {
      --responsive-spacing-tier: -2;
    }
    @include utilities.allBetween(small, medium) {
      --responsive-spacing-tier: -1;
    }
    @include utilities.allAbove(medium) {
      --responsive-spacing-tier: 0;
    }
  }

  // Explicit density overrides (defined after defaults → wins by cascade)
  &-responsive--force-compact {
    --responsive-spacing-tier: -1;
  }

  &-responsive--force-spacious {
    --responsive-spacing-tier: 1;
  }

  // Reset responsive overrides when Space.ResponsiveContext off is set,
  // so inherited --spacing-* custom properties from an ancestor
  // .dnb-space-responsive do not leak into opted-out subtrees.
  // Values mirror the theme defaults in themes/ui/properties.scss.
  &-responsive--off {
    --spacing-xx-small: 0.25rem; // 4px
    --spacing-x-small: 0.5rem; // 8px
    --spacing-small: 1rem; // 16px
    --spacing-medium: 1.5rem; // 24px
    --spacing-large: 2rem; // 32px
    --spacing-x-large: 3rem; // 48px
    --spacing-xx-large: 3.5rem; // 56px
  }
}
span.dnb-space--no-collapse > span {
  display: block;
}
