import React from 'react';
import PropTypes from 'prop-types';
import cn from 'classnames';
import { inRange, get, isString } from 'lodash';
import { action, observable } from 'mobx';
import { observer } from 'mobx-react';
import InputSlider from 'react-input-slider';
import CheckBox from 'grommet/components/CheckBox';
import Box from 'grommet/components/Box';

const NON_DIGIT = /\D/;

function getDigits(ev) {
    const val = get(ev, 'target.value', ev.x);
    if (isString(val) && (!val || NON_DIGIT.test(val))) { return null; }
    return parseInt(val, 10);
}

@observer
export default class TimeSelector extends React.PureComponent {
    static propTypes = {
        moment: PropTypes.object.isRequired,
        onChange: PropTypes.func.isRequired,
        minuteStep: PropTypes.number,
    }

    @observable isPM;
    @observable hour;
    @observable minutes;

    componentWillMount() {
        this.set(this.props);
    }

    componentWillReceiveProps(nextProps) {
        this.set(nextProps);
    }

    set(props) {
        this.isPM = !!(12 <= props.moment.hour());
        this.hour = (12 <= props.moment.hour()) ? props.moment.hour() - 12 : props.moment.hour();
        this.minutes = props.moment.minute();
    }

    @action.bound
    onHourChange(ev) {
        const d = getDigits(ev);
        const m = this.props.moment;
        if (inRange(d, 1, 13)) {
            m.hours(this.isPM ? d + 12 : d);
            this.hour = d;
        } else {
            this.hour = 0;
            m.hours(0);
        }
        this.props.onChange(m);
    }

    @action.bound
    onMinuteChange(ev) {
        const d = getDigits(ev);
        if (inRange(d, 0, 60)) {
            const m = this.props.moment;
            m.minutes(d);
            this.props.onChange(m);
            this.minutes = d;
        } else {
            this.minutes = 0;
        }
    }

    @action.bound
    toggleAMPM(ev) {
        this.isPM = ev.target.checked;
        this.props.moment.hours(this.isPM ? this.hour + 12 : this.hour);
        this.props.onChange(this.props.moment);
    }

    render() {
        const { hour, minutes } = this;

        return (
            <div className={cn('time-picker', this.props.className)}>
                <Box direction='row' className="showtime" justify="center" align="center">
                    <input className="hour" value={hour} onChange={this.onHourChange} />
                    <span className="separater">:</span>
                    <input className="minutes" value={minutes} onChange={this.onMinuteChange} />
                    <CheckBox
                        toggle
                        className="am-pm"
                        label='AM / PM'
                        checked={this.isPM}
                        onChange={this.toggleAMPM}
                    />
                </Box>

                <div className="sliders">
                    <div className="time-text">Hours:</div>
                    <InputSlider
                        className="u-slider-time"
                        xmin={1}
                        xmax={12}
                        step={this.props.minuteStep}
                        x={hour}
                        onChange={this.onHourChange}
                    />
                    <div className="time-text">Minutes:</div>
                    <InputSlider
                        className="u-slider-time"
                        xmin={0}
                        xmax={59}
                        x={minutes || 0}
                        onChange={this.onMinuteChange}
                    />
                </div>
            </div>
        );
    }
}