@use '../../internals/Box/styles/index' as box;
@use '../../styles/mixins/utilities' as utils;
@use '../../styles/mixins/color-modes' as color-modes;
@use '../../styles/colors/colors-base' as colors;
@use '../../Button/styles/mixin' as button-mixin;

//
// Toggle
// --------------------------------------------------

.rs-toggle {
  // CSS Variables
  --rs-toggle-transition: 0.2s ease-in-out;
  --rs-toggle-gap: 10px;
  --rs-toggle-active-scale: 1.2;

  // Extra small size
  --rs-toggle-font-size-xs: var(--rs-font-size-2xs);
  --rs-toggle-inner-font-size-xs: var(--rs-font-size-3xs);
  --rs-toggle-line-height-xs: 1;
  --rs-toggle-gap-xs: 4px;
  --rs-toggle-handle-gap-xs: 2px;
  --rs-toggle-size-xs: 14px;
  --rs-toggle-inner-margin-xs: 4px;

  // Small size
  --rs-toggle-font-size-sm: var(--rs-font-size-xs);
  --rs-toggle-inner-font-size-sm: var(--rs-font-size-2xs);
  --rs-toggle-line-height-sm: 1.4;
  --rs-toggle-gap-sm: 6px;
  --rs-toggle-handle-gap-sm: 2px;
  --rs-toggle-size-sm: 18px;
  --rs-toggle-inner-margin-sm: 6px;

  // Medium size
  --rs-toggle-font-size-md: var(--rs-font-size-sm);
  --rs-toggle-inner-font-size-md: var(--rs-font-size-xs);
  --rs-toggle-line-height-md: 2;
  --rs-toggle-gap-md: 8px;
  --rs-toggle-handle-gap-md: 3px;
  --rs-toggle-size-md: 22px;
  --rs-toggle-inner-margin-md: 8px;

  // Large size
  --rs-toggle-font-size-lg: var(--rs-font-size-md);
  --rs-toggle-inner-font-size-lg: var(--rs-font-size-sm);
  --rs-toggle-line-height-lg: 2.14285714;
  --rs-toggle-gap-lg: 10px;
  --rs-toggle-handle-gap-lg: 4px;
  --rs-toggle-size-lg: 28px;
  --rs-toggle-inner-margin-lg: 10px;

  // Extra large size
  --rs-toggle-font-size-xl: var(--rs-font-size-lg);
  --rs-toggle-inner-font-size-xl: var(--rs-font-size-md);
  --rs-toggle-line-height-xl: 2.14285714;
  --rs-toggle-gap-xl: 12px;
  --rs-toggle-handle-gap-xl: 5px;
  --rs-toggle-size-xl: 34px;
  --rs-toggle-inner-margin-xl: 12px;

  position: relative;
  display: inline-flex;
  align-items: center;
  font-size: var(--rs-toggle-font-size);
  gap: var(--rs-toggle-gap);

  // Size variants
  $sizes: xs, sm, md, lg, xl;

  @each $size in $sizes {
    &[data-size='#{$size}'] {
      --rs-toggle-font-size: var(--rs-toggle-font-size-#{$size});
      --rs-toggle-inner-font-size: var(--rs-toggle-inner-font-size-#{$size});
      --rs-toggle-line-height: var(--rs-toggle-line-height-#{$size});
      --rs-toggle-inner-margin: var(--rs-toggle-inner-margin-#{$size});
      --rs-toggle-handle-size: calc(
        var(--rs-toggle-size-#{$size}) - var(--rs-toggle-handle-gap-#{$size}) * 2
      );
      --rs-toggle-handle-gap: var(--rs-toggle-handle-gap-#{$size});
      --rs-toggle-gap: var(--rs-toggle-gap-#{$size});
      --rs-toggle-min-width: calc(var(--rs-toggle-size-#{$size}) * 2 - var(--rs-toggle-handle-gap));
      --rs-toggle-size: var(--rs-toggle-size-#{$size});
      --rs-toggle-checked-margin-left: calc(
        (var(--rs-toggle-size) - var(--rs-toggle-handle-gap)) * -1
      );
      --rs-toggle-active-checked-margin-left: calc(
        (var(--rs-toggle-size) * var(--rs-toggle-active-scale) - var(--rs-toggle-handle-gap)) * -1
      );
    }
  }

  // Colorful
  @each $color in colors.$spectrum {
    &[data-color='#{$color}'] {
      --rs-toggle-checked-bg: var(--rs-#{$color}-500);
      --rs-toggle-checked-hover-bg: var(--rs-#{$color}-600);
    }
  }

  &:where([data-placement='start']) {
    flex-direction: row-reverse;
  }

  &-label {
    cursor: pointer;
    font-size: inherit;
  }

  &-inner {
    display: flex;
    align-items: center;
    justify-content: center;
    transition: margin var(--rs-toggle-transition);
    font-size: var(--rs-toggle-inner-font-size);
    line-height: var(--rs-toggle-line-height);
    margin-inline-start: var(--rs-toggle-size);
    margin-inline-end: var(--rs-toggle-inner-margin);
    height: var(--rs-toggle-size);

    .rs-icon {
      font-size: inherit;
    }
  }

  &-input {
    cursor: pointer;
    position: absolute;
    inset: 0;
    opacity: 0;
  }

  &-track {
    position: relative;
    display: inline-block;
    box-sizing: border-box;
    vertical-align: middle;
    background-color: var(--rs-toggle-bg);
    color: var(--rs-toggle-thumb);
    cursor: pointer;
    transition:
      background-color var(--rs-toggle-transition),
      width var(--rs-toggle-transition);
    user-select: none;
    height: var(--rs-toggle-size);
    line-height: 1;
    min-width: var(--rs-toggle-min-width);
    border-radius: var(--rs-radius-full);

    &::after {
      width: var(--rs-toggle-handle-size);
      height: var(--rs-toggle-handle-size);
      inset-inline-start: var(--rs-toggle-handle-gap);
      top: var(--rs-toggle-handle-gap);
      border-radius: var(--rs-radius-full);
    }

    &:active::after {
      width: calc(var(--rs-toggle-handle-size) * var(--rs-toggle-active-scale));
    }

    @include color-modes.high-contrast-mode {
      transition: none;
      box-shadow: inset 0 0 0 1px var(--rs-toggle-thumb);
    }

    // Focus state
    .rs-toggle-input:focus-visible + & {
      @include utils.focus-ring;
      box-shadow:
        inset 0 0 0 1px var(--rs-toggle-thumb),
        var(--rs-state-focus-shadow);
    }

    // Hover state
    &:hover {
      background-color: var(--rs-toggle-hover-bg);
    }

    // Toggle thumb
    &::after {
      content: '';
      cursor: pointer;
      position: absolute;
      background-color: currentColor;
      transition:
        inset-inline-start var(--rs-toggle-transition),
        margin-inline-start var(--rs-toggle-transition),
        width var(--rs-toggle-transition);
    }

    // Disabled state
    .rs-toggle[data-disabled='true'] & {
      background-color: var(--rs-toggle-disabled-bg);
      color: var(--rs-toggle-disabled-thumb);
      pointer-events: none;
    }

    // Checked state
    .rs-toggle[data-checked='true'] & {
      background-color: var(--rs-toggle-checked-bg);
      color: var(--rs-toggle-checked-thumb);
      box-shadow: none;

      &::after {
        inset-inline-start: 100%;
        margin-inline-start: var(--rs-toggle-checked-margin-left);
      }

      &:active::after {
        margin-inline-start: var(--rs-toggle-active-checked-margin-left);
      }

      .rs-toggle-inner {
        margin-inline-end: var(--rs-toggle-size);
        margin-inline-start: var(--rs-toggle-inner-margin);
      }

      &:hover {
        background-color: var(--rs-toggle-checked-hover-bg);
      }
    }

    .rs-toggle[data-checked='true'][data-disabled='true'] & {
      background-color: var(--rs-toggle-checked-disabled-bg);
      color: var(--rs-toggle-checked-disabled-thumb);
    }

    .rs-toggle[data-loading='true'] & {
      &::after {
        display: none;
      }
    }
  }

  &-loader {
    position: absolute;
    transition:
      left var(--rs-toggle-transition),
      margin-left var(--rs-toggle-transition),
      width var(--rs-toggle-transition);
    width: var(--rs-toggle-handle-size);
    height: var(--rs-toggle-handle-size);
    inset-inline-start: var(--rs-toggle-handle-gap);
    top: var(--rs-toggle-handle-gap);

    .rs-loader-spin,
    .rs-loader-spin::before,
    .rs-loader-spin::after {
      width: var(--rs-toggle-handle-size);
      height: var(--rs-toggle-handle-size);
    }

    .rs-loader-spin::before,
    .rs-loader-spin::after {
      border-width: 2px;
    }

    .rs-toggle[data-checked='true'] & {
      inset-inline-start: 100%;
      margin-inline-start: var(--rs-toggle-checked-margin-left);
    }

    .rs-loader-spin {
      &::before {
        border-color: var(--rs-toggle-loader-ring);
      }
      &::after {
        border-top-color: var(--rs-toggle-loader-rotor);
      }

      .rs-toggle[data-checked='true'] & {
        @include color-modes.high-contrast-mode {
          &::before {
            border-color: var(--rs-gray-200);
          }
          &::after {
            border-top-color: var(--rs-gray-500);
          }
        }
      }
    }
  }
}
