<template>
  <div
    :class="{'--active': active}"
    class="ui-slider"
    @touchstart="onTouchStart"
    @touchmove="onTouchMove"
  >
    <div class="ui-slider__header">
      <span class="ui-slider__label">
        <UiIcon
          v-if="icon"
          :name="icon"
          :prefix="iconPrefix"
          class="ui-slider__label-icon"
          size="16"
        />
        {{ title }}
      </span>
      <slot name="title-append"/>
      <p class="ui-slider__subtitle">
        <span class="ui-slider__range">{{ Array.isArray(displayValue) ? `${displayValue[0]}–${displayValue[1]}` : displayValue }}</span>
      </p>
    </div>
    <div class="ui-slider__wrapper">
      <Slider
        v-model="model"
        v-bind="$attrs"
        :tooltips="false"
        @slide="(val: number | number[]) => displayValue = val"
      />
    </div>
  </div>
</template>

<script setup lang="ts">
const Slider = defineAsyncComponent(() => import('@vueform/slider'));

const model = defineModel<number | number[]>();
const displayValue = ref<number | number[]>(model.value ?? 0);

watch(model, (val) => { if (val !== undefined) displayValue.value = val; });

defineProps<{
  title: string
  active?: boolean
  between?: string[]
  icon?: string
  iconPrefix?: string
}>();

let startX = 0;

function onTouchStart(e: TouchEvent) {
  startX = e.touches[0].clientX;
}

function onTouchMove(e: TouchEvent) {
  const deltaX = e.touches[0].clientX - startX;
  // Если пользователь начал свайп с левого края (например < 30px) и двигает вправо — предотвращаем навигацию
  if (startX < 30 && deltaX > 10) {
    e.preventDefault();
  }
}
</script>

<style lang="scss">
.ui-slider {
  --slider-height: 4px;
  --slider-radius: #{$radius-full};

  min-width: 214px;

  @include from-br(sm) {
    min-width: auto;
  }
}

.ui-slider__wrapper {
  padding-top: 8px;
  padding-bottom: 8px;
  width: calc(100% - 16px);
  margin: 0 auto;
}

.ui-slider__header {
  @include font-sm;

  display: flex;
  align-items: center;
  gap: 6px;
  margin-bottom: 8px;
  color: $slider-header-text;
}

.ui-slider__range {
  @include font-xs;
}

.ui-slider__subtitle {
  display: flex;
  align-items: center;
  margin-left: auto;
}

.ui-slider__range {
  color: $slider-range-text;
}

.ui-slider__label {
  display: flex;
  flex-wrap: nowrap;
  align-items: center;
  column-gap: 8px;

  &::first-letter {
    text-transform: uppercase;
  }
}

.ui-slider__label-icon {
  flex-shrink: 0;
  color: $slider-label-icon;
}

// вендорный CSS @vueform/slider
.slider-target, .slider-target * {
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
  box-sizing: border-box;
  touch-action: none;
  user-select: none
}

.slider-target {
  position: relative
}

.slider-base, .slider-connects {
  height: 100%;
  position: relative;
  width: 100%;
  z-index: 1
}

.slider-connects {
  overflow: hidden;
  z-index: 0
}

.slider-connect, .slider-origin {
  height: 100%;
  position: absolute;
  right: 0;
  top: 0;
  transform-origin: 0 0;
  transform-style: preserve-3d;
  transform-style: flat;
  width: 100%;
  will-change: transform;
  z-index: 1
}

.slider-txt-dir-rtl.slider-horizontal .slider-origin {
  left: 0;
  right: auto
}

.slider-vertical .slider-origin {
  top: -100%;
  width: 0
}

.slider-horizontal .slider-origin {
  height: 0
}

.slider-handle {
  backface-visibility: hidden;
  position: absolute
}

.slider-touch-area {
  height: 100%;
  width: 100%
}

.slider-state-tap .slider-connect, .slider-state-tap .slider-origin {
  transition: transform .3s
}

