'use client'

import { type ISliderProps } from '@/Types'
import { makeClassName } from '@/utils'
import * as Slider from '@radix-ui/react-slider'
import React, { useEffect, useState, type ReactElement } from 'react'
import Description from './Description'
import Label from './Label'
import { getDefaultThumbClass } from '@/Components/Inputs/sliderHelpers'

const validateValue = (value: number | undefined, min: number, max: number): number => {
  const newV = value === undefined
    ? min
    : value > max
      ? max
      : value < min
        ? min
        : value
  return newV
}

const SliderSingle = ({
  id,
  testId = 'slider',
  error,
  size = 'med',
  disabled = false,
  label,
  description,
  before,
  after,
  max = 100,
  min = 1,
  step = 1,
  value,
  onChange,
  onChangeComplete,
  defaultClassName = 'relative flex items-center select-none touch-none h-5',
  wrapperClassName,
  className,
  thumbClass,
  retainUndefinedOnLoad = false

}: ISliderProps): ReactElement => {
  const thumbDefaultClassName = getDefaultThumbClass(size)
  const [sliderValue, setSlidervalue] = useState<number | undefined>()
  const onSliderChange = (v: number[]): void => {
    const newV = validateValue(v[0], min, max)
    if (typeof onChange === 'function') {
      onChange(newV)
    }
    setSlidervalue(newV)
  }

  const onSliderChangeCommit = (v: number[]): void => {
    const newV = validateValue(v[0], min, max)
    if (typeof onChangeComplete === 'function') {
      onChangeComplete(newV)
    }
  }

  useEffect(() => {
    if (value === undefined && retainUndefinedOnLoad) {
      setSlidervalue(validateValue(value, min, max))
    } else {
      const newVal = validateValue(value, min, max)
      setSlidervalue(newVal)
      if (newVal !== value) {
        onSliderChange([newVal])
        onSliderChangeCommit([newVal])
      }
    }
  }, [value])

  return (
    <div className={wrapperClassName}>
      {
        typeof label === 'string'
          ? <Label disabled={disabled} label={label} />
          : label !== undefined ? label : ''
      }
      {
        typeof description === 'string'
          ? <Description disabled={disabled} description={description} />
          : description !== undefined ? description : ''
      }
      {before !== undefined ? before : ''}
      <Slider.Root
        className={makeClassName({
          defaultClassName,
          className,
          extras: [
            disabled ? 'cursor-not-allowed opacity-50' : undefined
          ]
        })}
        disabled={disabled}
        defaultValue={[validateValue(value, min, max)]}
        value={sliderValue !== undefined ? [sliderValue] : undefined}
        min={min}
        max={max}
        step={step}
        minStepsBetweenThumbs={1}
        onValueChange={onSliderChange}
        onValueCommit={onSliderChangeCommit}
      >
        <Slider.Track className={
          makeClassName({
            className: 'bg-slate-400 relative grow rounded-full h-[3px]',
            extras: [
              disabled ? 'cursor-not-allowed opacity-50' : undefined
            ]
          })
        }>
          <Slider.Range className="absolute bg-blue-400 rounded-full h-full" />
        </Slider.Track>
        <Slider.Thumb
          className={makeClassName({
            defaultClassName: thumbDefaultClassName,
            className: thumbClass,
            extras: [
              disabled ? 'cursor-not-allowed opacity-80' : ''
            ]
          })}
          aria-label="Value"
        />
      </Slider.Root>
      {after !== undefined ? after : ''}
    </div>
  )
}

export default SliderSingle
