@use 'sass:map';

@use './shared' as *;
@use './design' as *;

$switch: () !default;
$switch: map.merge(
  (
    bg-color: value('fill-color-secondary'),
    bg-color-open: value('color-primary-base'),
    bg-color-disabled: value('fill-color-disabled'),
    opacity-disabled: 60%,
    opacity-loading: value('switch-opacity-disabled'),
    s-color-focus: value('color-primary-opacity-6'),
    label-color: value('color-white'),
    height: 22px,
    signal-size: calc(value('switch-height') - 4px),
    signal-bg-color: value('color-white'),
    series-span: 8px,
    icon-color: value('color-black'),
    icon-color-loading: value('color-primary-base'),
    circle-opacity: 0,
    radius-rectangle: value('radius-base')
  ),
  $switch
);

.#{$namespace}-switch {
  &-vars {
    @include define-preset-values('switch', $switch);
  }

  @mixin define-switch-style($style-map) {
    @include define-preset-style('switch', $style-map);
  }

  $height: value('switch-height');
  $signal: value('switch-signal-size');

  @include basis {
    position: relative;
    display: inline-flex;
    align-items: center;
    vertical-align: middle;
    cursor: pointer;
    user-select: none;
    background-color: value('switch-bg-color');
    border-radius: $height;
    transition: value('transition-background'), value('transition-border'),
      value('transition-shadow'), value('transition-opacity');
  }

  &--small {
    @include define-preset-values(
      'switch',
      (
        height: 18px
      )
    );
  }

  &--large {
    @include define-preset-values(
      'switch',
      (
        height: 26px
      )
    );
  }

  & + & {
    margin-inline-start: value('switch-series-span');
  }

  &:focus-within {
    box-shadow: value('shadow-focus') value('switch-s-color-focus');
  }

  &--loading {
    cursor: default;
    opacity: value('switch-opacity-loading');
  }

  &--open {
    background-color: value('switch-bg-color-open');
  }

  &__placeholder {
    display: flex;
    flex-direction: column;
    min-width: calc(#{$height} * 2);
    height: $height;
    padding-inline-start: calc(#{$height} * 1.5 + 1px);
    overflow: hidden;
    white-space: nowrap;
    pointer-events: none;
    visibility: hidden;
  }

  &__label {
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    padding-inline: calc(#{$height} + 2px) calc(#{$height} * 0.5 - 1px);
    line-height: 1;
    color: value('switch-label-color');
    border-radius: $height;
    transition: padding value('transition-base');
  }

  &--open &__label {
    padding-inline: calc(#{$height} * 0.5 - 1px) calc(#{$height} + 2px);
  }

  &__open-text,
  &__close-text {
    display: flex;
    white-space: nowrap;
  }

  &__signal {
    position: absolute;
    inset-inline-start: calc((#{$height} - #{$signal}) * 0.5);
    display: flex;
    align-items: center;
    justify-content: center;
    width: $signal;
    height: $signal;
    background-color: value('switch-signal-bg-color');
    border-radius: 50%;
    transition:
      inset-inline-start value('transition-base'),
      value('transition-transform');
    will-change: inset-inline-start;

    .#{$namespace}-icon {
      color: value('switch-icon-color');
    }
  }

  &--open &__signal {
    inset-inline-start: calc(100% - #{$signal} - (#{$height} - #{$signal}) * 0.5);
  }

  &--loading &__signal .#{$namespace}-icon {
    color: value('switch-icon-color-loading');
  }

  &--rectangle,
  &--rectangle &__label,
  &--rectangle &__signal {
    border-radius: value('switch-radius-rectangle');
  }

  $states: success, error, warning;

  @each $state in $states {
    &--#{$state} {
      @include define-switch-style(
        (
          bg-color: 'color' $state 'light-1',
          bg-color-open: 'color' $state 'light-1',
          s-color-focus: 'color' $state 'opacity-6',
          circle-opacity: 80%
        )
      );
    }
  }

  &--disabled {
    cursor: not-allowed;
    background-color: value('switch-bg-color-disabled');
    opacity: value('switch-opacity-disabled');
  }

  &--disabled &__signal {
    pointer-events: none;
  }

  &__input {
    width: 0;
    height: 0;
    margin: 0;
    pointer-events: none;
    opacity: 0%;
  }
}
