////
/// @group form-toggle
////

@use 'sass:color';

@import '~@react-md/button/dist/mixins';
@import '~@react-md/icon/dist/mixins';
@import '~@react-md/menu/dist/mixins';
@import '~@react-md/progress/dist/mixins';
@import '~@react-md/states/dist/mixins';
@import '~@react-md/theme/dist/mixins';
@import '~@react-md/utils/dist/mixins';
@import '../variables';
@import '../functions';

/// Creates the minimal styles for a toggle container.
/// @access private
@mixin rmd-toggle-container {
  align-items: center;
  display: flex;

  &--inline {
    display: inline-flex;
  }

  &--stacked {
    flex-direction: column;
  }
}

/// Creates all the styles for creating the icon container for the checkbox and
/// radio input types.
/// @access private
@mixin rmd-toggle {
  @include rmd-button-theme(height, icon-size);
  @include rmd-button-theme(width, icon-size);
  @include rmd-states-surface('&--focused');

  align-items: center;
  border-radius: $rmd-toggle-border-radius;
  display: inline-flex;
  flex-shrink: 0;
  justify-content: center;
  position: relative;

  &--disabled {
    @include rmd-states-theme-update-var(hover-color, transparent);
  }
}

/// Creates styles to apply to the "hidden" input for checkboxes and radios.
/// @access private
@mixin rmd-input-hidden {
  @include rmd-utils-hide-focus-outline;

  bottom: 0;
  height: 100%;
  left: 0;
  margin: 0;
  opacity: 0;
  position: absolute;
  right: 0;
  top: 0;
  width: 100%;
  z-index: 1;

  &:hover {
    cursor: pointer;
  }

  &:disabled {
    &:hover {
      cursor: default;
    }
  }
}

/// Creates the styles for a form input that should be hidden from view. This
/// should normally be applied to checkbox or radio input types.
/// @access private
@mixin rmd-toggle-hidden {
  @include rmd-input-hidden;

  @if $rmd-toggle-active-color != $rmd-toggle-inactive-color {
    &:checked + .rmd-toggle__icon {
      color: $rmd-toggle-active-color;
    }
  }

  &:checked + .rmd-toggle__icon::before {
    opacity: 0;
  }

  &:checked + .rmd-toggle__icon--indeterminate {
    &::before,
    &::after {
      opacity: 1;
    }
  }
}

/// Creates the styles for the checkbox and radio input types' icon
/// @access private
@mixin rmd-toggle-icon {
  @include rmd-icon-theme(height, size);
  @include rmd-icon-theme(width, size);
  @include rmd-icon-theme-update-var(color, currentColor);

  align-items: center;
  color: $rmd-toggle-inactive-color;
  display: inline-flex;
  justify-content: center;
  pointer-events: none;
  position: absolute;

  &--overlay {
    &::before {
      @include rmd-transition(standard);
      @include rmd-form-theme(bottom, toggle-inset);
      @include rmd-form-theme(left, toggle-inset);
      @include rmd-form-theme(right, toggle-inset);
      @include rmd-form-theme(top, toggle-inset);
      @include rmd-theme(background-color, background);

      content: '';
      opacity: 1;
      position: absolute;
      transition: opacity $rmd-transition-standard-time;
      z-index: 1;
    }
  }

  &--indeterminate::after {
    @include rmd-transition(standard);
    @include rmd-form-theme(background-color, active-color);
    @include rmd-form-theme(left, toggle-inset);
    @include rmd-form-theme(right, toggle-inset);
    @include rmd-form-theme(height, indeterminate-height);

    content: '';
    opacity: 0;
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
    transition: opacity $rmd-transition-standard-time;
    z-index: 2;
  }

  &--circle::before {
    border-radius: $rmd-toggle-border-radius;
  }

  &--disabled {
    @include rmd-theme(color, text-disabled-on-background);
  }

  &--dense {
    @include rmd-form-theme(bottom, toggle-dense-inset);
    @include rmd-form-theme(left, toggle-dense-inset);
    @include rmd-form-theme(right, toggle-dense-inset);
    @include rmd-form-theme(top, toggle-dense-inset);
    @include rmd-form-theme(height, indeterminate-dense-height);
  }

  &--checked {
    @if $rmd-toggle-active-color != $rmd-toggle-inactive-color {
      @include rmd-icon-theme-update-var(color, $rmd-toggle-active-color);
    }

    &::before {
      opacity: 0;
    }
  }

  &--indeterminate-checked {
    @if $rmd-toggle-active-color != $rmd-toggle-inactive-color {
      @include rmd-icon-theme-update-var(color, $rmd-toggle-active-color);
    }

    &::after {
      opacity: 1;
    }
  }
}

/// Updates the checkbox and radio components to have a dense theme by updating
/// the toggle-inset css variable to be the dense version. This should generally
/// be used within media queries.
@mixin rmd-toggle-dense-theme {
  @include rmd-form-theme-update-var(
    toggle-inset,
    rmd-form-theme-var(toggle-dense-inset)
  );
  @include rmd-form-theme-update-var(
    indeterminate-height,
    rmd-form-theme-var(indeterminate-dense-height)
  );
}

