const Issue = require('./src/issue');
const text = require('./src/text');
const { isCoreCommitter } = require('./src/coreCommitters');

module.exports = app => {
    app.on(['issues.opened'], async context => {
        const issue = new Issue(context);

        // Ignore comment because it will commented when adding invalid label
        const comment = issue.response === text.NOT_USING_TEMPLATE
            ? Promise.resolve()
            : commentIssue(context, issue.response);

        const addLabels = issue.addLabels.length
            ? context.github.issues.addLabels(context.issue({
                labels: issue.addLabels
            }))
            : Promise.resolve();

        const removeLabel = issue.removeLabel
            ? getRemoveLabel(issue.removeLabel)
            : Promise.resolve();

        return Promise.all([comment, addLabels, removeLabel]);
    });

    app.on('issues.labeled', async context => {
        var replaceAt = function (comment) {
            return replaceAll(
                comment,
                'AT_ISSUE_AUTHOR',
                '@' + context.payload.issue.user.login
            );
        };

        switch (context.payload.label.name) {
            case 'invalid':
                return Promise.all([commentIssue(context, text.NOT_USING_TEMPLATE), closeIssue(context)]);

            case 'howto':
                return Promise.all([commentIssue(context, text.LABEL_HOWTO), closeIssue(context)]);

            case 'inactive':
                return Promise.all([commentIssue(context, text.INACTIVE_ISSUE), closeIssue(context)]);

            case 'missing-demo':
                return Promise.all([
                    commentIssue(context, replaceAt(text.MISSING_DEMO)),
                    getRemoveLabel(context, 'waiting-for: community'),
                    context.github.issues.addLabels(context.issue({
                        labels: ['waiting-for: author']
                    }))
                ]);

            // case 'waiting-for: author':
            //     return commentIssue(context, replaceAt(text.ISSUE_TAGGED_WAITING_AUTHOR));

            case 'difficulty: easy':
                return commentIssue(context, replaceAt(text.ISSUE_TAGGED_EASY));

            case 'priority: high':
                return commentIssue(context, replaceAt(text.ISSUE_TAGGED_PRIORITY_HIGH));
        }
    });

    app.on('issue_comment.created', async context => {
        const isPr = context.payload.issue.html_url.indexOf('/pull/') > -1;
        if (isPr) {
            // Do nothing when pr is commented
            return;
        }

        const commenter = context.payload.comment.user.login;
        const isCommenterAuthor = commenter === context.payload.issue.user.login;
        let removeLabel;
        let addLabel;
        if (isCommitter(context.payload.comment.author_association)) {
            // New comment from core committers
            removeLabel = getRemoveLabel(context, 'waiting-for: community');
        }
        else if (isCommenterAuthor) {
            // New comment from issue author
            removeLabel = getRemoveLabel(context, 'waiting-for: author');
            addLabel = context.github.issues.addLabels(context.issue({
                labels: ['waiting-for: community']
            }));
        }
        return Promise.all([removeLabel, addLabel]);
    });

    app.on(['pull_request.opened'], async context => {
        // const auth = context.payload.pull_request.author_association;
        const isCore = isCoreCommitter(context.payload.pull_request.user.login);
        let commentText = isCore
            ? text.PR_OPENED_BY_COMMITTER
            : text.PR_OPENED;

        const labelList = ['PR: awaiting review'];
        if (isCore) {
            labelList.push('PR: author is committer');
        }
        const content = context.payload.pull_request.body;
        if (content && content.indexOf('[x] The API has been changed.') > -1) {
            labelList.push('PR: awaiting doc');
            commentText += '\n\n' + text.PR_AWAITING_DOC;
        }

        const comment = context.github.issues.createComment(context.issue({
            body: commentText
        }));

        const addLabel = context.github.issues.addLabels(context.issue({
            labels: labelList
        }));

        return Promise.all([comment, addLabel]);
    });

    app.on(['pull_request.edited'], async context => {
        const content = context.payload.pull_request.body;
        if (content && content.indexOf('[x] The API has been changed.') > -1) {
            return context.github.issues.addLabels(context.issue({
                labels: ['PR: awaiting doc']
            }));
        }
        else {
            return getRemoveLabel(context, 'PR: awaiting doc');
        }
    });

    app.on(['pull_request.synchronize'], async context => {
        const addLabel = context.github.issues.addLabels(context.issue({
            labels: ['PR: awaiting review']
        }));
        const removeLabel = getRemoveLabel(context, 'PR: revision needed');
        return Promise.all([addLabel, removeLabel]);
    });

    app.on(['pull_request.closed'], async context => {
        const actions = [
            getRemoveLabel(context, 'PR: revision needed'),
            getRemoveLabel(context, 'PR: awaiting review')
        ];
        const isMerged = context.payload['pull_request'].merged;
        if (isMerged) {
            const comment = context.github.issues.createComment(context.issue({
                body: text.PR_MERGED
            }));
            actions.push(comment);
        }
        return Promise.all(actions);
    });

    app.on(['pull_request_review.submitted'], async context => {
        if (context.payload.review.state === 'changes_requested'
            && isCommitter(context.payload.review.author_association)
        ) {
            const addLabel = context.github.issues.addLabels(context.issue({
                labels: ['PR: revision needed']
            }));

            const removeLabel = getRemoveLabel(context, 'PR: awaiting review');
            return Promise.all([addLabel, removeLabel]);
        }
    });
}

function getRemoveLabel(context, name) {
    return context.github.issues.removeLabel(
        context.issue({
            name: name
        })
    ).catch(err => {
        // Ignore error caused by not existing.
        // if (err.message !== 'Not Found') {
        //     throw(err);
        // }
    });
}

function closeIssue(context) {
    const closeIssue = context.github.issues.update(context.issue({
        state: 'closed'
    }));
    return closeIssue;
}

function commentIssue(context, commentText) {
    const comment = context.github.issues.createComment(context.issue({
        body: commentText
    }));
    return comment;
}

function replaceAll(str, search, replacement) {
    return str.replace(new RegExp(search, 'g'), replacement);
}

function isCommitter(auth) {
    return auth === 'COLLABORATOR' || auth === 'MEMBER' || auth === 'OWNER';
}
