/*globals module, console, require */

module.exports = function (controller) {

    /**
     * Ensure that is a call to Panda api and not to something else
     * @param req
     * @param res
     * @returns {*}
     */
    controller.handleApi = function (req, res) {
        // Parse Content
        var payload = req.body;
        if (payload.payload) {
            payload = JSON.parse(payload.payload);
        }

        var bot = controller.spawn({});

        // Handle Response
        if ('panda_api' == payload.type) {
            return handlePandaAPI(payload, bot, res);
        } else {
            console.log('Unhandled API');
        }
    };

    /**
     * Handle Panda API endpoints
     *
     * @param payload
     * @param bot
     * @param res
     */
    function handlePandaAPI(payload, bot, res) {
        if ('teams' == payload.api_type) {
            // List all channels
            listChannels(bot, res, function (channelsList) {
                res.json({
                    channels: channelsList,
                    status: true,
                    message: 'List Channels'
                });
            });
        } else if ('help_requests' == payload.api_type) {
            // Send an Help Request
            sendHelpRequest(payload, bot, res);
        } else if ('solutions' == payload.api_type) {
            sendSolutionFeedback(payload, bot, res);
        }
    }

    /**
     * Allows bot to thanks a user or more after he helps somebody
     *
     * @param payload
     * @param bot
     * @param res
     */
    function sendSolutionFeedback(payload, bot, res) {
        helpRequestStatus = payload.help_request_status;
        helpRequestId = payload.help_request_id;

        solutionStatus = payload.solution_status;
        currentHelperNickname = payload.solution_helper_username;

        otherHelpersNickname = payload.other_helpers_username;

        userNickname = payload.username.charAt(0).toUpperCase() + payload.username.slice(1);
        hot_keyword = userNickname.charAt(0) + helpRequestId;

        getHelpChannelId(bot, res, function (helpChannelId) {
            if (helpChannelId) {

                if ('resolved' == helpRequestStatus) {

                    if ('undefined' == typeof otherHelpersNickname) {
                        special_thanks = 'La demande ' + hot_keyword + ' est close. Merci @' + currentHelperNickname + ' d\'avoir aidé ' + userNickname + ', vous avez solutionné son problème.';
                    } else if (!Array.isArray(otherHelpersNickname)) {
                        special_thanks = 'La demande ' + hot_keyword + ' est close. Merci @' + currentHelperNickname + ' d\'avoir aidé ' + userNickname + ', vous avez solutionné son problème. Merci également à ' + otherHelpersNickname + ' d\'avoir aidé.';
                    } else {
                        lastOtherHelperNickname = otherHelpersNickname.pop();
                        special_thanks = 'La demande ' + hot_keyword + ' est close. Merci @' + currentHelperNickname + ' d\'avoir aidé ' + userNickname + ', vous avez solutionné son problème. Merci également à ' + otherHelpersNickname.join(', ') + ' et ' + lastOtherHelperNickname + ' d\'avoir aidé.';
                    }

                    // Acknowledge new helper
                    bot.say({
                        text: special_thanks,
                        channel: helpChannelId
                    });

                } else {

                    // Acknowledge new helper
                    bot.say({
                        text: 'Merci @' + currentHelperNickname + ' d\'avoir aidé ' + userNickname + ', mais d\'avantage de détails sont nécessaires, merci de répondre à la requête ' + hot_keyword + '.',
                        channel: helpChannelId
                    });

                }

                res.json({
                    status: true,
                    message: 'Message sent'
                });
            } else {
                console.log('no helpChannelId provided : channel Help not found');
                res.json({
                    status: false,
                    message: 'Help channel not found'
                });
            }
        });
    }

    /**
     * List all channels where bot is
     *
     * @param bot
     * @param res
     * @param callback
     */
    function listChannels(bot, res, callback) {
        var channelsList = [];

        controller.storage.channels.all(function (err, existingChannels) {

            if (err) {
                console.log('error retriving existing channels : ' + err);
            } else {
                // Send stored channels
                if (0 < existingChannels.length) {
                    console.log('list existing channels');
                    channelsList = existingChannels;
                    callback(channelsList);

                    // Get new channels
                } else {
                    console.log('request new channels');
                    retrieveChannels(bot, res, function (channelsList) {
                        callback(channelsList);
                    });
                }
            }
        });
    }

    /**
     *  Find channels registered on spark
     *
     * @param bot
     * @param res
     * @param callback
     */
    function retrieveChannels(bot, res, callback) {
        // Request HR details
        var channelsList = [];
        var request = require('request');

        var options = {
            url: 'https://api.ciscospark.com/v1/rooms',
            headers: {
                'Authorization': 'Bearer ' + process.env.access_token,
                'Content-Type': 'application/json; charset=utf-8'
            }
        };

        request(options, function (error, response, body) {
            if (!error && 200 == response.statusCode) {
                const
                    channelsResult = JSON.parse(body),
                    channels = channelsResult.items;

                // Store Channels
                for (let channelKey in channels) {
                    const
                        channelHash = {};

                    channelHash['id'] = channels[channelKey].id;
                    channelHash['title'] = channels[channelKey].title;

                    controller.storage.channels.save({
                        id: channels[channelKey].id,
                        title: channels[channelKey].title
                    });
                    channelsList.push(channelHash);
                }

                callback(channelsList);
            } else {
                console.log('error:', error);
                console.log('statusCode:', response && response.statusCode);
                callback(channelsList);
            }
        });
    }

    /**
     * Get the help channel
     *
     * @param bot
     * @param res
     * @param callback
     */
    function getHelpChannelId(bot, res, callback) {
        var helpChannelId = '';
        var helpChannelPattern = /help/i;

        listChannels(bot, res, function (channels) {
            var total = channels.length;

            // Go through each channels to find the help channel
            for (let channelId = 0; channelId < total; channelId++) {
                let channel = channels[channelId];

                // Get the help channel
                if (helpChannelPattern.test(channel.title)) {
                    helpChannelId = channel.id;
                    // Trigger callback with help Channel id
                    callback(helpChannelId);
                }
            }
            return helpChannelId;
        });
    }

    /**
     * Send help request on main channel
     *
     * @param payload
     * @param bot
     * @param res
     */
    function sendHelpRequest(payload, bot, res) {
        getHelpChannelId(bot, res, function (helpChannelId) {
            if (helpChannelId) {
                helpRequestId = payload.help_request_id;
                username = payload.username.charAt(0).toUpperCase() + payload.username.slice(1);
                hot_keyword = username.charAt(0) + helpRequestId;

                // Acknowledge new helper
                bot.say({
                    text: username + ' a besoin de votre aide. Pour l\'aider, dites moi ' + hot_keyword + ' .',
                    channel: helpChannelId
                });

                // Wait for challengers
                controller.hears([hot_keyword], 'direct_mention', function (bot, message) {
                    person = {
                        id: message.original_message.personId,
                        email: message.original_message.personEmail
                    };
                    controller.startHelpRequestDialog(bot, helpRequestId, person)
                });

                res.json({
                    status: true,
                    message: 'Message sent'
                });
            } else {
                console.log('no helpChannelId provided : channel Help not found');
                res.json({
                    status: false,
                    message: 'Help channel not found'
                });
            }
        });
    }
};
