import classNames from 'classnames';
import $ from 'jquery';
import _ from 'lodash';
import { Component, PropTypes } from 'react';

import webFragments from 'bitbucket/internal/impl/web-fragments';

import AUIComponent from '../../aui-react/component';
import { PullRequestState } from '../../models/models';

const propTypes = {
    onMoreAction: PropTypes.func.isRequired,
    isWatching: PropTypes.bool.isRequired,
    conditions: PropTypes.objectOf(PropTypes.bool).isRequired,
    pullRequest: PropTypes.object.isRequired,
};

class PullRequestMore extends Component {

    constructor() {
        super();
        this.dropdownIsVisible = false;

        const reasonableDelay = 50;
        this.throttledTriggerHideOnScroll = _.throttle(function() {
            if (this.dropdownIsVisible) {
                $('.pull-request-more-trigger').trigger("aui-button-invoke");
            }
        }.bind(this), reasonableDelay);
    }

    componentDidMount() {
        // hide the more menu when it's supposed to be closed
        // For whatever reason (probably a react / non-react conflict) the more menu doesn't hide itself properly
        // and instead hangs around too long. We force it to hide here.
        $("#pull-request-header-more").on({
            "aui-dropdown2-show": () => {
                this.dropdownIsVisible = true;
            },
            "aui-dropdown2-hide": event => {
                $(event.target).hide();
                this.dropdownIsVisible = false;
            },
        });

        $(document).on('scroll', this.throttledTriggerHideOnScroll);
    }

    componentWillUnmount() {
        $("#pull-request-header-more").off("aui-dropdown2-hide");
        $(document).off('scroll', this.throttledTriggerHideOnScroll);
    }

    render() {
        let editMenuItem;
        let declineMenuItem;
        const pullRequestIsOpen = this.props.pullRequest.state === PullRequestState.OPEN;
        const pullRequestIsMerged = this.props.pullRequest.state === PullRequestState.MERGED;

        const addonActions = webFragments.getWebItems('bitbucket.pullrequest.action', { pullRequest: this.props.pullRequest });
        const deprecatedActions = _.flatten(
                webFragments.getWebSections('bitbucket.internal.pullrequest.toolbar.deprecated')
                        .map(section => webFragments.getWebItems('bitbucket.internal.pullrequest.toolbar.deprecated/' + section.key)));

        if (this.props.conditions.canEdit && !pullRequestIsMerged) { // disallow editing merged pull requests.
            editMenuItem = (
                <li>
                    <button className="aui-button aui-button-link" role="menuitem" data-action="edit">
                        {AJS.I18n.getText('bitbucket.component.pull.request.edit')}
                    </button>
                </li>
            );
        }
        if (this.props.conditions.canDecline && pullRequestIsOpen) {
            declineMenuItem = (
                <li>
                    <button className="aui-button aui-button-link" role="menuitem" data-action="decline">
                        {AJS.I18n.getText('bitbucket.component.pull.request.decline')}
                    </button>
                </li>
            );
        }
        return (
            <div>
                <button
                    className="pull-request-more-trigger aui-button aui-button-subtle aui-dropdown2-trigger aui-dropdown2-trigger-arrowless"
                    aria-haspopup="true"
                    aria-owns="pull-request-header-more"
                >
                    <span className="aui-icon aui-icon-small aui-iconfont-more">{AJS.I18n.getText('bitbucket.component.pull.request.more')}</span>
                </button>
                <AUIComponent
                    id="pull-request-header-more"
                    markup={`<div class="aui-style-default aui-dropdown2"></div>`}
                    wrapperClass="aui-dropdown2-section"
                >
                    <ul className="aui-list-truncate" onClick={e => this.props.onMoreAction(e.target.dataset.action)}>
                        {editMenuItem}
                        {declineMenuItem}
                        <li>
                            <button className="aui-button aui-button-link" role="menuitem" data-action="watch">
                                {this.props.isWatching ?
                                    AJS.I18n.getText('bitbucket.component.pull.request.unwatch') :
                                    AJS.I18n.getText('bitbucket.component.pull.request.watch')
                                }
                            </button>
                        </li>
                        {addonActions.concat(deprecatedActions).map(webItem =>
                            <li key={webItem.completeModuleKey || webItem.key}>
                                {webItem.url ?
                                    <a href={webItem.url} className={webItem.cssClass} id={webItem.id} title={webItem.tooltip}>
                                        {webItem.text}
                                    </a> :
                                    <button
                                        className={classNames("aui-button aui-button-link", webItem.cssClass)}
                                        role="menuitem"
                                        id={webItem.id}
                                        title={webItem.tooltip}
                                    >
                                        {webItem.text}
                                    </button>
                                }
                            </li>
                        )}
                    </ul>
                </AUIComponent>
            </div>
        );
    }
}

PullRequestMore.propTypes = propTypes;

export default PullRequestMore;