.slider-state-drag * {
  cursor: inherit !important
}

.slider-tooltip-drag .slider-tooltip, .slider-tooltip-focus .slider-tooltip {
  display: none !important
}

.slider-tooltip-drag .slider-active .slider-tooltip, .slider-tooltip-drag.slider-state-drag .slider-tooltip:not(.slider-tooltip-hidden), .slider-tooltip-focus.slider-focused .slider-tooltip:not(.slider-tooltip-hidden) {
  display: block !important
}

.slider-horizontal {
  height: var(--slider-height, 6px)
}

.slider-horizontal .slider-handle {
  height: var(--slider-handle-height, 16px);
  right: calc(var(--slider-handle-width, 16px) / 2 * -1);
  top: calc((var(--slider-handle-height, 16px) - var(--slider-height, 6px)) / 2 * -1 + -1px);
  width: var(--slider-handle-width, 16px)
}

.slider-vertical {
  height: var(--slider-vertical-height, 300px);
  width: var(--slider-height, 6px)
}

.slider-vertical .slider-handle {
  bottom: calc(var(--slider-handle-width, 16px) / 2 * -1);
  height: var(--slider-handle-width, 16px);
  right: calc((var(--slider-handle-height, 16px) - var(--slider-height, 6px)) / 2 * -1 + -1px);
  width: var(--slider-handle-height, 16px)
}

.slider-txt-dir-rtl.slider-horizontal .slider-handle {
  left: calc(var(--slider-handle-width, 16px) / 2 * -1);
  right: auto
}

.slider-base {
  background-color: $slider-track-bg
}

.slider-base, .slider-connects {
  border-radius: var(--slider-radius, 9999px)
}

.slider-connect {
  background: $slider-active-color;
  cursor: pointer
}

.slider-draggable {
  cursor: ew-resize
}

.slider-vertical .slider-draggable {
  cursor: ns-resize
}

.slider-handle {
  background: $slider-handler-bg;
  border: 2px solid $slider-active-color;
  border-radius: var(--slider-handle-radius, 9999px);
  box-shadow: var(--slider-handle-shadow, .5px .5px 2px 1px $shadow-color-strong);
  cursor: grab;
  height: var(--slider-handle-height, 16px);
  width: var(--slider-handle-width, 16px)
}

.slider-handle:focus {
  box-shadow: 0 0 0 var(--slider-handle-ring-width, 3px) $slider-handle-ring-color, var(--slider-handle-shadow, .5px .5px 2px 1px $shadow-color-strong);
  outline: none
}

.slider-active {
  box-shadow: var(--slider-handle-shadow-active, .5px .5px 2px 1px $shadow-color--active);
  cursor: grabbing
}

[disabled] .slider-connect {
  background: $slider-connect-bg--disabled
}

[disabled] .slider-handle, [disabled].slider-handle, [disabled].slider-target {
  cursor: not-allowed
}

[disabled] .slider-tooltip {
  background: $slider-tooltip-bg--disabled;
  border-color: $slider-tooltip-bg--disabled
}

.slider-tooltip {
  background: $slider-tooltip-bg;
  border: 1px solid $slider-tooltip-bg;
  border-radius: var(--slider-tooltip-radius, 5px);
  color: $slider-tooltip-color;
  display: block;
  font-size: var(--slider-tooltip-font-size, .875rem);
  font-weight: var(--slider-tooltip-font-weight, 600);
  line-height: var(--slider-tooltip-line-height, 1.25rem);
  min-width: var(--slider-tooltip-min-width, 20px);
  padding: var(--slider-tooltip-py, 2px) var(--slider-tooltip-px, 6px);
  position: absolute;
  text-align: center;
  white-space: nowrap
}

.slider-horizontal .slider-tooltip-top {
  bottom: calc(var(--slider-handle-height, 16px) + var(--slider-tooltip-arrow-size, 5px) + var(--slider-tooltip-distance, 3px));
  left: 50%;
  transform: translate(-50%)
}

