@use 'sass:map';
@use 'sass:math';
@use 'config/colors';
@use 'functions/color';
@use 'mixins/flex';
@use 'mixins/position';
@use 'mixins/spacing';
@use 'mixins/transition';

$field: (
  min-height: 40px, // of the field container (NOT the switch track!)
  padding-x: 5px,
  padding-y: 2px,
  border-radius: 50px,
  opacity-disabled: 0.3,
);

$label: (
  spacing: 10px, // from track
  font-weight: 500,
  font-size: 12px,

  color: (
    default: (
      light: colors.$black,
      dark: colors.$white,
    ),

    hover: (
      light: color.shade(colors.$blue, 15%),
      dark: colors.$blue,
    ),

    read-only: (
      light: color.alpha(colors.$black, 0.65),
      dark: color.alpha(colors.$white, 0.65),
    ),
  ),
);

$backdrop: (
  gutter: 0,
  opacity-disabled: 0.3,

  background-color: (
    default: (
      light: color.alpha(colors.$black, 0.025),
      dark: color.alpha(colors.$white, 0.025),
    ),

    selected: (
      light: color.shade(colors.$blue, 15%),
      dark: colors.$blue,
    ),
  ),
);

$track: (
  height: math.div(map.get($field, min-height), 2),
  gutter: 4px, // padding between track and handle

  box-shadow: (
    light: (
      0 0 1px color.alpha(colors.$black, 0.3),
      0 0 2px color.alpha(colors.$gray-darker, 0.3),
    ),

    dark: (
      0 0 1px color.alpha(colors.$white, 0.5),
      0 0 2px color.alpha(colors.$black, 0.3),
    ),
  )
);

$handle: (
  size: map.get($track, height) - map.get($track, gutter),

  background-color: (
    default: (
      light: colors.$white,
      dark: colors.$white,
    ),

    disabled: (
      light: colors.$gray-light,
      dark: colors.$white,
    ),
  ),

  box-shadow: (
    light: (
      0 0 1px color.alpha(colors.$black, 0.3),
      0 0 3px color.alpha(colors.$gray-darker, 0.25),
    ),

    dark: (
      0 0 1px color.alpha(colors.$white, 0.3),
      0 0 3px color.alpha(colors.$black, 0.25),
    ),
  ),

  opacity: (
    read-only: 0.5,
    disabled: 0.5,
  ),

  transition-duration: 125ms,
);

.container {
  position: relative;
}

.field {
  @include flex.row;
  // min-height: map.get($field, min-height);
  @include spacing.padding-xy($x: map.get($field, padding-x), $y: map.get($field, padding-y));
  font-weight: map.get($label, font-weight);
  font-size: map.get($label, font-size);
  border-radius: map.get($field, border-radius);
  outline: none;
  @include transition.apply(color, opacity);
  cursor: pointer;

  .light & {
    color: map.get($label, color, default, light);
  }

  .dark & {
    color: map.get($label, color, default, dark);
  }

  &:not(.readOnly):hover {
    .light & {
      color: map.get($label, color, hover, light);
    }

    .dark & {
      color: map.get($label, color, hover, dark);
    }
  }

  &.readOnly {
    cursor: default;

    .light & {
      color: map.get($label, color, read-only, light);
    }

    .dark & {
      color: map.get($label, color, read-only, dark);
    }
  }

  &.disabled {
    opacity: map.get($field, opacity-disabled);
    pointer-events: none;
  }

  & > * {
    align-self: center;
  }

  input {
    pointer-events: none;
  }
}

.label {
  display: block;
  @include spacing.margin($left: map.get($label, spacing));
  color: inherit;
  user-select: none;
}

.track {
  position: relative;
  @include flex.row;
  @include spacing.padding-all(map.get($track, gutter));
  border-radius: map.get($field, border-radius);
  // @include transition.apply(box-shadow);

  // .light & {
  //   box-shadow: map.get($track, box-shadow, light);
  // }

  // .dark & {
  //   box-shadow: map.get($track, box-shadow, dark);
  // }
}

.backdrop {
  @include position.absolute-all(map.get($backdrop, gutter));
  display: block;
  border-radius: map.get($field, border-radius);
  @include transition.apply(box-shadow);
  overflow: hidden;
  // z-index: -1;

  .light & {
    box-shadow: map.get($track, box-shadow, light);
  }

  .dark & {
    box-shadow: map.get($track, box-shadow, dark);
  }
}

.innerBackdrop {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: map.get($field, border-radius);
  @include transition.apply(background-color);

  .light & {
    background-color: map.get($backdrop, background-color, default, light);
  }

  .dark & {
    background-color: map.get($backdrop, background-color, default, dark);
  }

  .selected & {
    .light & {
      background-color: map.get($backdrop, background-color, selected, light);
    }

    .dark & {
      background-color: map.get($backdrop, background-color, selected, dark);
    }
  }
}

// otherwise, the handle can be dragged into the padding
.trackContainer {
  @include flex.row;
  width: 100%;
}

.handle {
  width: map.get($handle, size);
  height: map.get($handle, size);
  background: none;
  border: none;
  border-radius: map.get($field, border-radius);
  outline: none;
  @include transition.apply(
    background-color,
    box-shadow,
    opacity,
    (transform, map.get($handle, transition-duration)),
  );
  z-index: 1;
  cursor: grab;

  .light & {
    background-color: map.get($handle, background-color, default, light);
    box-shadow: map.get($handle, box-shadow, light);
  }

  .dark & {
    background-color: map.get($handle, background-color, default, dark);
    box-shadow: map.get($handle, box-shadow, dark);
  }

  &.dragging {
    cursor: grabbing;
  }

  &.readOnly {
    opacity: map.get($handle, opacity, read-only);
    cursor: default;
  }

  .disabled & {
    box-shadow: none;
    opacity: map.get($handle, opacity, disabled);
    cursor: not-allowed;

    .light & {
      background-color: map.get($handle, background-color, disabled, light);
    }

    .dark & {
      background-color: map.get($handle, background-color, disabled, dark);
    }
  }
}
