import _objectWithoutProperties from 'babel-runtime/helpers/objectWithoutProperties';
import _defineProperty from 'babel-runtime/helpers/defineProperty';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
var _jsxFileName = 'src/modal/Modal.jsx';
/**
 * Modal.jsx
 *
 * @Author: jruif
 * @Date: 2017/7/7 下午9:07
 *
 * todo: 移除Box，使用Overlay & Portal组件重写
 */

import React from 'react';
import { findDOMNode } from 'react-dom';
import PropTypes from 'prop-types';
import classNames from 'classnames';
import addEventListener from '../util/addEventListener';
import { isObject } from '../util/isType';
import omit from '../util/omit';
import Button from '../button';
import ModalHeader from './ModalHeader';
import ModalFooter from './ModalFooter';
import ModalContent from './ModalContent';
import { CSSTransition, TransitionGroup } from 'react-transition-group';
import Box from '../box';
import extend from 'object-assign';

var props = {
    prefixCls: 'ne-modal',
    size: 'md',
    cancelText: '取消',
    okText: '确定',
    isOpen: false,
    maskType: 'default',
    vertical: 'top',
    mountNode: document.body,
    isScrollOnBody: false,
    // isCloseOnDocumentClick: false,
    isCloseOnMaskClick: false,
    isConfirmLoading: false,
    hasCloseBtnOnHeader: true,
    showCancelBtnOnFooter: true,
    transitionName: 'animate-slideDown',
    transitionDuration: 500,
    hasHeader: true,
    hasFooter: true
};

export var defaultProps = extend({}, props);

var mousePositionEventBinded = null;

/**
 * Modal
 * */

