import React from 'react';
import bodyFreezer from '../../etc/body-freezer';
import { VelocityTransitionGroup } from 'velocity-react';
import './modal.less';

/**\

    title: Modal
    category: component
    description: A simple Modal
    props:
        isOpen[Bool]: Set to false by default
        closeFunc[Func]:
            This function, if supplied, should ensure isOpen
            will become set to false
        className[String]:
            append classes to the container to make
            special looking modals
    example:
        <Modal isOpen={true} closeFunc={this.close}>
            <h2>Modal Content</h2>
            <p>More content</p>
        </Modal>

\**/
class Modal extends React.Component {
    static defaultProps = {
        isOpen: false
    };

    elem = null;

    keyEvent(event) {
        /* istanbul ignore next: simulation has no bubbling */
        if (event.key === 'Escape' || event.keyCode === 27) {
            this.closeModal();
        }
    }

    clickEvent(event) {
        /* istanbul ignore if: simulation has no bubbling */
        if (!this.elem) {
            return;
        }

        if (event.target === this.elem) {
            this.closeModal();
        }
    }

    closeModal() {
        if (!this.props.isOpen) {
            return;
        }

        if (typeof this.props.closeFunc === 'function') {
            this.props.closeFunc();
        }
    }

    componentDidMount() {
        this.boundKeyEvent = this.keyEvent.bind(this);
        window.addEventListener('keydown', this.boundKeyEvent, false);
    }

    componentWillUnmount() {
        /* istanbul ignore else: no one cares */
        if (this.props.isOpen) {
            bodyFreezer.unfreeze();
        }

        window.removeEventListener('keydown', this.boundKeyEvent, false);
    }

    componentWillReceiveProps(props) {
        /* istanbul ignore next: transition stuff */
        if (!this.props.isOpen && props.isOpen) {
            bodyFreezer.freeze();
        }

        /* istanbul ignore next: transition stuff */
        if (
            this.props.isOpen &&
            props.hasOwnProperty('isOpen') &&
            !props.isOpen
        ) {
            bodyFreezer.unfreeze();
        }
    }

    render() {
        let classer = 'modal',
            body = false;

        if (this.props.className) {
            classer += ' ' + this.props.className;
        }

        if (this.props.isOpen) {
            body = (
                <div ref={ (c) => (this.elem = c) }
                    className={ classer }
                    onClick={ this.clickEvent.bind(this) }>
                    <div className="modal-dialog">
                        { this.props.children }
                    </div>
                </div>
            );
        }

        return (
            <VelocityTransitionGroup
                enter={ { animation: 'fadeIn' } }
                leave={ { animation: 'fadeOut' } }>
                { body }
            </VelocityTransitionGroup>
        );
    }
}

export default Modal;
