@use 'sass:map';
@use 'sass:color';
@use '@material/switch/switch-theme' as mdc-switch-theme;
@use '@material/theme/color-palette' as mdc-color-palette;
@use '@material/form-field' as mdc-form-field;
@use '../core/theming/theming';
@use '../core/mdc-helpers/mdc-helpers';
@use '../core/typography/typography';


// Generates all color mapping for the properties that only change based on the theme.
@function _get-theme-base-map($is-dark) {
  $on-surface: if($is-dark, mdc-color-palette.$grey-100, mdc-color-palette.$grey-800);
  $hairline: if($is-dark, mdc-color-palette.$grey-700, mdc-color-palette.$grey-300);
  $on-surface-variant: if($is-dark, mdc-color-palette.$grey-500, mdc-color-palette.$grey-700);
  $on-surface-state-content: if($is-dark, mdc-color-palette.$grey-50, mdc-color-palette.$grey-900);
  $disabled-handle-color: if($is-dark, #000, mdc-color-palette.$grey-800);
  $icon-color: if($is-dark, mdc-color-palette.$grey-900, #fff);

  @return (
    disabled-selected-handle-color: $disabled-handle-color,
    disabled-unselected-handle-color: $disabled-handle-color,

    disabled-selected-track-color: $on-surface,
    disabled-unselected-track-color: $on-surface,
    unselected-focus-state-layer-color: $on-surface,
    unselected-pressed-state-layer-color: $on-surface,
    unselected-hover-state-layer-color: $on-surface,

    unselected-focus-track-color: $hairline,
    unselected-hover-track-color: $hairline,
    unselected-pressed-track-color: $hairline,
    unselected-track-color: $hairline,

    unselected-focus-handle-color: $on-surface-state-content,
    unselected-hover-handle-color: $on-surface-state-content,
    unselected-pressed-handle-color: $on-surface-state-content,

    handle-surface-color: surface,
    unselected-handle-color: $on-surface-variant,

    selected-icon-color: $icon-color,
    disabled-selected-icon-color: $icon-color,
    disabled-unselected-icon-color: $icon-color,
    unselected-icon-color: $icon-color,
  );
}

// Generates the mapping for the properties that change based on the slide toggle color.
@function _get-theme-color-map($color-palette, $is-dark) {
  $primary: theming.get-color-from-palette($color-palette, if($is-dark, 300, 600));
  $state-content: theming.get-color-from-palette($color-palette, if($is-dark, 200, 900));
  $inverse: theming.get-color-from-palette($color-palette, if($is-dark, 600, 300));

  @return (
    selected-focus-state-layer-color: $primary,
    selected-handle-color: $primary,
    selected-hover-state-layer-color: $primary,
    selected-pressed-state-layer-color: $primary,

    selected-focus-handle-color: $state-content,
    selected-hover-handle-color: $state-content,
    selected-pressed-handle-color: $state-content,

    selected-focus-track-color: $inverse,
    selected-hover-track-color: $inverse,
    selected-pressed-track-color: $inverse,
    selected-track-color: $inverse,
  );
}

@mixin color($config-or-theme) {
  $config: theming.get-color-config($config-or-theme);
  $primary: map.get($config, primary);
  $accent: map.get($config, accent);
  $warn: map.get($config, warn);
  $is-dark: map.get($config, is-dark);
  $foreground: map.get($config, foreground);

  @include mdc-helpers.using-mdc-theme($config) {
    // MDC's switch doesn't support a `color` property. We add support
    // for it by adding a CSS class for accent and warn style.
    .mat-mdc-slide-toggle {
      @include mdc-form-field.core-styles($query: mdc-helpers.$mdc-theme-styles-query);
      @include mdc-switch-theme.theme(_get-theme-base-map($is-dark));

      // MDC should set the disabled color on the label, but doesn't, so we do it here instead.
      .mdc-switch--disabled + label {
        color: theming.get-color-from-palette($foreground, disabled-text);
      }

      &.mat-primary {
        @include mdc-switch-theme.theme(_get-theme-color-map($primary, $is-dark));
      }

      &.mat-accent {
        @include mdc-switch-theme.theme(_get-theme-color-map($accent, $is-dark));
      }

      &.mat-warn {
        @include mdc-switch-theme.theme(_get-theme-color-map($warn, $is-dark));
      }
    }
  }
}

@mixin typography($config-or-theme) {
  $config: typography.private-typography-to-2018-config(
      theming.get-typography-config($config-or-theme));
  @include mdc-helpers.using-mdc-typography($config) {
    @include mdc-form-field.core-styles($query: mdc-helpers.$mdc-typography-styles-query);
  }
}

@mixin density($config-or-theme) {
  $density-scale: theming.get-density-config($config-or-theme);
  .mat-mdc-slide-toggle {
    @include mdc-switch-theme.theme(mdc-switch-theme.density($density-scale));
  }
}

@mixin theme($theme-or-color-config) {
  $theme: theming.private-legacy-get-theme($theme-or-color-config);

  @include theming.private-check-duplicate-theme-styles($theme, 'mat-slide-toggle') {
    $color: theming.get-color-config($theme);
    $density: theming.get-density-config($theme);
    $typography: theming.get-typography-config($theme);

    @if $color != null {
      @include color($color);
    }
    @if $density != null {
      @include density($density);
    }
    @if $typography != null {
      @include typography($typography);
    }
  }
}

