@use 'sass:map';
@use '../../style/theming';

// Sections
@mixin core() {
  /// @dbx-utility spacer
  /// @intent flex spacer — fills remaining space in a flex container to push siblings apart
  /// @role flex
  /// @see-also dbx-flex-fill, dbx-button-spacer
  .dbx-spacer,
  .spacer {
    flex: 1 1 auto;
  }

  .decoration,
  .pointer-disabled {
    pointer-events: none;
  }

  /// @dbx-utility no-margin
  /// @intent strip margin (forced) — `margin: 0 !important`
  /// @role spacing
  .no-margin {
    margin: 0 !important;
  }

  /// @dbx-utility no-padding
  /// @intent strip padding (forced) — `padding: 0 !important`
  /// @role spacing
  /// @see-also dbx-list-item-p0
  .no-padding {
    padding: 0 !important;
  }

  /// @dbx-utility hide
  /// @intent hide element (forced) — `display: none !important`
  /// @role state
  .dbx-hide {
    display: none !important;
  }

  @each $i, $padding in theming.$padding-map {
    .dbx-m#{$i} {
      margin: $padding !important;
    }

    .dbx-mb#{$i} {
      margin-bottom: $padding !important;
    }

    .dbx-mv#{$i} {
      margin: $padding 0 !important;
    }

    .dbx-p#{$i} {
      padding: $padding !important;
    }

    .dbx-pv#{$i} {
      padding: $padding 0 !important;
    }

    .dbx-pt#{$i} {
      padding-top: $padding !important;
    }

    .dbx-pb#{$i} {
      padding-bottom: $padding !important;
    }

    .dbx-pl#{$i} {
      padding-left: $padding !important;
    }

    .dbx-pr#{$i} {
      padding-right: $padding !important;
    }
  }

  /// @dbx-utility h100
  /// @intent fill height — `height: 100%`
  /// @role layout
  /// @see-also dbx-w100
  .dbx-h100 {
    height: 100%;
  }

  /// @dbx-utility block
  /// @intent set display: block
  /// @role layout
  /// @see-also dbx-iblock, dbx-flex
  .d-block,
  .dbx-block {
    display: block;
  }

  /// @dbx-utility iblock
  /// @intent set display: inline-block
  /// @role layout
  /// @see-also dbx-block, dbx-iflex
  .d-iblock,
  .dbx-iblock {
    display: inline-block;
  }

  /// @dbx-utility inline
  /// @intent set display: inline
  /// @role layout
  /// @see-also dbx-iblock
  .d-inline,
  .dbx-inline {
    display: inline;
  }

  /// @dbx-utility flex
  /// @intent set display: flex (no other flex defaults)
  /// @role flex
  /// @see-also dbx-flex-bar, dbx-flex-center, dbx-flex-column, dbx-iflex
  .d-flex,
  .dbx-flex {
    display: flex;
  }

  /// @dbx-utility iflex
  /// @intent set display: inline-flex
  /// @role flex
  /// @see-also dbx-flex, dbx-fiflex
  .d-iflex,
  .dbx-iflex {
    display: inline-flex;
  }

  /// @dbx-utility w100
  /// @intent fill width — `width: 100%`
  /// @role layout
  /// @see-also dbx-h100
  .dbx-w100 {
    width: 100%;
  }

  // force
  /// @dbx-utility fiflex
  /// @intent set display: inline-flex (forced) — wins over inherited `display`
  /// @role flex
  /// @see-also dbx-iflex
  .d-fiflex,
  .dbx-fiflex {
    display: inline-flex !important;
  }

  @each $color, $colorConfig in theming.$dbx-theme-colors-main {
    @include define-dbx-color-class($color, map.get($colorConfig, 'color'), map.get($colorConfig, 'contrast'));
  }

  @each $color, $colorConfig in theming.$dbx-theme-extra-colors-main {
    @include define-dbx-color-class($color, map.get($colorConfig, 'color'), map.get($colorConfig, 'contrast'));
  }

  @each $color, $colorConfig in theming.$dbx-theme-extra-colors-secondary {
    @include define-dbx-color-class($color, map.get($colorConfig, 'color'), map.get($colorConfig, 'contrast'));
  }

  /// @dbx-utility color-bg
  /// @intent the painting utility — paints `background` (a `color-mix` of `--dbx-bg-color-current` with `--dbx-color-bg-tone`) plus the contrast `color` from `--dbx-color-current`. Pair with `[dbxColor]` (or a static `dbx-{color}-bg` token class) on the same element to supply those tokens. `[dbxColor]` itself never paints; this class (or a component's own `.dbx-color`-scoped SCSS) is what turns the tokens into a visible surface.
  /// @role color
  /// @see-also color-text, color-tonal
  .dbx-color-bg {
    @include dbx-color-bg-body();
  }

  // tonal mode: use the vibrant theme color as text instead of the contrast color.
  // Applied via CSS class (not [style.color]) to avoid conflicting with [ngStyle] on buttons.
  // Declared after `.dbx-color-bg` so the tonal `color:` wins the same-specificity
  // cascade when both classes are present on the painted surface.
  /// @dbx-utility color-tonal
  /// @intent paint text with the vibrant `--dbx-bg-color` (tonal mode) instead of the contrast color — pair with `.dbx-color-bg` + `[dbxColor]` + `[dbxColorTone]` for the muted background variant
  /// @role state
  /// @see-also color-bg
  .dbx-color-tonal {
    color: var(#{theming.$dbx-bg-color-var});
  }

  /// @dbx-utility color-text
  /// @intent generic themed-text class — pair with `[dbxTextColor]="config"` to drive `--dbx-color-current` from an arbitrary CSS color value
  /// @role color
  .dbx-color-text {
    color: #{theming.$dbx-color};
  }

  /// @dbx-utility color-border
  /// @intent subtle themed solid border derived from the current dbxColor text color (`--dbx-color-current`) — pair with `[dbxColor]`/`[dbxTextColor]` on the element or any ancestor (custom properties inherit); override `--dbx-color-border-tone` (percentage) for subtlety or `--dbx-color-border-width` for thickness
  /// @role color
  /// @see-also color-bg, color-text, color-tonal
  .dbx-color-border {
    border: var(--dbx-color-border-width, 1px) solid color-mix(in srgb, #{theming.$dbx-color} var(--dbx-color-border-tone, 25%), transparent);
  }

  /// @dbx-utility color-text-dim
  /// @intent de-emphasized themed text — paints text with a partially-transparent mix of the current dbxColor text color (`--dbx-color-current`), for secondary lines (eyebrows, hints, labels) on painted surfaces where a fixed grey would clash; override `--dbx-color-text-dim-tone` (percentage) to tune the emphasis
  /// @role color
  /// @see-also color-text, color-border, hint
  .dbx-color-text-dim {
    color: color-mix(in srgb, #{theming.$dbx-color} var(--dbx-color-text-dim-tone, 72%), transparent);
  }
}

@mixin dbx-color-bg-body($default-bg-tone: 100%) {
  #{theming.$dbx-bg-tone-var}: $default-bg-tone;
  background: color-mix(in srgb, #{theming.$dbx-bg-color} var(#{theming.$dbx-bg-tone-var}), transparent);
  color: #{theming.$dbx-color};
}

// Paints a colored surface from the inherited dbx color tokens
// (`--dbx-bg-color-current` / `--dbx-color-current` / `--dbx-color-bg-tone`).
// Unlike `dbx-color-bg-body`, the tone fallback lives inside the `var(...)`
// rather than being declared as a property, so the surface does not leak an
// inheritable `--dbx-color-bg-tone` to nested elements. Scope this on a
// `.dbx-color` marker (the model is `mat-card.dbx-color` in `_card.scss`) so
// only hosts directly marked with `[dbxColor]` repaint — token inheritance
// alone never triggers a repaint.
@mixin dbx-color-surface($default-bg-tone: 100%) {
  background: color-mix(in srgb, #{theming.$dbx-bg-color} var(#{theming.$dbx-bg-tone-var}, #{$default-bg-tone}), transparent);
  color: #{theming.$dbx-color};
}

@mixin define-dbx-color-class($name, $color, $contrast, $swap-bg: false) {
  .dbx-#{$name} {
    #{theming.$dbx-color-var}: #{$color};
    color: #{theming.$dbx-color};
  }

  $bg-color: if($swap-bg, $contrast, $color);
  $bg-text: if($swap-bg, $color, $contrast);

  // Token-only: a `-bg` class declares the color tokens but paints nothing.
  // Painting happens via the `.dbx-color-bg` utility or a component's own
  // `.dbx-color`-scoped SCSS reading these tokens.
  .dbx-#{$name}-bg {
    #{theming.$dbx-color-var}: #{$bg-text};
    #{theming.$dbx-bg-color-var}: #{$bg-color};
  }
}

@mixin color($theme-config) {
  // add the css for the default background color
  $default-config: map.get(theming.$dbx-theme-extra-colors-secondary, 'default');
  #{theming.$dbx-color-var}: #{map.get($default-config, 'contrast')};
  #{theming.$dbx-bg-color-var}: #{map.get($default-config, 'color')};
  background: #{theming.$dbx-bg-color};

  // material color overrides
  // - button
  --mat-icon-button-icon-color: #{theming.$dbx-color-var};
  --mat-button-text-label-text-color: #{theming.$dbx-color-var};
  // - list item
  --mat-list-list-item-label-text-color: #{theming.$dbx-color-var};
  --mat-list-list-item-leading-icon-color: #{theming.$dbx-color-var};
}

@mixin theme($theme-config) {
  @include color($theme-config);
}
