@use '../../../style/elements/ui-spacing.scss';
@import '../../../components/space/style/space-mixins.scss';

// includes all classes, tags, etc. needed for "global" typography rules (like css variables)
@mixin typographySelectors() {
  @include headingClasses() {
    $selectors: &;
    @at-root {
      @include headingTags() {
        // prettier-ignore
        $selectors: #{$selectors}, &;
        @at-root {
          @include otherSelectors() {
            // prettier-ignore
            $selectors: #{$selectors}, &;

            @at-root #{$selectors} {
              @content;
            }
          }
        }
      }
    }
  }
}

@mixin headingTags() {
  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    @content;
  }
}

@mixin headingClasses() {
  .dnb-lead,
  .dnb-h--xx-large,
  .dnb-h--x-large,
  .dnb-h--large,
  .dnb-h--medium,
  .dnb-h--basis,
  .dnb-h--small,
  .dnb-h--x-small,
  // make exception on headings which are inside of dnb-core-style
  .dnb-core-style .dnb-lead,
  .dnb-core-style .dnb-h--xx-large,
  .dnb-core-style .dnb-h--x-large,
  .dnb-core-style .dnb-h--large,
  .dnb-core-style .dnb-h--medium,
  .dnb-core-style .dnb-h--basis,
  .dnb-core-style .dnb-h--small,
  .dnb-core-style .dnb-h--x-small {
    @content;
  }
}

@mixin otherSelectors() {
  p,
  b,
  small,
  strong,
  .dnb-p,
  .dnb-small,
  .dnb-table,
  sub,
  sup {
    @content;
  }
}

@mixin headingStyle(
  $size,
  $line,
  $smallSize: null,
  $smallLine: null,
  $weight: null
) {
  font-size: $size;
  line-height: $line;
  font-weight: $weight;

  & > small {
    font-size: $smallSize;
    line-height: $smallLine;
  }

  @content;
}

@mixin headingDefaults() {
  padding: 0;

  @include spaceReset();

  font-family: var(--font-family-heading);

  // make icons inside heading responsive to the heading size
  .dnb-icon--default {
    font-size: 1em;
  }

  .dnb-icon--medium {
    font-size: 1.5em;
  }

  // to ensure we don't make the heading higher than it is supposed to be
  a,
  .dnb-anchor {
    padding-top: 0;
    padding-bottom: 0.03125rem;
  }

  @if mixin-exists('headingDefaultsCustomisation') {
    @include headingDefaultsCustomisation();
  }
}

@mixin headingSize_xx-large() {
  @include headingStyle(
    var(--typography-h-xx-large-font-size),
    var(--typography-h-xx-large-line-height),
    var(--typography-h-xx-large-small-font-size),
    var(--typography-h-xx-large-small-line-height),
    var(--typography-h-xx-large-weight)
  ) {
    & > small {
      display: block;
    }
    @content;
  }
}

@mixin headingSize_x-large() {
  @include headingStyle(
    var(--typography-h-x-large-font-size),
    var(--typography-h-x-large-line-height),
    var(--typography-h-x-large-small-font-size),
    var(--typography-h-x-large-small-line-height),
    var(--typography-h-x-large-weight)
  ) {
    & > small {
      display: block;
    }
    @content;
  }
}

@mixin headingSize_large() {
  @include headingStyle(
    var(--typography-h-large-font-size),
    var(--typography-h-large-line-height),
    var(--typography-h-large-small-font-size),
    var(--typography-h-large-small-line-height),
    var(--typography-h-large-weight)
  ) {
    @content;
  }
}

@mixin typography_lead() {
  @include headingStyle(
    var(--typography-lead-font-size),
    var(--typography-lead-line-height),
    var(--typography-lead-small-font-size),
    var(--typography-lead-small-line-height),
    var(--typography-lead-weight)
  ) {
    @content;
  }
}

@mixin headingSize_medium() {
  @include headingStyle(
    var(--typography-h-medium-font-size),
    var(--typography-h-medium-line-height),
    var(--typography-h-medium-small-font-size),
    var(--typography-h-medium-small-line-height),
    var(--typography-h-medium-weight)
  ) {
    @content;
  }
}

@mixin headingSize_basis() {
  @include headingStyle(
    var(--typography-h-basis-font-size),
    var(--typography-h-basis-line-height),
    var(--typography-h-basis-small-font-size),
    var(--typography-h-basis-small-line-height),
    var(--typography-h-basis-weight)
  ) {
    font-family: var(--typography-h-basis-font-family);
    @content;
  }
}