var Modal = function (_React$Component) {
    _inherits(Modal, _React$Component);

    function Modal(props, context) {
        _classCallCheck(this, Modal);

        var _this = _possibleConstructorReturn(this, (Modal.__proto__ || Object.getPrototypeOf(Modal)).call(this, props, context));

        _initialiseProps.call(_this);

        _this.mousePosition = null;
        _this.state = {
            isOpen: false,
            showMask: false,
            isConfirmLoading: props.isConfirmLoading,
            opacity: 0
        };
        return _this;
    }

    _createClass(Modal, [{
        key: 'componentWillMount',
        value: function componentWillMount(e) {
            //this.setPosition();
            clearTimeout(this.animateTimer);
            var onMount = this.props.onMount;

            if (onMount) onMount(e, this.props);
        }
    }, {
        key: 'componentDidMount',
        value: function componentDidMount() {
            var _this2 = this;

            var isOpen = this.props.isOpen;

            if (isOpen) {
                this.handleOpen();
            }

            if (mousePositionEventBinded) {
                return;
            }
            // 只有点击事件支持从鼠标位置动画展开
            addEventListener(document.documentElement, 'click', function (e) {
                _this2.mousePosition = {
                    x: e.pageX,
                    y: e.pageY
                };
                // 100ms 内发生过点击事件，则从点击位置动画展示
                // 否则直接 zoom 展示
                // 这样可以兼容非点击方式展开
                // console.log(this.mousePosition);
                setTimeout(function () {
                    return _this2.mousePosition = null;
                }, 100);
            });

            mousePositionEventBinded = true;
        }
    }, {
        key: 'componentWillReceiveProps',
        value: function componentWillReceiveProps(nextProps) {
            var newState = {};
            if (nextProps.isOpen !== this.props.isOpen) {
                //newState.isOpen = nextProps.isOpen;
                if (nextProps.isOpen) {
                    return this.handleOpen();
                } else if (this.state.isOpen && !nextProps.isOpen) {
                    return this.handleClose();
                }
            }
            if (nextProps.isConfirmLoading !== this.props.isConfirmLoading) {
                newState.isConfirmLoading = nextProps.isConfirmLoading;
            }
            if (Object.keys(newState).length > 0) {
                this.setState(newState);
            }
        }
    }, {
        key: 'componentDidUpdate',
        value: function componentDidUpdate(prevProps, prevState) {
            var state = this.state;
            var onClose = this.props.onClose;

            if (state.isOpen !== prevState.isOpen && !state.isOpen) {
                // 关闭
                this.handleClose();

                if (onClose) {
                    onClose();
                }
            }
            this.clearOnClose();
        }
    }, {
        key: 'componentWillUnmount',
        value: function componentWillUnmount() {
            this.clearOnClose();
        }

        // shouldComponentUpdate(nextProps, nextState) {
        //     // 当 isOpen 是 true 时，再更新
        //     return this.state.isOpen || nextState.isOpen;
        // }
        //
        // componentWillUnmount(e) {
        //     cancelAnimationFrame(this.animationRequestId);
        //
        //     const { onUnmount } = this.props;
        //     if (onUnmount) onUnmount(e, this.props);
        // }
        //
        // setPosition = () => {
        //     if (this.ref) {
        //         const mountNode = this.props.mountNode;
        //         const { height } = this.ref.getBoundingClientRect();
        //
        //         const marginTop = -Math.round(height / 2);
        //         const scrolling = height >= window.innerHeight;
        //
        //         const newState = {};
        //
        //         if (this.state.marginTop !== marginTop) {
        //             newState.marginTop = marginTop;
        //         }
        //
        //         if (this.state.scrolling !== scrolling) {
        //             newState.scrolling = scrolling;
        //
        //             if (scrolling) {
        //                 mountNode.classList.add('scrolling');
        //             } else {
        //                 mountNode.classList.remove('scrolling');
        //             }
        //         }
        //
        //         if (Object.keys(newState).length > 0) {
        //             this.setState(newState);
        //         }
        //     }
        //
        //     this.animationRequestId = requestAnimationFrame(this.setPosition);
        // };

    }, {
        key: 'renderContent',
        value: function renderContent() {
            var _classNames,
                _classNames2,
                _this3 = this;

            var _props = this.props,
                prefixCls = _props.prefixCls,
                className = _props.className,
                okText = _props.okText,
                cancelText = _props.cancelText,
                title = _props.title,
                children = _props.children,
                vertical = _props.vertical,
                size = _props.size,
                style = _props.style,
                maskType = _props.maskType,
                hasCloseBtnOnHeader = _props.hasCloseBtnOnHeader,
                showCancelBtnOnFooter = _props.showCancelBtnOnFooter,
                transitionName = _props.transitionName,
                transitionDuration = _props.transitionDuration,
                hasHeader = _props.hasHeader,
                hasFooter = _props.hasFooter;
            var _props$content = this.props.content,
                content = _props$content === undefined ? [] : _props$content;


            var classes = classNames(prefixCls + '-plane', (_classNames = {}, _defineProperty(_classNames, prefixCls + '-' + size, size), _defineProperty(_classNames, prefixCls + '-vertical-' + vertical, vertical), _classNames), className);

            var defaultFooter = [React.createElement(
                Button,
                { hollow: true, key: 'cancel', onClick: this.handleCancel, __source: {
                        fileName: _jsxFileName,
                        lineNumber: 361
                    },
                    __self: this
                },
                cancelText || '取消'
            ), React.createElement(
                Button,
                {
                    key: 'confirm',
                    type: 'primary',
                    disabled: this.state.isConfirmLoading,
                    loading: this.state.isConfirmLoading,
                    onClick: this.handleOk, __source: {
                        fileName: _jsxFileName,
                        lineNumber: 364
                    },
                    __self: this
                },
                okText || '确定'
            )];

            if (!showCancelBtnOnFooter) {
                defaultFooter.shift();
            }

            var header = null;
            var body = null;
            var footer = null;

            if (!Array.isArray(content)) {
                // fix bug: 当直接调用content字段传内容当时候会提示无key
                content = [React.isValidElement(content) ? React.cloneElement(content, { key: 'content' }) : content];
            }

            React.Children.forEach(children, function (child) {
                var childType = child ? isObject(child.type) || typeof child.type === 'function' ? child.type.displayName || child.type.name : child.type : child;
                if (childType === 'NeatUI.ModalHeader') {
                    header = child;
                } else if (hasFooter && childType === 'NeatUI.ModalFooter') {
                    footer = child;
                } else if (childType === 'NeatUI.ModalContent') {
                    body = child;
                } else {
                    content.push(child);
                }
            });

            var modalContent = React.createElement(
                CSSTransition,
                { classNames: transitionName, timeout: transitionDuration, 'in': this.state.isOpen, __source: {
                        fileName: _jsxFileName,
                        lineNumber: 405
                    },
                    __self: this
                },
                React.createElement(
                    'div',
                    { className: classes, ref: this.handleRef, style: style, key: 'box', __source: {
                            fileName: _jsxFileName,
                            lineNumber: 406
                        },
                        __self: this
                    },
                    !hasHeader ? null : header ? header : title ? React.createElement(
                        ModalHeader,
                        { onClose: this.handleCancel, hasCloseBtnOnHeader: hasCloseBtnOnHeader, __source: {
                                fileName: _jsxFileName,
                                lineNumber: 410
                            },
                            __self: this
                        },
                        title
                    ) : null,
                    body ? body : React.createElement(
                        ModalContent,
                        {
                            __source: {
                                fileName: _jsxFileName,
                                lineNumber: 414
                            },
                            __self: this
                        },
                        content
                    ),
                    !hasFooter ? null : footer ? footer : React.createElement(
                        ModalFooter,
                        {
                            __source: {
                                fileName: _jsxFileName,
                                lineNumber: 415
                            },
                            __self: this
                        },
                        defaultFooter
                    )
                )
            );

            return React.createElement(
                TransitionGroup,
                {
                    appear: true,
                    className: classNames(prefixCls, prefixCls + '-vertical', (_classNames2 = {}, _defineProperty(_classNames2, prefixCls + '-not-open', !this.state.isOpen), _defineProperty(_classNames2, prefixCls + '-mask', maskType !== 'none'), _defineProperty(_classNames2, prefixCls + '-mask-' + maskType, maskType !== 'none' && this.state.showMask), _classNames2)),
                    ref: function ref(c) {
                        return _this3.maskNode = c;
                    },
                    onClick: this.handleClickMask, __source: {
                        fileName: _jsxFileName,
                        lineNumber: 421
                    },
                    __self: this
                },
                this.state.isOpen ? modalContent : null
            );
        }
    }, {
        key: 'render',
        value: function render() {
            var _props2 = this.props,
                prefixCls = _props2.prefixCls,
                mountNode = _props2.mountNode,
                other = _objectWithoutProperties(_props2, ['prefixCls', 'mountNode']);

            return React.createElement(
                Box,
                Object.assign({
                    className: classNames(prefixCls + '-base'),
                    position: this.mousePosition,
                    mountNode: mountNode,
                    isOpen: this.state.isOpen
                }, omit(other, ['prefixCls', 'className', 'okText', 'cancelText', 'title', 'isConfirmLoading', 'children', 'content', 'size', 'style', 'vertical', 'onClose', 'onOk', 'isOpen']), {
                    __source: {
                        fileName: _jsxFileName,
                        lineNumber: 439
                    },
                    __self: this
                }),
                this.renderContent()
            );
        }
    }]);

    return Modal;
}(React.Component);

