/**
 * imui.Datepicker - DateInput
 * @author riverhan
 * @data 2016-8-10
 */
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import {
  isDayInMonth,
  isSameDate,
  compareDate,
  isDateInRange,
  getMode,
  isRangeMode,
  isWaitForSecondDay,
  findDate,
} from './dateUtils';

class Day extends React.Component {
  static propTypes = {
    day: PropTypes.object.isRequired,
    monthDay: PropTypes.object.isRequired,
    onDayClick: PropTypes.func.isRequired,
    onDayHover: PropTypes.func,
    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 = {
    day: new Date(),
    monthDay: new Date(),
  };

  getClickHandle = (disabled) => {
    return () => {
      if (!disabled) {
        this.props.onDayClick(this.props.day);
      }
    };
  };

  getHoverHandle = (disabled) => {
    if (disabled || typeof this.props.onDayHover !== 'function') {
      return () => { };
    }

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

  render() {
    const { day, monthDay, weekMode,
      selected, selectedRange, maySelectedRange,
      minDate, maxDate, highLightDates, onlyEnableHighLightDate } = this.props;
    const mode = getMode(this.props.mode, weekMode);
    const showDay = isDayInMonth(day, monthDay);
    const disabled = (minDate && compareDate(day, minDate) < 0)
      || (maxDate && compareDate(day, maxDate) > 0)
      || onlyEnableHighLightDate && !findDate(highLightDates, day);
    // 正在等待第二个日期的选择
    const isMaySelected = isWaitForSecondDay(mode, selected, selectedRange) && isDateInRange(day, maySelectedRange);

    // 选中日期
    let isSelected = false;
    if (!isMaySelected) {
      isSelected = isRangeMode(mode) && isDateInRange(day, selectedRange) || isSameDate(day, this.props.selected);
    }

    const isToday = isSameDate(day, new Date());
    const isSelectedRange = isSelected && isRangeMode(mode);
    const isMaySelectedFirst = isMaySelected && isSameDate(day, maySelectedRange.from);
    const isMaySelectedLast = isMaySelected && isSameDate(day, maySelectedRange.to);
    const isSelectedRangeFirst = isSelectedRange && isSameDate(day, selectedRange.from);
    const isSelectedRangeLast = isSelectedRange && isSameDate(day, selectedRange.to);

    return (
      <span
        className={classnames({
          'im-dp-day': true,
          'im-dp-day--unvisual': !showDay && !weekMode,
          'im-dp-day--highlight': findDate(highLightDates, day),
          selected: isSelected,
          'selected--range': isMaySelected || isSelectedRange,
          'selected--range--first': isMaySelectedFirst || isSelectedRangeFirst,
          'selected--range--last': isMaySelectedLast || isSelectedRangeLast,
          today: isToday,
          disabled,
        })}
        onClick={this.getClickHandle(disabled)}
        onMouseOver={this.getHoverHandle(disabled)}
      >
        {day.getDate()}
      </span>
    );
  }
}

export default Day;
