import React, { PropTypes } from 'react';
import ReactDOM from 'react-dom';
import classSet from 'classnames';

import './appMenu.styl';
import './appMenuItems.styl';

function isLink(element) {
    return (element.tagName || '').toLowerCase() === 'a';
}

function insideLink(element) {
    while (element) {
        if (isLink(element)) {
            return true;
        }
        element = element.parentNode;
    }
    return false;
}

var AppMenu = React.createClass({

    getInitialState() {
        return { active: false };
    },

    componentDidMount() {
        document.body.addEventListener('click', this._handleClosingClick);
    },

    componentWillUnmount() {
        document.body.removeEventListener('click', this._handleClosingClick);
    },

    _handleClosingClick(event) {
        var { onClose } = this.props;

        var e = event.target;
        var popup = ReactDOM.findDOMNode(this.refs.popup);

        if (this.state.active && popup && e !== popup && !popup.contains(e)) {
            this.setState({ active: false });
            event.stopPropagation();

            if (onClose) {
                onClose();
            }
        }
    },

    _handleOpeningClick(event) {
        var { onOpen } = this.props;

        if (!insideLink(event.target) && !this.state.active) {
            this.setState({ active: true });

            if (onOpen) {
                onOpen();
            }
        }
    },

    _handleItemSelect(item) {
        var { onSelect } = this.props;

        this.setState({ active: false });

        if (onSelect) {
            onSelect(item);
        }
    },

    _renderItem(item, index) {
        var className = classSet({
            'appboard-item': true,
            [ 'appboard-item__' + item.slug ]: true
        });

        return (
            <a className={className}
                href={item.url}
                target={item.slug === 'calendar' ? '_blank' : null}
                onClick={this._handleItemSelect.bind(this, item)}
                key={index}>
                <div className="appboard-item__frame">
                    <div className="appboard-item__icon">
                        <img src={item.icon} className="appboard-item__icon-image"/>
                    </div>
                    <div className="appboard-item__title">{item.name}</div>
                </div>
            </a>
        );
    },

    render() {
        var { services } = this.props;
        var isEmpty = !services || !services.length;

        var className = classSet({
            'appmenu': true,
            'appmenu_active': this.state.active && !isEmpty,
            'appmenu_empty': isEmpty
        });

        var appList;

        if (!isEmpty) {
            appList = (
                <div className="appmenu__popup" ref="popup">
                    <div className="appmenu__popup-content appboard">
                        {services.map(this._renderItem)}
                    </div>
                </div>
            );
        }

        return (
            <div className={className}>
                <div className="appmenu__body" onClick={this._handleOpeningClick}>
                    <div className="appmenu__button" onClick={this.props.onMenuButtonClick}/>
                    {this.props.children}
                </div>
                {appList}
            </div>
        );
    }

});

AppMenu.propTypes = {
    services: PropTypes.arrayOf(
        PropTypes.shape({
            url: PropTypes.oneOfType([ PropTypes.string, PropTypes.func ]),
            slug: PropTypes.string,
            name: PropTypes.string,
            icon: PropTypes.string
        })
    ),
    onMenuButtonClick: PropTypes.func,
    onOpen: PropTypes.func,
    onClose: PropTypes.func,
    onSelect: PropTypes.func
};

AppMenu.defaultProps = {
    services: []
};

export default AppMenu;
