import React from 'react';
import DateRangePicker from 'react-daterange-picker';
import moment from 'moment';
import 'moment-range';
import reactMixin from 'react-mixin';
import OnClickOutside from 'react-onclickoutside';
import classNames from 'classnames';

/**
 * DatePicker
 * @classdesc Contains state/HTML rendering for date filters.
 * @extends React.Component
 * @class
 */
class DatePicker extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      visible: false,
      dateStart: props.dateStart ? moment(props.dateStart) : null,
      dateEnd: props.dateEnd ? moment(props.dateEnd) : null
    };

    this.handleClickOutside = this.handleClickOutside.bind(this);
  }

  componentWillReceiveProps(nextProps) {
    // This does not get called on first render so we need to set the state
    // in the constructor if there are initial props that could potentially be
    // the same as incoming props
    if (this.props.dateStart !== nextProps.dateStart) {
      this.setState({dateStart: (nextProps.dateStart ? moment(nextProps.dateStart) : null)});
    }
    if (this.props.dateEnd !== nextProps.dateEnd) {
      this.setState({dateEnd: (nextProps.dateEnd ? moment(nextProps.dateEnd) : null)});
    }
  }

  hidePicker() {
    this.setState({visible: false});
  }

  showPicker() {
    this.setState({visible: true});
  }

  togglePicker() {
    this.setState({visible: !this.state.visible});
  }

  handleClickOutside(e) {
    if (this.state.visible) {
      this.setState({visible: false});
    }
  }

  /**
   * Handles the preset date range on click events
   * @param  {Event} event  The event from the onClick event
   */
  handleDatePreset(event) {
    let start = null;
    let end = null;

    switch (event.target.getAttribute('data-preset')) {
    case 'this-week':
      start = moment().startOf('week');
      end = moment().endOf('week');
      break;

    case 'this-month':
      start = moment().startOf('month');
      end = moment().endOf('month');
      break;

    case 'last-month':
      start = moment().subtract(1, 'months').startOf('month');
      end = moment().subtract(1, 'months').endOf('month');
      break;

    case 'rolling-7-days':
      start = moment().subtract(7, 'days');
      end = moment();
      break;

    case 'rolling-30-days':
      start = moment().subtract(30, 'days');
      end = moment();
      break;

    case 'week-to-date':
      start = moment().startOf('week');
      end = moment();
      break;

    case 'today':
    case 'clear':
    default:
      start = moment();
      end = moment();
    }

    if (start !== null && end !== null) {
      this.changeDateRange(moment.range(start, end));
    }

    this.hidePicker();

    bzTrack.track('Calendar: DatePicker PresetSelected', {
      preset: event.target.getAttribute('data-preset')
    });
  }

  changeDateRange(range) {
    this.props.onChange(range.start.format('YYYY-MM-DD'), range.end.format('YYYY-MM-DD'));
    this.hidePicker();

    bzTrack.track('Calendar: DatePicker Date Changed', {
      start: range.start.format('YYYY-MM-DD'),
      end: range.end.format('YYYY-MM-DD')
    });
  }

  render() {
    const { dateStart, dateEnd, visible } = this.state;
    const pickerClasses = classNames('CalendarDate-picker', {visible: visible});

    const selectedRange = (dateStart && dateEnd) ? moment.range(dateStart, dateEnd) : false;
    const isSingleDay = (dateStart && dateEnd) ? dateStart.isSame(dateEnd) : false;
    let displayDate = 'Select a Date..';

    if (isSingleDay) {
      displayDate = dateStart.format('MM/DD/YYYY');
    } else {
      displayDate = dateStart ? dateStart.format('MM/DD/YYYY') : 'All';
      displayDate += ' - ';
      displayDate += dateEnd ? dateEnd.format('MM/DD/YYYY') : 'All';
    }

    return (
      <div className="CalendarDate">
        <span className="CalendarDate-display"
              onKeyDown={() => this.tabAway()}
              onFocus={() => this.showPicker()}
              onClick={() => this.togglePicker()}>{displayDate || 'Search by date'}</span>
        <div className={pickerClasses}>
            <DateRangePicker
                singleDateRange
                value={selectedRange}
                numberOfCalendars={2}
                onSelect={(range, state) => this.changeDateRange(range)} />
            <button className="CalendarDate-preset" data-preset="today" onClick={(e) => this.handleDatePreset(e)}>Today</button>
            <button className="CalendarDate-preset" data-preset="this-week" onClick={(e) => this.handleDatePreset(e)}>This Week</button>
            <button className="CalendarDate-preset" data-preset="this-month" onClick={(e) => this.handleDatePreset(e)}>This Month</button>
            <button className="CalendarDate-preset" data-preset="last-month" onClick={(e) => this.handleDatePreset(e)}>Last Month</button>
            <button className="CalendarDate-preset" data-preset="rolling-7-days" onClick={(e) => this.handleDatePreset(e)}>Trailing 7-day</button>
            <button className="CalendarDate-preset" data-preset="rolling-30-days" onClick={(e) => this.handleDatePreset(e)}>Trailing 30-day</button>
            <button className="CalendarDate-preset" data-preset="week-to-date" onClick={(e) => this.handleDatePreset(e)}>WTD</button>
            <button className="CalendarDate-preset" data-preset="clear" onClick={(e) => this.handleDatePreset(e)}>Clear</button>
        </div>
        <div className="CalendarDate__underlay" onClick={() => this.hidePicker()}></div>
      </div>
    );
  }
}

DatePicker.propTypes = {
  dateStart: React.PropTypes.string,
  dateEnd: React.PropTypes.string,
  onChange: React.PropTypes.func
};

reactMixin.onClass(DatePicker, OnClickOutside);
export default DatePicker;
