@use '../core/styles' as sbb;

$theme: 'standard' !default;

@mixin base {
  --sbb-table-border-color: light-dark(var(--sbb-color-cloud), var(--sbb-color-anthracite));
  --sbb-table-background-color: var(--sbb-background-color-1);
  --sbb-table-row-striped-color: var(--sbb-background-color-3);
  --sbb-table-color: var(--sbb-color-1);
  --sbb-table-caption-color: light-dark(var(--sbb-color-granite), var(--sbb-color-cement));
  --sbb-table-caption-margin-block-start: var(--sbb-spacing-fixed-4x);
  --sbb-table-sticky-shadow-width: 3rem;
  --sbb-table-sticky-shadow-transition-easing: var(--sbb-animation-easing);
  --sbb-table-header-cell-font-size: var(--sbb-text-font-size-xs);
  --sbb-table-data-cell-font-size: #{sbb.theme-pattern-select(
      (
        'standard': var(--sbb-text-font-size-s),
        'lean': var(--sbb-text-font-size-xs),
      ),
      $theme
    )};
  --sbb-table-header-padding-block: #{sbb.theme-pattern-select(
      (
        'standard': var(--sbb-spacing-fixed-3x),
        'lean': var(--sbb-spacing-fixed-1x),
      ),
      $theme
    )};
  --sbb-table-header-padding-inline: #{sbb.theme-pattern-select(
      (
        'standard': var(--sbb-spacing-fixed-4x),
        'lean': var(--sbb-spacing-fixed-2x),
      ),
      $theme
    )};
  --sbb-table-cell-padding-block: #{sbb.theme-pattern-select(
      (
        'standard': var(--sbb-spacing-responsive-xxxs),
        'lean': var(--sbb-spacing-fixed-1x),
      ),
      $theme
    )};
  --sbb-table-cell-padding-inline: #{sbb.theme-pattern-select(
      (
        'standard': var(--sbb-spacing-fixed-4x),
        'lean': var(--sbb-spacing-fixed-2x),
      ),
      $theme
    )};
}

