'use strict';

import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import validator from 'validator';
import ButtonGroup from 'react-bootstrap/lib/ButtonGroup';
import {FormControl} from './FormControl';
import {TextInputControl} from './TextInputControl';
import {KeyCodes} from '../../../utils/constants';
import {Button} from '../Button';
import {Icon} from '../Icon';

const Natural_Number_Regex = /^[0-9]+$/;
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER || 9007199254740991;

export class InputCounterControl extends FormControl {
    static propTypes = {
        ...FormControl.propTypes,
        maxLength: PropTypes.number,
        minValue: PropTypes.number,
        maxValue: PropTypes.number,
        decreaseLabel: PropTypes.string,
        increaseLabel: PropTypes.string
    };

    static defaultProps = {
        ...FormControl.defaultProps,
        testAutomationId: 'inputCounter',
        maxLength: String(MAX_SAFE_INTEGER).length,
        minValue: 0,
        maxValue: MAX_SAFE_INTEGER,
        decreaseLabel: 'TRANSLATE:DECREASE',
        increaseLabel: 'TRANSLATE:INCREASE'
    };

    getValue() {
        return this.refs.input.getValue();
    }

    setValue(value) {
        let {...props} = this.getPropsFromContext();
        props.onChange(this.getValidatedValue(value));
    }

    getInputDOMNode() {
        return this.refs.input.getInputDOMNode();
    }

    getValidatedValue(value) {
        let minValue = this.props.minValue;
        let maxValue = this.props.maxValue;
        let isValid = validator.isInt(value, {
            min: minValue,
            max: maxValue
        });

        if (isValid) {
            return value;
        } else {
            if (value < minValue || value === '') {
                return minValue;
            }

            if (value > maxValue) {
                return maxValue;
            }
        }
    }

    onTextInputChange(e) {
        let {...props} = this.getPropsFromContext();
        let value = e.target.value;
        const isNaturalNumber = Natural_Number_Regex.test(value);

        if (isNaturalNumber || value === '') {
            if (isNaturalNumber) {
                value = parseInt(value, 10);
            }
            props.onChange(value);
        }
    }

    onTextInputBlur() {
        this.setValue(this.getValue());
    }

    onTextInputKeyDown = e => {
        if (e.keyCode === KeyCodes.ARROW_UP || e.keyCode === KeyCodes.ARROW_DOWN) {
            if (e.keyCode === KeyCodes.ARROW_UP) {
                this.increment();
            } else {
                this.decrement();
            }
            e.preventDefault();
        }
        e.stopPropagation();
    };

    increment() {
        this.setValue(Number(this.getValue()) + 1);
    }

    decrement() {
        this.setValue(Number(this.getValue()) - 1);
    }

    render() {
        let {testAutomationId, decreaseLabel, increaseLabel, ...props} = this.getPropsFromContext();
        let inputCounterClassNames = classnames('input-counter');

        return (
            <ButtonGroup
                className={inputCounterClassNames}
                data-test-automation-id={
                    this.props.hasFormGroupContainer ? undefined : testAutomationId
                }>
                <Button
                    testAutomationId="decrementButton"
                    className="decrement-button"
                    onClick={this.decrement.bind(this)}
                    aria-label={decreaseLabel}
                    tabIndex="-1"
                    disabled={props.value <= this.props.minValue}>
                    <Icon name="checkbox-mix-readonly" />
                </Button>
                <TextInputControl
                    {...props}
                    className="value"
                    ref="input"
                    role="spinbutton"
                    aria-valuenow={props.value}
                    aria-valuemin={props.minValue}
                    aria-valuemax={props.maxValue}
                    min={props.minValue}
                    max={props.maxValue}
                    onChange={this.onTextInputChange.bind(this)}
                    onKeyDown={this.onTextInputKeyDown}
                    onBlur={this.onTextInputBlur.bind(this)}
                />
                <Button
                    testAutomationId="incrementButton"
                    className="increment-button"
                    onClick={this.increment.bind(this)}
                    aria-label={increaseLabel}
                    tabIndex="-1"
                    disabled={props.value >= this.props.maxValue}>
                    <Icon name="add-big" />
                </Button>
            </ButtonGroup>
        );
    }
}
