@use 'sass:map';
@use '../utils/constants.scss';
@use '../utils/mixins.scss' as mixins;
@use '../utils/tokens.scss' as tokens;

@import '@viasat/beam-tokens/components/List';

$listBaseClass: '#{constants.$prefix}list';
$listItemBaseClass: '#{constants.$prefix}list__item';

$ol-list-styles: decimal, lower-alpha, lower-roman;
$ul-list-styles: disc, circle;

$sizes: (
  sm: (
    text: tokens.$bm-sem-typo-body-sm,
    icon: tokens.$bm-sem-size-icon-md,
  ),
  md: (
    text: tokens.$bm-sem-typo-body-md,
    icon: tokens.$bm-sem-size-icon-lg,
  ),
  lg: (
    text: tokens.$bm-sem-typo-body-lg,
    icon: tokens.$bm-sem-size-icon-xl,
  ),
  xl: (
    text: tokens.$bm-sem-typo-body-xl,
    icon: tokens.$bm-sem-size-icon-2xl,
  ),
);

$densities: (
  density-md: tokens.$bm-comp-list-space-bottom-md,
  density-lg: tokens.$bm-comp-list-space-bottom-lg,
);

// Recursive mixins to handle nested list ordering for child lists of the same type
@mixin nested-ol-list-styles($depth: 0) {
  list-style-type: nth($ol-list-styles, ($depth % length($ol-list-styles)) + 1);

  li {
    padding-inline-start: tokens.$bm-comp-list-space-marker;
  }

  @if $depth < 10 {
    // support both sublists nested in li and regular sub lists of lists
    & > li .#{$listBaseClass}--ordered {
      @include nested-ol-list-styles($depth + 1);
    }
  }
}

@mixin nested-ul-list-styles($depth: 0) {
  list-style-type: nth($ul-list-styles, ($depth % length($ul-list-styles)) + 1);

  li {
    padding-inline-start: tokens.$bm-comp-list-space-marker;
  }

  @if $depth < 10 {
    // support both sublists nested in li and regular sub lists of lists
    & > li .#{$listBaseClass}--unordered {
      @include nested-ul-list-styles($depth + 1);
    }
  }
}

.#{$listBaseClass} {
  list-style: none;
  color: tokens.$bm-sem-color-text-primary;
  padding-inline-start: tokens.$bm-comp-list-space-indent;
  margin-block-start: 0;
  margin-block-end: 0;

  &--ordered {
    @include nested-ol-list-styles();
  }

  &--unordered {
    @include nested-ul-list-styles();
  }

  &--unstyled {
    list-style-type: none;
    padding-inline-start: 0;
  }

  &--withIcons {
    list-style-type: none;
    padding-inline-start: 0;
  }

  &--withIcons &__content {
    display: flex;
  }

  &--indent {
    padding-inline-start: tokens.$bm-comp-list-space-indent;
  }

  @each $size, $sizeValue in $sizes {
    &--#{$size} {
      &.#{$listBaseClass}--wcWithIcons {
        // negative margin to counteract withIcons flexbox layout (wc)
        margin-inline-start: calc(
          -1 * (map.get($sizeValue, 'icon') + tokens.$bm-comp-list-space-icon)
        );
      }

      li,
      &,
      ::slotted(bm-list-item) {
        font: map.get($sizeValue, 'text');
      }
    }

    &--#{$size} &__icon {
      color: tokens.$bm-sem-color-icon-primary;

      svg {
        vertical-align: bottom;
        margin-inline-end: tokens.$bm-comp-list-space-icon;
        width: map.get($sizeValue, 'icon');
        height: map.get($sizeValue, 'icon');
      }
    }

    &--#{$size} &--withIcons {
      // negative margin to counteract withIcons flexbox layout (react)
      margin-inline-start: calc(
        -1 * (map.get($sizeValue, 'icon') + tokens.$bm-comp-list-space-icon)
      );
    }
  }

  @each $density, $densityValue in $densities {
    &--#{$density} {
      li:not(:has(> ol, > ul)) {
        padding-bottom: $densityValue;
      }

      ol,
      ul,
      &--nested {
        padding-top: $densityValue;
      }
    }
  }
}

.#{$listItemBaseClass} {
  display: list-item;

  &--decimal {
    list-style-type: decimal;
    padding-inline-start: tokens.$bm-comp-list-space-marker;
  }

  &--lower-alpha {
    list-style: lower-alpha;
    padding-inline-start: tokens.$bm-comp-list-space-marker;
  }

  &--lower-roman {
    list-style-type: lower-roman;
    padding-inline-start: tokens.$bm-comp-list-space-marker;
  }

  &--disc {
    list-style-type: disc;
    padding-inline-start: tokens.$bm-comp-list-space-marker;
  }

  &--circle {
    list-style-type: circle;
    padding-inline-start: tokens.$bm-comp-list-space-marker;
  }

  &__content {
    display: flex;
  }

  @each $density, $densityValue in $densities {
    &--#{$density} {
      padding-bottom: $densityValue;
    }
  }

  @each $size, $sizeValue in $sizes {
    &--#{$size} {
      &__icon svg,
      ::slotted([slot='icon']) {
        flex-shrink: 0;
        color: tokens.$bm-sem-color-icon-primary;
        display: inline-block;
        vertical-align: bottom;
        margin-inline-end: tokens.$bm-comp-list-space-icon;
        width: map.get($sizeValue, 'icon');
        height: map.get($sizeValue, 'icon');
      }
    }
  }
}
