<template>
  <div ref="slider"
    :class="[getModifiersClass('o-range-slider', modifiers), { 'o-range-slider--single': !secondValue }]">
    <div class="o-range-slider__minmax">
      <div class="o-range-slider__minmax-placeholder">
        <input type="number" :step v-model="sliderFirstValue" />
      </div>
      <div class="o-range-slider__minmax-placeholder">
        <input v-if="secondValue" type="number" :step v-model="sliderSecondValue" />
      </div>
    </div>
    <div class="o-range-slider__minmax-indicator"></div>

    <input ref="inputMin" type="range" name="min" id="min" :min :max :step :value="sliderFirstValue" @input="onInput" />
    <input v-if="secondValue" ref="inputMax" type="range" name="max" id="max" :min :max :step :value="sliderSecondValue"
      @input="onInput" />
  </div>
</template>

<script setup lang="ts">
import type { ModifierItems } from './loader.config';
import { ref, useTemplateRef, watch } from "vue";
import useComponentModifiers from '../../composable/useComponentModifiers';

const { getModifiersClass } = useComponentModifiers();

const props = withDefaults(
  defineProps<{
    min?: number;
    max?: number;
    step?: number;
    firstValue?: number;
    secondValue?: number;
    modifiers?: ModifierItems;
  }>(),
  {
    max: 100,
    min: 0,
    step: 1,
    firstValue: 0,
  });

// define emits for the slider component
const emit = defineEmits(["update:firstValue", "update:secondValue"]);

// define refs for the slider element and the slider values
const slider = useTemplateRef("slider");
const inputMin = useTemplateRef("inputMin");
const inputMax = useTemplateRef("inputMax");
const sliderFirstValue = ref<number>(props.firstValue);
const sliderSecondValue = ref<number>(props.secondValue);

// function to get the percentage of a value between the min and max values
const getPercent = (value: number, min: number, max: number): number => {
  return ((value - min) / (max - min)) * 100;
};

// function to set the css variables for width, left and right
const setCSSProps = (left: number, right: number) => {
  slider.value.style.setProperty("--progressLeft", `${left}%`);
  slider.value.style.setProperty("--progressRight", `${right}%`);
};

// listen for changes in the slider values
watch(
  [sliderFirstValue, sliderSecondValue],
  ([newFirstValue, newSecondValue]) => {
    if (slider.value) {
      // emit slidet values when updated
      emit("update:firstValue", newFirstValue);
      emit("update:secondValue", newSecondValue);

      // calculate values in percentages
      const leftPercent = getPercent(newFirstValue, props.min, props.max);
      const rightPercent = 100 - getPercent(newSecondValue, props.min, props.max);

      // set the CSS variables
      setCSSProps(leftPercent, rightPercent);
    }
  }
);

// validation sliderMinValue do not greater than sliderMaxValue and opposite
const onInput = ({ target }: any): void => {
  if (target.name === 'min') {
    target.value > sliderSecondValue.value
      ? target.value = sliderSecondValue.value
      : sliderFirstValue.value = parseFloat(target.value);
  }

  if (target.name === 'max') {
    target.value < sliderFirstValue.value
      ? target.value = sliderFirstValue.value
      : sliderSecondValue.value = parseFloat(target.value);
  }
};
</script>