@mixin rules {
  // Notes:
  // We cannot use `border-collapse` because in sticky variants it gets visually broken.
  // Therefore, we have to build the grid avoiding double borders.
  :is(.sbb-table, .sbb-table-m, .sbb-table-s, .sbb-table-xs) {
    --sbb-table-border: var(--sbb-border-width-1x) solid var(--sbb-table-border-color);
    --sbb-table-sticky-shadow-transition-duration: var(
      --sbb-disable-animation-duration,
      var(--sbb-animation-duration-6x)
    );

    border-spacing: 0;
    caption-side: bottom;
    color: var(--sbb-table-color);
    table-layout: auto;
    text-align: left;

    th {
      font-size: var(--sbb-table-header-cell-font-size);
      letter-spacing: var(--sbb-typo-letter-spacing-text);
      font-weight: bold;
      background-color: var(--sbb-table-background-color);
      border-block-end: var(--sbb-table-border);
      border-inline-end: var(--sbb-table-border);
      padding-block: var(--sbb-table-header-padding-block);
      padding-inline: var(--sbb-table-header-padding-inline);
    }

    td {
      font-size: var(--sbb-table-data-cell-font-size);
      letter-spacing: var(--sbb-typo-letter-spacing-text);
      background-color: var(--sbb-table-background-color);
      border-block-end: var(--sbb-table-border);
      border-inline-end: var(--sbb-table-border);
      padding-block: var(--sbb-table-cell-padding-block);
      padding-inline: var(--sbb-table-cell-padding-inline);
    }

    :is(th, td) {
      &.sbb-table-group-with-next {
        border-inline-end: none;
      }

      &:first-child {
        border-inline-start: var(--sbb-table-border);
      }
    }

    // In Angular the CDK table always adds a thead even if there are no headers.
    // Due to this fact we have to also insert `tr` in the `:has()` selector.
    &:has(thead tr) thead,
    &:not(:has(thead tr)) tbody {
      tr:first-of-type > :is(th, td) {
        border-block-start: var(--sbb-table-border);
      }
    }

    // Avoid borders between header rows (design specification).
    thead > tr:has(+ tr) > :is(th, td) {
      border-block-end: none;
    }
  }

  :is(.sbb-table, .sbb-table-m, .sbb-table-s, .sbb-table-xs) caption,
  .sbb-table-caption {
    // Workaround for storybook. It crashes if 'light-dark' is used as a 'var' fallback
    --sbb-table-caption-color-fallback: light-dark(
      var(--sbb-color-granite),
      var(--sbb-color-cement)
    );

    font-size: var(--sbb-text-font-size-xs);
    letter-spacing: var(--sbb-typo-letter-spacing-text);

    // Defaults are needed for cases where the caption is used outside a table
    color: var(--sbb-table-caption-color, var(--sbb-table-caption-color-fallback));
    margin-block-start: var(--sbb-table-caption-margin-block-start, var(--sbb-spacing-fixed-4x));
    text-align: left;
  }

  .sbb-table-xs {
    --sbb-table-data-cell-font-size: var(--sbb-text-font-size-xs);
    --sbb-table-header-padding-block: 0;
    --sbb-table-header-padding-inline: var(--sbb-spacing-fixed-1x);
    --sbb-table-cell-padding-block: 0;
    --sbb-table-cell-padding-inline: var(--sbb-spacing-fixed-1x);
  }

  .sbb-table-s {
    --sbb-table-data-cell-font-size: var(--sbb-text-font-size-xs);
    --sbb-table-header-padding-block: var(--sbb-spacing-fixed-1x);
    --sbb-table-header-padding-inline: var(--sbb-spacing-fixed-2x);
    --sbb-table-cell-padding-block: var(--sbb-spacing-fixed-1x);
    --sbb-table-cell-padding-inline: var(--sbb-spacing-fixed-2x);
  }

  .sbb-table-m {
    --sbb-table-data-cell-font-size: var(--sbb-text-font-size-s);
    --sbb-table-header-padding-block: var(--sbb-spacing-fixed-3x);
    --sbb-table-header-padding-inline: var(--sbb-spacing-fixed-4x);
    --sbb-table-cell-padding-block: var(--sbb-spacing-responsive-xxxs);
    --sbb-table-cell-padding-inline: var(--sbb-spacing-fixed-4x);
  }

  sbb-table-wrapper[negative] .sbb-table,
  .sbb-table--negative {
    --sbb-table-border-color: var(--sbb-color-anthracite);
    --sbb-table-background-color: var(--sbb-background-color-1-negative);
    --sbb-table-color: var(--sbb-color-1-negative);
    --sbb-table-row-striped-color: var(--sbb-background-color-3-negative);
    --sbb-table-caption-color: var(--sbb-color-cement);
  }

  .sbb-table--striped {
    tbody tr:nth-child(odd) :is(th, td) {
      background-color: var(--sbb-table-row-striped-color);
    }
  }

  .sbb-table--unstriped {
    tbody tr:nth-child(odd) :is(th, td) {
      background-color: var(--sbb-table-background-color);
    }
  }

  .sbb-table--theme-iron {
    --sbb-table-cell-color: var(--sbb-color-4);

    sbb-table-wrapper[negative] &,
    &.sbb-table--negative {
      --sbb-table-cell-color: var(--sbb-color-cloud);
    }

    tbody > tr > td {
      color: var(--sbb-table-cell-color);
    }
  }

  .sbb-table-header-subtitle {
    font-weight: normal;
  }

  .sbb-table-row--striped {
    background-color: var(--sbb-table-row-striped-color);
  }

  .sbb-table-filter {
    padding-block-start: 0 !important;
  }

  .sbb-table-caption {
    // Workaround for storybook. It crashes if 'light-dark' is used as a 'var' fallback
    --sbb-table-caption-color-fallback: light-dark(
      var(--sbb-color-granite),
      var(--sbb-color-cement)
    );

    font-size: var(--sbb-text-font-size-xs);
    letter-spacing: var(--sbb-typo-letter-spacing-text);

    // Defaults are needed for cases where the caption is used outside a table
    color: var(--sbb-table-caption-color, var(--sbb-table-caption-color-fallback));
    margin-block-start: var(--sbb-table-caption-margin-block-start, var(--sbb-spacing-fixed-4x));
    text-align: left;
  }

  .sbb-table-sticky {
    // Note that the table can either set this class or an inline style to make something sticky.
    // We set the style as `!important` so that we get an identical specificity in both cases
    // and to avoid cases where user styles have a higher specificity.
    position: sticky !important;
  }

  // The `sbb-table-sticky-*` css classes are used by the Angular wrapper and CDK.
  // Do not rename them, please.
  :is(.sbb-table-sticky-border-elem-left, .sbb-table-sticky-border-elem-right)::after {
    content: '';
    transition: {
      timing-function: var(--sbb-table-sticky-shadow-transition-easing);
      duration: var(--sbb-table-sticky-shadow-transition-duration);
      property: visibility, opacity;
    }

    visibility: hidden;
    opacity: 0;
    position: absolute;
    width: var(--sbb-table-sticky-shadow-width);
    inset: 0;
  }

  .sbb-table-sticky-border-elem-left {
    :is(.sbb-table-wrapper-offset-left, .sbb-table-wrapper-offset-both) & {
      border-inline-end: var(--sbb-table-border);

      &::after {
        visibility: visible;
        opacity: 1;
        background-image: linear-gradient(-270deg, rgb(0 0 0 / 10%) 0%, transparent 100%);
        inset-inline-start: unset;
        inset-inline-end: calc(var(--sbb-table-sticky-shadow-width) * -1 - 1px);
      }
    }
  }

  .sbb-table-sticky-border-elem-right {
    :is(.sbb-table-wrapper-offset-right, .sbb-table-wrapper-offset-both) & {
      border-inline-start: var(--sbb-table-border);

      &::after {
        visibility: visible;
        opacity: 1;
        background-image: linear-gradient(270deg, rgb(0 0 0 / 10%) 0%, transparent 100%);
        inset-inline-start: calc(var(--sbb-table-sticky-shadow-width) * -1 - 1px);
        inset-inline-end: unset;
      }
    }
  }

  .sbb-table-align-start {
    text-align: start;
  }

  .sbb-table-align-center {
    text-align: center;
  }

  .sbb-table-align-end {
    text-align: end;
  }

  .sbb-table-align-justify {
    text-align: justify;
  }

  // Backwards compatibility for sbb-angular
  .sbb-table-align-left {
    text-align: left;
  }

  // Backwards compatibility for sbb-angular
  .sbb-table-align-right {
    text-align: right;
  }
}
