/**
 * imui.Datepicker - Calendar
 * @author riverhan
 * @data 2016-8-10
 */
import React from 'react';
import classnames from 'classnames';
import PropTypes from 'prop-types';
import Month from './Month';
import MonthOper from './MonthOper';
import WeekTh from './WeekTh';
import { getPureDate, getDayOfNextMonth, getDayOfLastMonth, MODE, getMode } from './dateUtils';

let onClickOutside = require('react-onclickoutside');

class Calendar extends React.Component {
  static propTypes = {
    selected: PropTypes.object,
    day: PropTypes.object,
    onSelect: PropTypes.func.isRequired,
    onDayHover: PropTypes.func,
    show: PropTypes.bool.isRequired,
    handleClickOutPicker: PropTypes.func.isRequired,
    handleChangeMonth: PropTypes.func,
    inline: PropTypes.bool,
    left: PropTypes.number,
    top: PropTypes.number,
    zIndex: PropTypes.number,
    weekMode: PropTypes.bool,
    mode: PropTypes.string,
    selectedRange: PropTypes.shape({ // 当前选中的日期范围,为两个元素的数组
      from: PropTypes.instanceOf(Date),
      to: PropTypes.instanceOf(Date),
    }),
    maySelectedRange: PropTypes.shape({ // 当前选中的日期范围,为两个元素的数组
      from: PropTypes.instanceOf(Date),
      to: PropTypes.instanceOf(Date),
    }),
    highLightDates: PropTypes.array, // 高亮的日期
    onlyEnableHighLightDate: PropTypes.bool, // 仅高亮的日期可以选中
  };

  static defaultProps = {
    selected: undefined,
    day: new Date(),
    show: false,
    handleChangeMonth: () => {
    },
    inline: false,
  };

  state = {
    date: getPureDate(this.props.day),
  };

  componentWillReceiveProps(nextProps) {
    if (nextProps.day.valueOf() !== this.props.day.valueOf()) {
      this.setState({
        date: getPureDate(nextProps.day),
      });
    }
  }

  increaseMonth = () => {
    const nextMonthDate = getDayOfNextMonth(this.state.date);

    this.setState({
      date: nextMonthDate,
    });
    this.props.handleChangeMonth(new Date(nextMonthDate), new Date(this.state.date));
  };

  decreaseMonth = () => {
    const prevMonthDate = getDayOfLastMonth(this.state.date);

    this.setState({
      date: prevMonthDate,
    });
    this.props.handleChangeMonth(new Date(prevMonthDate), new Date(this.state.date));
  };

  handleDayClick = (day) => {
    this.props.onSelect(day);
  };

  handleDayHover = (day) => {
    if (this.props.onDayHover) {
      this.props.onDayHover(day);
    }
  };

  handleClickOutside = () => {
    this.props.handleClickOutPicker();
  };

  render() {
    const { inline, zIndex, weekMode } = this.props;
    const mode = getMode(this.props.mode, weekMode);
    let styleObj = {};

    if (zIndex) {
      styleObj.zIndex = zIndex;
    }

    return (
      <div
        className={classnames({
          'im-dp-calendar': true,
          'im-dp-calendar--inline': inline,
          hide: !this.props.show && !inline,
          'im-dp-calendar--week': mode === MODE.week,
        })}
      >
        <MonthOper
          day={this.state.date}
          onClickNextMonth={this.increaseMonth}
          onClickPrevMonth={this.decreaseMonth}
        />
        <WeekTh />
        <Month
          selected={this.props.selected}
          day={this.state.date}
          onDayClick={this.handleDayClick}
          onDayHover={this.handleDayHover}
          minDate={this.props.minDate}
          maxDate={this.props.maxDate}
          weekMode={this.props.weekMode}
          mode={mode}
          selectedRange={this.props.selectedRange}
          maySelectedRange={this.props.maySelectedRange}
          highLightDates={this.props.highLightDates}
          onlyEnableHighLightDate={this.props.onlyEnableHighLightDate}
        />
      </div>
    );
  }
}

export default onClickOutside(Calendar);
