/**
 * imui.PopWrap
 * @author shirlyzhang
 * @date 2016-08-18
 */
import React, { Component } from 'react';
import ReactDom from 'react-dom';
import Align from 'rc-align';
import PropTypes from 'prop-types';
import Popconfirm from './Popconfirm';
import placements from './placements';
// @require '../style/index.scss'

const renderSubtreeIntoContainer = ReactDom.unstable_renderSubtreeIntoContainer;

export default class PopWrap extends Component {
  static propTypes = {
    /**
     * 是否内联，默认挂载到body上,注意： 非内联时必须用getTarget方法提供气泡框目标元素
     */
    inline: PropTypes.bool,
    /**
     * 是否可见
     */
    visible: PropTypes.bool,
    /**
     *  气泡框标题
     */
    title: PropTypes.node,
    /**
     *  气泡框内容
     */
    content: PropTypes.node,
    /**
     *  气泡框按钮组
     */
    button: PropTypes.arrayOf(PropTypes.element),
    /**
     *  气泡框zIndex
     */
    zIndex: PropTypes.number,
    /**
     *  气泡框显示隐藏后的回调，参数visible表示nextProps.visible
     */
    onVisibleChange: PropTypes.func,
    /**
     *  气泡框显示隐藏前的回调，返回false阻止回调onVisibleChange执行
     */
    onBeforeVisibleChange: PropTypes.func,
    /**
     *  气泡框自定义className
     */
    className: PropTypes.string,
    /**
     *  气泡框位置，可选所列12个方向
     */
    placement: PropTypes.oneOf(['left', 'right', 'top', 'bottom', 'topLeft', 'leftTop', 'topRight',
      'rightTop', 'bottomRight', 'rightBottom', 'bottomLeft', 'leftBottom']),
    /**
     *  气泡框最大宽度
     */
    maxWidth: PropTypes.number,
    /**
     *  获取气泡框目标元素
     */
    getTarget: PropTypes.func,
    /**
     *  自定义气泡框位置
     */
    align: PropTypes.object,
  };

  static defaultProps = {
    inline: false,
    visible: false,
    zIndex: 5000,
    onVisibleChange() {
    },
    onBeforeVisibleChange() {
    },
    className: '',
    placement: 'bottom',
    maxWidth: 300,
    getTarget: () => document.body,
  };

  componentDidMount() {
    const body = document.body;
    const container = this.container = document.createElement('div');
    container.className = 'im-popconfirm-root';

    body.appendChild(container);
    this.renderPopconfirm(this.props);
  }

  componentWillReceiveProps(props) {
    this.renderPopconfirm(props);
  }

  componentWillUnmount() {
    this.container.parentNode.removeChild(this.container);
  }

  componentWillUpdate(nextProps) {
    if (nextProps.visible !== this.props.visible) {
      this.onVisibleChange(nextProps.visible);
    }
  }

  onVisibleChange = (visible) => {
    if (this.props.onBeforeVisibleChange(visible) !== false) {
      this.props.onVisibleChange(visible);
    }
  };

  renderPopconfirm = (p) => {
    const { inline, visible } = p;

    // 非inline模式下，一般统一将弹窗置于body下，防止z-index问题
    if (!inline) {
      if (visible) {
        const { getTarget, placement, align } = p;
        let popAlign = align || placements[placement];

        renderSubtreeIntoContainer(this,
          <Align
            align={popAlign}
            target={getTarget}
            monitorWindowResize
          >
            <Popconfirm
              {...p}
            />
          </Align>,
          this.container);
      } else {
        renderSubtreeIntoContainer(this,
          <Popconfirm
            {...p}
          />,
          this.container);
      }
    }
  };

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

    return (inline && visible) ?
      <Popconfirm
        {...this.props}
        className="im-popconfirm-inline"
      /> : null;
  }
}
