import clamp from 'lodash.clamp';
import React from 'react';
import Slider from 'rc-slider';

import { numberHasErrors, isNumber } from '../../utils/validations.js';
import { buildOptionLabel } from '../KdSelectNumber/options';

const Input = ({ value, onChange, name }) => {
  return (
    <input
      className="o-kd-autocomplete c-kd-slider__input c-kd__input"
      name={name}
      type="text"
      value={value}
      onChange={onChange}
    />
  );
};

class KdSlider extends React.Component {
  constructor(props) {
    super(props);

    this.prepareSlider(props);
    this.onSliderChange = this.onSliderChange.bind(this);
    this.onInputChange = this.onInputChange.bind(this);
    this.renderLabel = this.renderLabel.bind(this);
  }

  componentDidMount() {
    this.props.onSelectedValue(this.state.sliderValues);
  }

  prepareSlider() {
    const { min, max, values } = this.props;

    const oneThirdSlider = Math.floor((max - min) / 3);
    const start = values[0] || oneThirdSlider;
    const end = values[1] || oneThirdSlider * 2;

    this.state = { start, end, sliderValues: [start, end] };
  }

  onSliderChange(sliderValues) {
    this.props.onSelectedValue(sliderValues);
    this.setState({ start: sliderValues[0], end: sliderValues[1], sliderValues });
  }

  onInputChange({ target }) {
    const { value, name } = target;
    const { min, max } = this.props;
    const { start, end, sliderValues } = this.state;
    let valueToCheck = value;

    if (name  === 'start') {
      valueToCheck = [value, end];
    } else if (name === 'end') {
      valueToCheck = [start, value];
    }
    const errors = numberHasErrors(valueToCheck, min, max);
    if (errors) {
      this.props.onError({ errors });
      this.setState({ [name]: value });

    } else {
      const nextState = Object.assign({}, this.state, { [name]: value });
      const sliderValues = this.safetyValues(nextState);

      this.props.onSelectedValue(sliderValues);
      this.setState({ [name]: value, sliderValues });
    }


  }

  safetyValues({ start, end, sliderValues }) {
    let newValues = sliderValues;
    let newStart = this.clampSliderValue(start);
    const newEnd = this.clampSliderValue(end);

    if (newStart > newEnd) {
      newStart = newEnd;
    }

    if (isNumber(newStart)) {
      newValues[0] = newStart;
    }

    if (isNumber(newEnd)) {
      newValues[1] = newEnd;
    }

    return newValues;
  }

  clampSliderValue(value) {
    return clamp(value, this.props.min, this.props.max);
  }

  renderLabel() {
    const { slider: { label: { visible, handler } } } = this.props;
    if (!visible) {
      return null;
    }

    const label = buildOptionLabel({
      value: this.state.sliderValues,
      operator: 'Between',
      handler,
      unit: this.props.unit,
    });
    return (
      <span className="c-kd-slider__label">
        {label}
      </span>
    );
  }

  render() {
    const { start, sliderValues, end } = this.state;
    return (
      <div className="c-kd-select-number__slider">
        {this.renderLabel()}
        <Input
          value={start}
          onChange={this.onInputChange}
          name={'start'}
        />
        <Slider
          range
          allowCross={false}
          onChange={this.onSliderChange}
          value={sliderValues}
          min={this.props.min}
          max={this.props.max}
        />
        <Input
          value={end}
          onChange={this.onInputChange}
          name={'end'}
        />
      </div>
    );
  }
}

KdSlider.defaultProps = {
  min: 0,
  max: 100,
  values: [],
};

export default KdSlider;
