import ReactSlider from 'react-slider'

import { Box } from '../box'
import { styled, useStyleConfig, vui } from '../core'
import { Tooltip } from '../tooltip'
import { cs, filterUndefined } from '../utils'
import { rangeColors } from './consts'
import { RangeProps, RangeTrackKey } from './range.types'

const SliderBase = styled(ReactSlider)`
  width: 100%;
  height: 4px;
  cursor: pointer;
  transition-duration: '0s';
`

const defaultFormatter = (value: string) => `${value}`

/** Implements a range input. */
export const Range = vui<'div', RangeProps>((props, ref) => {
  const {
    className,
    value,
    defaultValue = 0,
    disabled,
    min = 0,
    minDistance = 0,
    max = 100,
    step = 1,
    showTooltip = false,
    showValue = false,
    formatter = defaultFormatter,
    onChange,
    ...rest
  } = props

  const styles = useStyleConfig('Range', props)
  const aliasedProps = filterUndefined({
    'aria-disabled': disabled,
  })
  const isSingleValue = typeof defaultValue !== 'object' && typeof value !== 'object'
  const mainColor = disabled ? rangeColors.disabled : rangeColors.main

  const getTrackColor = (trackProps: any) => {
    const { key } = trackProps

    if (isSingleValue) return key === RangeTrackKey.First ? mainColor : rangeColors.track

    return key === RangeTrackKey.Third
      ? rangeColors.track
      : key === RangeTrackKey.Second
        ? mainColor
        : rangeColors.track
  }

  const Thumb = (props: any, state: any) => {
    const content = (
      <Box className="vui-range-thumb" {...styles.thumb} borderColor={mainColor} {...props}>
        {showValue && (
          <Box center className="vui-range-thumb-value" {...styles.thumbValue}>
            {formatter(state.valueNow)}
          </Box>
        )}
      </Box>
    )
    return showValue ? (
      content
    ) : (
      <Tooltip disabled={disabled} text={formatter(state.valueNow)} visible={showTooltip}>
        {content}
      </Tooltip>
    )
  }

  const Track = (
    props: any,
    state: {
      index: number
      value: number | readonly number[]
    },
  ) => <Box {...styles.track} bg={getTrackColor(props)} className="vui-range-track" {...props} index={state.index} />

  return (
    <Box
      className={cs('vui-range', isSingleValue ? 'vui-range-single' : 'vui-range-range', className)}
      ref={ref}
      {...styles.container}
      {...aliasedProps}
      {...rest}
    >
      <SliderBase
        className="vui-range-slider"
        defaultValue={defaultValue}
        disabled={disabled}
        max={max}
        min={min}
        minDistance={minDistance}
        onChange={onChange}
        renderThumb={Thumb}
        renderTrack={Track}
        step={step}
        value={value}
      />
    </Box>
  )
})

Range.displayName = 'Range'
export default Range