.slider-horizontal .slider-tooltip-top::before {
  border: var(--slider-tooltip-arrow-size, 5px) solid transparent;
  border-top-color: inherit;
  bottom: calc(var(--slider-tooltip-arrow-size, 5px) * -2);
  content: "";
  height: 0;
  left: 50%;
  position: absolute;
  transform: translate(-50%);
  width: 0
}

.slider-horizontal .slider-tooltip-bottom {
  left: 50%;
  top: calc(var(--slider-handle-height, 16px) + var(--slider-tooltip-arrow-size, 5px) + var(--slider-tooltip-distance, 3px));
  transform: translate(-50%)
}

.slider-horizontal .slider-tooltip-bottom::before {
  border: var(--slider-tooltip-arrow-size, 5px) solid transparent;
  border-bottom-color: inherit;
  content: "";
  height: 0;
  left: 50%;
  position: absolute;
  top: calc(var(--slider-tooltip-arrow-size, 5px) * -2);
  transform: translate(-50%);
  width: 0
}

.slider-vertical .slider-tooltip-left {
  right: calc(var(--slider-handle-height, 16px) + var(--slider-tooltip-arrow-size, 5px) + var(--slider-tooltip-distance, 3px));
  top: 50%;
  transform: translateY(-50%)
}

.slider-vertical .slider-tooltip-left::before {
  border: var(--slider-tooltip-arrow-size, 5px) solid transparent;
  border-left-color: inherit;
  content: "";
  height: 0;
  position: absolute;
  right: calc(var(--slider-tooltip-arrow-size, 5px) * -2);
  top: 50%;
  transform: translateY(-50%);
  width: 0
}

.slider-vertical .slider-tooltip-right {
  left: calc(var(--slider-handle-height, 16px) + var(--slider-tooltip-arrow-size, 5px) + var(--slider-tooltip-distance, 3px));
  top: 50%;
  transform: translateY(-50%)
}

.slider-vertical .slider-tooltip-right::before {
  border: var(--slider-tooltip-arrow-size, 5px) solid transparent;
  border-right-color: inherit;
  content: "";
  height: 0;
  left: calc(var(--slider-tooltip-arrow-size, 5px) * -2);
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 0
}

.slider-horizontal .slider-origin > .slider-tooltip {
  left: auto;
  transform: translate(50%)
}

.slider-horizontal .slider-origin > .slider-tooltip-top {
  bottom: calc(var(--slider-tooltip-arrow-size, 5px) + (var(--slider-handle-height, 16px) - var(--slider-height, 6px)) / 2 + var(--slider-tooltip-distance, 3px) + 1px)
}

.slider-horizontal .slider-origin > .slider-tooltip-bottom {
  top: calc(var(--slider-tooltip-arrow-size, 5px) + (var(--slider-handle-height, 16px) - var(--slider-height, 6px)) / 2 + var(--slider-tooltip-distance, 3px) + var(--slider-height, 6px) - 1px)
}

.slider-vertical .slider-origin > .slider-tooltip {
  top: auto;
  transform: translateY(calc((var(--slider-tooltip-line-height, 1.25rem) - var(--slider-tooltip-py, 2px)) * -1 + 1px))
}

.slider-vertical .slider-origin > .slider-tooltip-left {
  right: calc(var(--slider-tooltip-arrow-size, 5px) + var(--slider-height, 6px) + (var(--slider-handle-height, 16px) - var(--slider-height, 6px)) / 2 + var(--slider-tooltip-distance, 3px) - 1px)
}

.slider-vertical .slider-origin > .slider-tooltip-right {
  left: calc(var(--slider-tooltip-arrow-size, 5px) + var(--slider-height, 6px) + (var(--slider-handle-height, 16px) - var(--slider-height, 6px)) / 2 + var(--slider-tooltip-distance, 3px) - var(--slider-height, 6px) + 1px)
}
</style>