/// Creates the styles for the switch component
/// @access private
@mixin rmd-switch {
  @include rmd-transition(standard);
  @include rmd-form-theme(background-color, track-background-color);

  border-radius: $rmd-switch-track-border-radius;
  height: $rmd-switch-track-height;
  position: relative;
  transition: background-color $rmd-transition-standard-time;
  width: $rmd-switch-track-width;

  &--disabled {
    @include rmd-form-theme-update-var(
      track-background-color,
      rmd-form-theme-var(disabled-color)
    );
  }

  &--async {
    // make the progress bar a bit more prominent
    @include rmd-progress-theme-update-var(
      circular-width,
      $rmd-switch-progress-width
    );
    // shrink the progress bar to be the same size as the switch's ball
    @include rmd-progress-theme-update-var(
      circular-size,
      $rmd-switch-ball-size
    );
  }
}

///
/// @access private
@mixin rmd-switch-ball-disabled {
  @include rmd-states-theme-update-var(hover-color, transparent);

  cursor: auto;

  &::after {
    @include rmd-form-theme(background-color, disabled-color);
  }
}

///
/// @access private
@mixin rmd-switch-ball-checked {
  $offset: $rmd-switch-ball-size + $rmd-switch-ball-offset;

  @include rmd-utils-rtl {
    transform: translateX(-$offset);
  }

  transform: translateX($offset);

  &::after {
    @include rmd-form-theme(background-color, active-color);
  }
}

///
/// @access private
@mixin rmd-switch-input {
  @include rmd-input-hidden;
  @include rmd-states-focus-shadow('&:focus + .rmd-switch__ball');
  @include rmd-utils-keyboard-only {
    &:focus + .rmd-switch__ball {
      @include rmd-states-theme-update-var(
        background-color,
        rmd-states-theme-var(focus-color)
      );
    }

    &:focus:hover + .rmd-switch__ball {
      @include rmd-states-theme-update-var(
        background-color,
        rmd-states-theme-var(hover-color)
      );
    }
  }
  @include rmd-utils-touch-only {
    &:focus + .rmd-switch__ball,
    &:hover + .rmd-switch__ball {
      @include rmd-states-theme-update-var(background-color, transparent);
    }
  }

  &:disabled + .rmd-switch__ball {
    @include rmd-switch-ball-disabled;
  }

  &:checked + .rmd-switch__ball {
    @include rmd-switch-ball-checked;
  }

  &:checked:disabled + .rmd-switch__ball::after {
    background-color: $rmd-switch-ball-disabled-color;
  }
}

/// @access private
@mixin rmd-switch-ball {
  @include rmd-utils-hide-focus-outline;
  @include rmd-transition(standard);
  @include rmd-utils-rtl {
    left: auto;
    right: calc(-50% + #{$rmd-switch-ball-offset});
  }

  align-items: center;
  border-radius: $rmd-switch-ball-border-radius;
  display: flex;
  height: $rmd-switch-ball-size * 2;
  justify-content: center;
  left: calc(-50% + #{$rmd-switch-ball-offset});
  position: absolute;
  top: calc(-50% - #{$rmd-switch-ball-size - $rmd-switch-track-height});
  transition-duration: $rmd-transition-standard-time;
  transition-property: background-color, transform;
  width: $rmd-switch-ball-size * 2;
  z-index: 1;

  &::before {
    @include rmd-states-surface-base;
  }

  &:hover {
    @include rmd-states-theme-update-var(
      background-color,
      rmd-states-theme-var(hover-color)
    );

    cursor: pointer;
  }

  &::after {
    @include rmd-elevation(1);

    background-color: color.adjust($rmd-white-base, $lightness: -5%);
    border-radius: inherit;
    content: '';
    height: $rmd-switch-ball-size;
    left: 25%;
    pointer-events: none;
    position: absolute;
    top: 25%;
    width: $rmd-switch-ball-size;
    z-index: 1;
  }

  &--checked {
    @include rmd-switch-ball-checked;
  }
}

/// @access private
@mixin rmd-switch-container {
  padding: $rmd-switch-container-vertical-padding
    $rmd-switch-container-horizontal-padding;
}

/// Creates all the styles for the toggle components in the form package.
/// @access private
@mixin react-md-toggle {
  .rmd-toggle-container {
    @include rmd-toggle-container;
  }

  .rmd-toggle {
    @include rmd-toggle;

    &__input {
      @include rmd-toggle-hidden;
    }

    &__icon {
      @include rmd-toggle-icon;
    }
  }

  .rmd-input-toggle-menu-item {
    // shrink the checkbox/radio icon size to just be an icon
    @include rmd-button-theme-update-var(icon-size, rmd-icon-theme-var(size));

    &--switch {
      // this makes the spacing correct between the switch and the text
      @include rmd-icon-theme-update-var(size, $rmd-switch-track-width);
    }

    &__toggle {
      // this disables some weird background color borders that gets applied
      // during `:hover` and `:focus`
      @include rmd-menu-theme(background-color);
    }

    // disable the interaction states since they are handled by the main menu
    // item. has to override both behaviors for `:focus` and `:hover` changes.
    .rmd-switch__ball,
    .rmd-switch__ball:hover {
      @include rmd-states-theme-update-var(background-color, transparent);
    }
  }

  .rmd-switch-container {
    @include rmd-switch-container;
  }

  .rmd-switch {
    @include rmd-switch;

    &__input {
      @include rmd-switch-input;
    }

    &__ball {
      @include rmd-switch-ball;
    }

    &__progress {
      background-color: $rmd-switch-progress-background-color;
      border-radius: inherit;
      padding: $rmd-switch-progress-padding;
      z-index: 2;
    }
  }
}
