import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import { IconChevronUpSmallOutline, IconChevronDownSmallOutline } from '@teamleader/ui-icons';
import Icon from '../icon';
import InputBase from './InputBase';
import theme from './theme.css';

class SpinnerControls extends PureComponent {
  render() {
    const { inverse, handleOnSpinnerUpClick, handleOnSpinnerDownClick } = this.props;
    const iconProps = {
      color: inverse ? 'teal' : 'neutral',
      element: 'button',
      tint: inverse ? 'lightest' : 'darkest',
    };

    return (
      <div className={theme['spinner']}>
        <Icon className={theme['spinner-up']} onClick={handleOnSpinnerUpClick} {...iconProps}>
          <IconChevronUpSmallOutline />
        </Icon>
        <Icon className={theme['spinner-down']} onClick={handleOnSpinnerDownClick} {...iconProps}>
          <IconChevronDownSmallOutline />
        </Icon>
      </div>
    );
  }
}

class NumericInput extends PureComponent {
  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.value !== undefined) {
      const newValue = nextProps.value || '';
      if (newValue !== prevState.value) {
        return {
          value: newValue,
        };
      }
    }
    return null;
  }

  state = {
    value: '',
  };

  handleOnChange = event => {
    this.setState({ value: this.parseValue(event.currentTarget.value) });
  };

  updateStep = n => {
    const { step } = this.props;

    const currentValue = this.toNumber(this.state.value || 0);
    const newValue = this.parseValue(currentValue + step * n);

    if (newValue !== currentValue) {
      this.setState({ value: newValue });
    }
  };

  parseValue = value => this.bindToMinMax(this.toNumber(value));

  toNumber = number => {
    let float = parseFloat(number);
    if (isNaN(float) || !isFinite(float)) {
      float = 0;
    }
    return float;
  };

  bindToMinMax = value => {
    const { min, max } = this.props;
    return Math.min(Math.max(value, min), max);
  };

  handleIncreaseValue = () => {
    this.updateStep(1);
  };

  handleDecreaseValue = () => {
    this.updateStep(-1);
  };

  getSuffixWithSpinner = () => [
    ...this.props.suffix,
    <SpinnerControls
      handleOnSpinnerUpClick={this.handleIncreaseValue}
      handleOnSpinnerDownClick={this.handleDecreaseValue}
    />,
  ];

  render() {
    const { spinner, suffix, onChange, ...others } = this.props;

    return (
      <InputBase
        type="number"
        value={this.state.value}
        suffix={spinner ? this.getSuffixWithSpinner() : suffix}
        onChange={event => {
          this.handleOnChange(event);
          onChange && onChange(event, event.currentTarget.value);
        }}
        {...others}
      />
    );
  }
}

NumericInput.propTypes = {
  /** Sets a class name for the wrapper to give custom styles. */
  className: PropTypes.string,
  /** The maximum value that can be inputted */
  max: PropTypes.number,
  /** The minimum value that can be inputted */
  min: PropTypes.number,
  /** Boolean indicating whether to number type input should render spinner controls */
  spinner: PropTypes.bool,
  /** Limit increment value for numeric inputs. */
  step: PropTypes.number,
};

NumericInput.defaultProps = {
  min: Number.MIN_SAFE_INTEGER,
  max: Number.MAX_SAFE_INTEGER,
  step: 1,
  suffix: [],
  spinner: true,
};

export default NumericInput;

@@ -1766,17 +1766,20 @@
 umber = 
-n
+rawN
 umber =%3E
@@ -1789,21 +1789,22 @@
     let 
-float
+number
  = parse
@@ -1809,17 +1809,20 @@
 seFloat(
-n
+rawN
 umber);%0A
@@ -1835,21 +1835,22 @@
  (isNaN(
-float
+number
 ) %7C%7C !is
@@ -1856,21 +1856,22 @@
 sFinite(
-float
+number
 )) %7B%0A   
@@ -1873,21 +1873,22 @@
 %7B%0A      
-float
+number
  = 0;%0A  
@@ -1906,13 +1906,14 @@
 urn 
-float
+number
 ;%0A  

Rename variables to peter represent their value