import classNames from 'classnames';
import Datepicker from 'react-datepicker';
import moment from 'moment';
import React, { PropTypes } from 'react';

import HourSelect from './HourSelect';
import { dateHasErrors } from '../../utils/validations.js';
import { HOUR_FORMAT } from './hourOptions';

const defaultProps = {
  min: moment().subtract(3, 'months'),
  max: moment().add(1, 'years'),
  from: moment(),
  to: moment(),
  showMinTime: false,
  showMaxTime: false,
};

const propTypes = {
  theme: PropTypes.oneOfType([
    PropTypes.object,
    PropTypes.func,
  ]).isRequired,
  onChange: PropTypes.func,
  min: PropTypes.object,
  max: PropTypes.object,
  showMonthDropdown: PropTypes.bool,
  showYearDropdown: PropTypes.bool,
  from: PropTypes.object,
  to: PropTypes.object,
  showMinTime: PropTypes.bool,
  showMaxTime: PropTypes.bool,
};

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

    this.state = {
      from: this.props.from,
      to: this.props.to,
    };
  }

  onChange(bound, value) {
    const { from, to } = this.state;
    if (dateHasErrors(value, this.props.min, this.props.max)) {
      this.setState({ [bound]: null });
    } else {
      this.setState({ [bound]: value });
    }
    if (bound === 'from') {
      this.props.onChange([value, to]);
    } else {
      this.props.onChange([from, value]);
    }
  }

  onHourChange = (input) => {
    return (hourString) => {
      if (hourString) {
        const { from, to } = this.state;
        const involvedDate = input === 'from' ? from : to;
        const hour = moment(hourString, HOUR_FORMAT).hour();
        involvedDate.hour(hour);

        this.props.onChange([from, to]);
      }
    };
  }

  render() {
    const { min, max, theme } = this.props;
    const { from, to } = this.state;

    const fromHour = from ? from.format(HOUR_FORMAT) : null;
    const toHour = to ? to.format(HOUR_FORMAT) : null;
    const dateFormat = this.props.showYearDropdown ? 'MM/DD/YYYY' : 'MM/DD';

    return (
      <div className={classNames('o-layout', theme['o-layout'])}>
        <div className={classNames('u-1/2', 'o-layout__item', theme['u-1/2'], theme['o-layout__item'])}>
          <div className={classNames('o-layout', theme['o-layout'])}>
            <div
              className={
                classNames(
                  'o-layout__item',
                  {
                    'u-3/4': this.props.showMinTime,
                    'u-1/1': !this.props.showMinTime,
                  },
                  theme['o-layout__item'],
                  {
                    [theme['u-3/4']]: this.props.showMinTime,
                    [theme['u-1/1']]: !this.props.showMinTime,
                  }
                )
              }
            >
              <Datepicker
                className={classNames('c-kd__input', theme['c-kd__input'])}
                selected={from}
                onChange={this.onChange.bind(this, 'from')}
                showMonthDropdown={this.props.showMonthDropdown}
                dropdownMode="select"
                showYearDropdown={this.props.showYearDropdown}
                scrollableYearDropdown
                minDate={min}
                maxDate={max}
                dateFormat={dateFormat}
                placeholderText={dateFormat}
              />
            </div>
            {
              (() => {
                if (this.props.showMinTime) {
                  return (
                    <div
                      className={
                        classNames(
                          'u-1/4',
                          'o-layout__item',
                          theme['u-1/4'],
                          theme['o-layout__item'],
                        )
                      }
                    >
                      <HourSelect
                        theme={theme}
                        onChange={this.onHourChange('from')}
                        selected={fromHour}
                      />
                    </div>
                  );
                }

                return null;
              })()
            }
          </div>
        </div>
        <div
          className={
            classNames(
              'u-1/2',
              'o-layout__item',
              theme['u-1/2'],
              theme['o-layout__item'],
            )
          }
        >
          <div className={classNames('o-layout', theme['o-layout'])}>
            <div
              className={
                classNames(
                  'o-layout__item',
                  {
                    'u-3/4': this.props.showMaxTime,
                    'u-1/1': !this.props.showMaxTime,
                  },
                  theme['o-layout__item'],
                  {
                    [theme['u-3/4']]: this.props.showMaxTime,
                    [theme['u-1/1']]: !this.props.showMaxTime,
                  },
                )
              }
            >
              <Datepicker
                className={classNames('c-kd__input', theme['c-kd__input'])}
                selected={to}
                onChange={this.onChange.bind(this, 'to')}
                showMonthDropdown={this.props.showMonthDropdown}
                dropdownMode="select"
                showYearDropdown={this.props.showYearDropdown}
                scrollableYearDropdown
                minDate={min}
                maxDate={max}
                dateFormat={dateFormat}
                placeholderText={dateFormat}
              />
            </div>
            {
              (() => {
                if (this.props.showMaxTime) {
                  return (
                    <div
                      className={
                        classNames(
                          'u-1/4',
                          'o-layout__item',
                          theme['u-1/4'],
                          theme['o-layout__item'],
                        )
                      }
                    >
                      <HourSelect
                        theme={theme}
                        onChange={this.onHourChange('to')}
                        selected={toHour}
                      />
                    </div>
                  );
                }

                return null;
              })()
            }
          </div>
        </div>
      </div>
    );
  }
}

BetweenDatepicker.defaultProps = defaultProps;
BetweenDatepicker.propTypes = propTypes;

export default BetweenDatepicker;