Modal.displayName = 'NeatUI.Modal';
Modal.propTypes = {
    prefixCls: PropTypes.string,
    /** 是否打开，可以手动控制弹窗显示*/
    isOpen: PropTypes.bool,
    /**
     * 触发打开事件的时候调用
     *
     * @param {SyntheticEvent} event - React's original SyntheticEvent.
     * @param {object} data - 所有 props.
     */
    onOpen: PropTypes.func,
    /**
     * 触发打开事件的时候调用
     *
     * @param {SyntheticEvent} event - React's original SyntheticEvent.
     * @param {object} data - 所有 props.
     */
    onClose: PropTypes.func,
    /**
     * modal被挂载的时候调用
     *
     * @param {null}
     * @param {object} data - 所有 props.
     */
    onMount: PropTypes.func,
    /**
     * modal被卸载的时候调用
     *
     * @param {null}
     * @param {object} data - 所有 props.
     */
    onUnmount: PropTypes.func,

    /** modal挂载的节点. 预设定为 document.body 节点下 */
    mountNode: PropTypes.any,
    /** 在body中是否滚动*/
    isScrollOnBody: PropTypes.bool,
    /** 弹窗大小*/
    size: PropTypes.oneOf(['fullScreen', 'lg', 'sm', 'md']),
    /** 弹窗外层容器的样式*/
    style: PropTypes.object,
    /** 弹窗外层容器的类名*/
    className: PropTypes.string,
    /** 垂直对齐*/
    vertical: PropTypes.oneOf(['middle', 'top', 'bottom']),
    /** 遮盖层样式*/
    maskType: PropTypes.oneOf(['default', 'none']),
    /**
     * @ignore
     * */
    children: PropTypes.node,
    /** Icon. */
    // closeIcon: PropTypes.oneOfType([
    //     PropTypes.node,
    //     PropTypes.object,
    //     PropTypes.bool,
    // ]),
    /** 点击遮幕是否关闭 */
    isCloseOnMaskClick: PropTypes.bool,
    /** 点击弹窗外部是否关闭*/
    // isCloseOnDocumentClick: PropTypes.bool,
    /** 弹窗顶部是否有关闭按钮*/
    hasCloseBtnOnHeader: PropTypes.bool,
    /** 是否有顶部，可移除预设顶部，优先级最高 */
    hasHeader: PropTypes.bool,
    /** 是否有底部，可移除预设底部，优先级最高  */
    hasFooter: PropTypes.bool,
    /** 确认按钮文字*/
    okText: PropTypes.string,
    /** 取消按钮文字*/
    cancelText: PropTypes.string,
    /** 确定按钮 loading*/
    isConfirmLoading: PropTypes.bool,
    /** 是否显示footer上的取消按钮 */
    showCancelBtnOnFooter: PropTypes.bool,
    /** 弹窗顶部标题，可用Modal.Header代替*/
    title: PropTypes.string,
    /** 弹窗内容，可用Modal.ModalContent代替*/
    content: PropTypes.any,
    /** 弹窗确定按钮回调*/
    onOk: PropTypes.func,
    /** 弹窗取消按钮回调*/
    onCancel: PropTypes.func,
    /** Modal窗体进入退出动画，可选择预设三种`animate-fade`, `animate-slideDown`, `animate-zoom`之一或自定义*/
    transitionName: PropTypes.string,
    /** 弹窗执行动画时长*/
    transitionDuration: PropTypes.number
};
Modal.defaultProps = props;

