@use './theming/theming';
@use './theming/inspection';
@use './ripple/ripple-theme';
@use './option/option-theme';
@use './option/optgroup-theme';
@use './selection/pseudo-checkbox/pseudo-checkbox-theme';
@use './style/sass-utils';
@use './typography/typography';
@use './tokens/token-utils';
@use './m2-app';
@use './m3-app';
@use 'ripple/m3-ripple';
@use 'option/m3-option';
@use 'option/m3-optgroup';
@use 'selection/pseudo-checkbox/m3-pseudo-checkbox';
@use 'sass:map';

@mixin base($theme) {
  @if inspection.get-theme-version($theme) == 1 {
    @include token-utils.create-token-values(map.get(m3-app.get-tokens($theme), base));
    @include token-utils.create-token-values(map.get(m3-ripple.get-tokens($theme), base));
    @include token-utils.create-token-values(map.get(m3-option.get-tokens($theme), base));
    @include token-utils.create-token-values(map.get(m3-optgroup.get-tokens($theme), base));
    @include token-utils.create-token-values(map.get(m3-pseudo-checkbox.get-tokens($theme), base));
  } @else {
    @include ripple-theme.base($theme);
    @include option-theme.base($theme);
    @include optgroup-theme.base($theme);
    @include pseudo-checkbox-theme.base($theme);
    @include sass-utils.current-selector-or-root() {
      @include token-utils.create-token-values-mixed(m2-app.get-unthemable-tokens());
    }
  }
}

@mixin color($theme) {
  @if inspection.get-theme-version($theme) == 1 {
    @include token-utils.create-token-values(map.get(m3-app.get-tokens($theme), color));
    @include token-utils.create-token-values(map.get(m3-ripple.get-tokens($theme), color));
    @include token-utils.create-token-values(map.get(m3-option.get-tokens($theme), color));
    @include token-utils.create-token-values(map.get(m3-optgroup.get-tokens($theme), color));
    @include token-utils.create-token-values(map.get(m3-pseudo-checkbox.get-tokens($theme), color));
  } @else {
    @include ripple-theme.color($theme);
    @include option-theme.color($theme);
    @include optgroup-theme.color($theme);
    @include pseudo-checkbox-theme.color($theme);
    @include sass-utils.current-selector-or-root() {
      @include token-utils.create-token-values-mixed(m2-app.get-color-tokens($theme));
    }
  }
}

@mixin typography($theme) {
  @if inspection.get-theme-version($theme) == 1 {
    @include token-utils.create-token-values(map.get(m3-app.get-tokens($theme), typography));
    @include token-utils.create-token-values(map.get(m3-ripple.get-tokens($theme), typography));
    @include token-utils.create-token-values(map.get(m3-option.get-tokens($theme), typography));
    @include token-utils.create-token-values(map.get(m3-optgroup.get-tokens($theme), typography));
    @include token-utils.create-token-values(
        map.get(m3-pseudo-checkbox.get-tokens($theme), typography));
  } @else {
    @include option-theme.typography($theme);
    @include optgroup-theme.typography($theme);
    @include pseudo-checkbox-theme.typography($theme);
    @include ripple-theme.typography($theme);
  }
}

@mixin density($theme) {
  @if inspection.get-theme-version($theme) == 1 {
    @include token-utils.create-token-values(map.get(m3-app.get-tokens($theme), density));
    @include token-utils.create-token-values(map.get(m3-ripple.get-tokens($theme), density));
    @include token-utils.create-token-values(map.get(m3-option.get-tokens($theme), density));
    @include token-utils.create-token-values(map.get(m3-optgroup.get-tokens($theme), density));
    @include token-utils.create-token-values(
        map.get(m3-pseudo-checkbox.get-tokens($theme), density));
  } @else {
    @include option-theme.density($theme);
    @include optgroup-theme.density($theme);
    @include pseudo-checkbox-theme.density($theme);
    @include ripple-theme.density($theme);
  }
}

@function _define-overrides() {
  @return (
    (
      namespace: app,
      tokens: token-utils.get-overrides(m3-app.get-tokens(), app),
      prefix: 'app-'
    ),
    (
      namespace: ripple,
      tokens: token-utils.get-overrides(m3-ripple.get-tokens(), ripple),
      prefix: 'ripple-'
    ),
    (
      namespace: option,
      tokens: token-utils.get-overrides(m3-option.get-tokens(), option),
      prefix: 'option-'
    ),
    (
      namespace: optgroup,
      tokens: token-utils.get-overrides(m3-optgroup.get-tokens(), optgroup),
      prefix: 'optgroup-'
    ),
    (
      namespace: pseudo-checkbox,
      tokens: token-utils.get-overrides(m3-pseudo-checkbox.get-tokens(), pseudo-checkbox),
      prefix: 'pseudo-checkbox-'
    ),
  );
}

@mixin overrides($tokens: ()) {
  @include token-utils.batch-create-token-values($tokens, _define-overrides());
}

// Mixin that renders all of the core styles that depend on the theme.
@mixin theme($theme) {
  // Wrap the sub-theme includes in the duplicate theme styles mixin. This ensures that
  // there won't be multiple warnings. e.g. if `mat-core-theme` reports a warning, then
  // the imported themes (such as `mat-ripple-theme`) should not report again.
  @include theming.private-check-duplicate-theme-styles($theme, 'mat-core') {
    @if inspection.get-theme-version($theme) == 1 {
      @include base($theme);
      @include color($theme);
      @include density($theme);
      @include typography($theme);
    } @else {
      @include base($theme);
      @if inspection.theme-has($theme, color) {
        @include color($theme);
      }
      @if inspection.theme-has($theme, density) {
        @include density($theme);
      }
      @if inspection.theme-has($theme, typography) {
        @include typography($theme);
      }
    }
  }
}
