/**
 * imui.Monthpicker
 * @author hanjiang
 * @date 2017-02-18
 */

import React from 'react';
import ReactDom from 'react-dom';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import Align from 'rc-align';
import Picker from './Picker';
import MonthInput from './MonthInput';
import {
    getDayOfMonth,
    isSameDate,
} from '../../datepicker/lib/dateUtils';

const renderSubtreeIntoContainer = ReactDom.unstable_renderSubtreeIntoContainer;

class Monthpicker extends React.Component {
  static propTypes = {
    inline: PropTypes.bool, // 不依附Input标签，直接展示inline的calendar
    value: PropTypes.instanceOf(Date), // 当前选中的月份（具体几号无所谓）
    showPicker: PropTypes.bool, // 是否初始展示选择器
    initYear: PropTypes.instanceOf(Date), // 日期选择器打开时显示的日期所在月分
    minDate: PropTypes.instanceOf(Date), // 选择器允许选择的最小日期
    maxDate: PropTypes.instanceOf(Date), // 选择器允许选择的最大日期
    className: PropTypes.string, // 选择器自定义className
    showIcon: PropTypes.bool, // 是否在输入框中显示日历icon，仅在非inline模式下有效
    onChange: PropTypes.func, // 目标日期改变时的回调函数
    onChangeYear: PropTypes.func, // 切换年份时的回调函数
    disabled: PropTypes.bool, // 是否禁用datepicker操作
    dateFormat: PropTypes.string, // 输入框的输出格式 'YYYY-MM-DD'
    pickerZindex: PropTypes.number, // 非inline模式下选择器的z-index
  };

  static defaultProps = {
    inline: false,
    value: undefined,
    showPicker: false,
    onChange: () => {},
    onChangeYear: () => {},
    showIcon: true,
    dateFormat: 'YYYY年M月',
    disabled: false,
    initYear: getDayOfMonth(new Date()),
  };

  constructor(props) {
    super(props);
    this.changeState(this.props, true);
  }

  changeState(props, isInit = false) {
    const { value } = props;
    let stateTarget = {};

    if (isInit) {
      stateTarget = {
        selected: value && getDayOfMonth(value),
        show: this.props.showPicker,
      };
      this.state = stateTarget;
    } else {
      stateTarget = {
        show: this.props.showPicker,
      };

      if (value !== undefined) {
        stateTarget.selected = getDayOfMonth(value);
      }

      this.setState(stateTarget);
    }
  }

  handleScroll = () => {
    if (!this.props.inline) {
      if (this.state.show) {
        this.setState({
          show: false,
        });
      }
    }
  }

  handleClean = (event) => {
    if (this.props.disabled) {
      return;
    }

    this.setState({
      selected: undefined,
    });

    if (this.state.selected) {
      this.props.onChange(undefined, getDayOfMonth(this.state.selected));
    }
    event.stopPropagation();
  }

  renderPickerTobody() {
    const { inline } = this.props;

    if (!inline) { // 非inline模式下，需要将calendar渲染到body下，防止z-index问题
      renderSubtreeIntoContainer(this,
        <Align
          align={{
            points: ['tl', 'bl'],
            overflow: {
              adjustX: true,
              adjustY: true,
            },
          }}
          target={() => this.refs.monthInput.refs.inputWrap}
          monitorWindowResize
        >
          <Picker
            {...this.props}
            {...this.state}
            day={this.props.initYear}
            onSelect={this.handleSelect}
            eventTypes="click"
            disableOnClickOutside={!this.state.show}
            handleClickOutPicker={this.handleClickOutPicker}
          />
        </Align>, this.container
      );
    }
  }

  handleInputClick = () => {
    if (this.props.disabled) {
      return;
    }

    this.setState({
      show: !this.state.show,
    });
  }

  handleClickOutPicker = () => {
    this.setState({
      show: false,
    });
  }

  handleSelect = (date) => {
    const { disabled, onChange } = this.props;

    if (disabled) {
      return;
    }

    if (!isSameDate(date, this.state.selected)) { // 选择的日期有变动
      onChange(date, this.state.selected);
    }

    this.setState({
      show: false,
      selected: date,
    });
  }

  componentDidMount() {
    const body = document.body;
    const container = this.container = document.createElement('div');

    body.appendChild(container);
    this.renderPickerTobody();

    window.addEventListener('scroll', this.handleScroll);
    window.addEventListener('resize', this.handleScroll);
  }

  componentDidUpdate() {
    this.renderPickerTobody();
  }

  componentWillUnmount() {
    if (this.container) {
      ReactDom.unmountComponentAtNode(this.container);
    }

    window.removeEventListener('scroll', this.handleScroll);
    window.removeEventListener('resize', this.handleScroll);
  }

  render() {
    const { inline } = this.props;

    return (
      <div className={classnames('im-monthpicker', this.props.className)}>
        {inline ? <Picker
          {...this.props}
          {...this.state}
          day={this.props.initYear}
          onSelect={this.handleSelect}
          eventTypes="click"
          handleClickOutPicker={this.handleClickOutPicker}
          eventTypes="click"
          onSelect={this.handleSelect}
          disableOnClickOutside
          handleClickOutPicker={this.handleClickOutPicker}
        /> : <MonthInput
          {...this.props}
          {...this.state}
          ref="monthInput"
          handleClean={this.handleClean}
          onInputClick={this.handleInputClick}
        />}
      </div>
    );
  }
}

export default Monthpicker;

