import './style/modal_portal.less';
import { Component } from 'inferno';

export class ModalPortal extends Component<any, any> {

  private timerInstance;

  public static defaultProps = {
    isOpen: false,
    onMask: () => { console.log('on Mask...'); },
    className: '',
    closeByMask: false,
    onBeforeOpen: () => { console.log(); },
    onAfterOpen: () => { console.log(); },
    onRequestClose: () => { console.log(); },
    onAfterClosed: () => { console.log(); },
  };

  public componentWillMount() {
    if (this.props.isOpen) {
      this.open();
    }
    if (this.props.onModalReady) {
      this.props.onModalReady(this);
    }
  }

  public handleMask = () => {
    this.props.onMask();
  }

  public state = {
    // init & opened & startClose & init
    status: 'init',
    _isClose: false,
    isOpen: false,
  };

  public componentWillReceiveProps(props) {
    const status = this.state.status;
    if (status === 'opened' && !props.isOpen) {
      this.close();
    } else if (status === 'init' && props.isOpen) {
      this.open();
    }

  }

  public open() {
    this.props.onBeforeOpen();
    this.setState({ status: 'opened' }, () => {
      setTimeout(() => {
        this.props.onAfterOpen();
      }, 150);
    });
  }

  public close(callback?) {
    this.props.onRequestClose();
    this.setState({ status: 'startClose' }, () => {
      this.timerInstance = setTimeout(() => {
        this.setState({
          status: 'init',
        });
        if (callback) callback();
        this.props.onAfterClosed();
      }, 150);
    });
  }

  public render() {
    const state = this.state;
    const cn: string[] = [this.props.className];
    if (state.status === 'opened') {
      cn.push('mp-open');
    }
    if (state.status === 'startClose') {
      cn.push('mp-close');
    }
    return (
      'opened_startClose'.indexOf(state.status) >= 0 ? (
        <div className={cn.join(' ')} c-modal-portal>
          <div className="mp-mask" onClick={this.handleMask}></div>
          <div className="mp-content">
            {this.props.children}
          </div>
        </div>
      ) : null
    );
  }

  public componentWillUnmount() {
    if (this.timerInstance) {
      clearTimeout(this.timerInstance);
    }
  }
}