var _initialiseProps = function _initialiseProps() {
    var _this4 = this;

    this.clearOnClose = function () {
        var state = _this4.state;
        var _props3 = _this4.props,
            mountNode = _props3.mountNode,
            isScrollOnBody = _props3.isScrollOnBody,
            isOpen = _props3.isOpen;

        if (!isScrollOnBody) {
            var clsReg = /is-modal-open/g;
            if (state.isOpen || isOpen) {
                if (!clsReg.test(mountNode.className)) {
                    mountNode.className = classNames(mountNode.className, 'is-modal-open');
                }
            } else {
                mountNode.className = mountNode.className.replace(clsReg, '').trim();
            }
        }
    };

    this.handleClose = function (e) {
        // const { transitionDuration } = this.props;
        _this4.setState({
            showMask: false
        });
        _this4.animateTimer = setTimeout(function () {
            _this4.setState({ isOpen: false });
        });
    };

    this.handleOpen = function (e) {
        // const { transitionDuration } = this.props;
        _this4.setState({ isOpen: true });
        _this4.animateTimer = setTimeout(function () {
            _this4.setState({
                showMask: true
            });
        });
    };

    this.handleOk = function (e) {
        var onOk = _this4.props.onOk;

        if (onOk) {
            onOk(e);
        }
    };

    this.handleCancel = function (e) {
        _this4.setState({ isOpen: false });
        var onCancel = _this4.props.onCancel;

        if (onCancel) {
            onCancel(e);
        }
        //this.handleClose();
    };

    this.handleClickMask = function (e) {
        var isCloseOnMaskClick = _this4.props.isCloseOnMaskClick;

        if (isCloseOnMaskClick && e.target === findDOMNode(_this4.maskNode)) {
            _this4.handleClose();
        }
    };

    this.handleRef = function (c) {
        return _this4.ref = c;
    };
};

export default Modal;