@mixin headingSize_small() {
  @include headingStyle(
    var(--typography-h-small-font-size),
    var(--typography-h-small-line-height),
    var(--typography-h-small-small-font-size),
    var(--typography-h-small-small-line-height),
    var(--typography-h-small-weight)
  ) {
    font-family: var(--typography-h-small-font-family);
    @content;
  }
}

@mixin headingSize_x-small() {
  @include headingStyle(
    var(--typography-h-x-small-font-size),
    var(--typography-h-x-small-line-height),
    null,
    null,
    var(--typography-h-x-small-weight)
  ) {
    font-family: var(--typography-h-x-small-font-family);
    @content;
  }
}

@mixin paragraphStyle() {
  font-size: var(--font-size-basis);

  // if we not reset margin, the browser is using: margin-block-end: 1rem;
  &:not([class*='space__top']) {
    margin-top: 0;
  }

  &:not([class*='space__bottom']) {
    margin-bottom: 0;
  }
  padding: 0;

  &--lead {
    @include typography_lead();
  }
  b,
  strong {
    font-weight: var(--font-weight-medium);
  }
  // is still needed for backwards compatibility when ".dnp-p" was used for all typography
  @include paragraphDeprecated();

  & > small {
    font-size: var(--font-size-small);
    line-height: var(--line-height-small);
  }

  & > cite {
    font-weight: var(--font-weight-medium);
    line-height: var(--line-height-basis);
    font-style: italic;
  }
}

// should use the .dnb-t classes instead
@mixin paragraphDeprecated() {
  // weights
  &--medium {
    font-weight: var(--font-weight-medium);
  }

  &--bold {
    font-weight: var(--font-weight-bold);
  }

  // sizes and line-heights
  &__size--xx-large {
    font-size: var(--font-size-xx-large);
    line-height: var(--line-height-xx-large);
  }

  &__size--x-large {
    font-size: var(--font-size-x-large);
    line-height: var(--line-height-x-large);
  }

  &__size--large {
    font-size: var(--font-size-large);
    line-height: var(--line-height-large);
  }

  &__size--basis {
    font-size: var(--font-size-basis);
    line-height: var(--line-height-basis);
  }

  &__size--medium {
    font-size: var(--font-size-medium);
    line-height: var(--line-height-medium);
  }

  &--small, // backwards compatibility
  &__size--small {
    font-size: var(--font-size-small);
    line-height: var(--line-height-small);
  }

  &--x-small, // backwards compatibility
  &__size--x-small {
    font-size: var(--font-size-x-small);
    line-height: var(--line-height-x-small);
  }
}

@mixin headingSpacing_xx-large() {
  &:not([class*='space__top']) {
    margin-top: 3rem;
  }

  &:not([class*='space__bottom']) {
    margin-bottom: 2.5rem;
  }
}

@mixin headingSpacing_x-large() {
  &:not([class*='space__top']) {
    margin-top: 3rem;
  }

  &:not([class*='space__bottom']) {
    margin-bottom: 1rem;
  }
}

@mixin headingSpacing_large() {
  &:not([class*='space__top']) {
    margin-top: 3rem;
  }

  &:not([class*='space__bottom']) {
    margin-bottom: 1rem;
  }
}

@mixin headingSpacing() {
  &:not([class*='space__top']) {
    margin-top: 2rem;
  }

  &:not([class*='space__bottom']) {
    margin-bottom: 1rem;
  }
}

@mixin typographyTags() {
  p {
    @include paragraphStyle();
  }

  b,
  strong {
    font-weight: var(--font-weight-bold);
  }

  small {
    font-size: var(--font-size-small);
  }

  h1,
  h2,
  h3,
  h4,
  h5,
  h6 {
    @include headingDefaults();
  }

  h1 {
    @include headingSize_xx-large();
  }

  h2 {
    @include headingSize_large();
  }

  h3 {
    @include headingSize_medium();
  }

  h4 {
    @include headingSize_basis();
  }

  h5 {
    @include headingSize_small();
  }

  h6 {
    @include headingSize_x-small();
  }

  h2 > small,
  h3 > small,
  h4 > small,
  h5 > small,
  h6 > small {
    line-height: var(
      --line-height-xx-small--em
    ); // for vertical alignment, we have to have no line-height
  }

  .dnb-spacing {
    h1,
    .dnb-core-style & h1 {
      @include headingSpacing_xx-large();
    }

    h2,
    .dnb-core-style & h2 {
      @include headingSpacing_large();
    }

    h3,
    h4,
    h5,
    h6,
    .dnb-core-style & h3,
    .dnb-core-style & h4,
    .dnb-core-style & h5,
    .dnb-core-style & h6 {
      @include headingSpacing();
    }

    p,
    .dnb-core-style & p {
      @include ui-spacing.defaultSpacing();
    }
  }
}
