/**
 * Screenshot or palyback module
 * @author Manish Yadav
 * @copyright Semusi Technologies PVT LTD
 */
var screenshot = {},
    common = require('./../../utils/common.js'),
    logger = require('../../../logger'),
    async = require('async'),
    path = require('path'),
    moment = require('moment'),
    campaignUtils = require('./../../utils/campaign.utils'),
    _ = require('underscore');
    semusiConfig = require('../../config');
(function (screenshot) {
    //get User last 10 history
    screenshot.userHistory = function(params){
        var argProps = {
                'did':{'required':true,'type':'String'}
            },
            history = {};

        if (!(history = common.validateArgs(params.qstring.args, argProps))) {
            common.returnMessage(params, 400, 'Not enough args');
            return false;
        }

        common.db.collection('screenshot_'+params.qstring.app_id).find({did:history.did}).sort({ et : -1 }).limit(10).toArray(function(error, result){
            if(!error){
                if(result){
                    common.returnOutput(params, result );
                }
                else{
                    common.returnOutput(params, []);
                }
            }
            else{
                common.returnOutput(params, []);
            }
        });
    };

    screenshot.currentUsers = function(params){
          var argProps = {
                  'startDate':{'required':true,'type':'Number'},
                  'endDate':{'required':true,'type':'Number'}
              },
              args = {};

          if (!(args = common.validateArgs(params.qstring.args, argProps))) {
              common.returnMessage(params, 400, 'Not enough args');
              return false;
          }

                var sortlist = ['et', 'data','time'];
                var sort = {et:-1}
                // check sort by
                if(params.qstring["order[0][column]"]
                    || (params.qstring["order[0][column]"] && params.qstring["order[0][column]"] == 0)){

                    // check filter column
                    if(params.qstring["order[0][column]"]){
                        sort = {}
                        sort[sortlist[params.qstring["order[0][column]"]]] = (params.qstring["order[0][dir]"] == 'asc')? 1 : -1;
                    }
                }
                // get pagination start
                params.qstring.start = parseInt(params.qstring.start);
                common.db.collection('screenshot_'+params.qstring.app_id)
                .find({et:{$gte:args.startDate, $lte:args.endDate}})
                .sort(sort).skip(params.qstring.start).limit(parseInt(params.qstring.length)).toArray(function(err,data){
                    if(err){
                        common.returnOutput(params,{});
                    }
                    else{
                common.db.collection('screenshot_'+params.qstring.app_id)
                    .find({et:{$gte:args.startDate, $lte:args.endDate}})
                    .count(function(error,totalCount){
                                    if(!error){
                          // Last session, device id, date, time
                          var usersList = [];
                          // var result = _.groupBy(data,"did");
                          // var data = _.map(Object.keys(result), function(did){
                          //     var lastSession = result[did][result[did].length-1];
                          //     lastSession.did = did;
                          //     lastSession.session = result[did].length;
                          //     return lastSession;
                          // });
                          data.forEach(function(value, key){
                              var userid = common.crypto.createHash(semusiConfig.shaV1Hash).update(params.qstring.key + value.did + "").digest('hex');
                              var obj = {
                                ls          : moment(value.et*1000).format('MMM DD, YYYY HH:mm:ss'),
                                did         : '<a href="dashboard?action=users#/users/details/'+userid+'">'+value.did+'</a>',
                                date        : moment(value.et*1000).format('MMM DD, YYYY'),
                                time        : moment(value.et*1000).format('hh:mm:ss A'),
                                //session     : value.session
                              }

                              usersList.push(obj);
                            });

                            var obj = {
                              "draw": parseInt(params.qstring.draw),
                              "recordsTotal": totalCount,
                              "recordsFiltered": totalCount,
                              "data": usersList
                            }
                          common.returnOutput(params, obj);
                      }
                      else{
                          common.returnOutput(params,{});
                      }
                          });
            }
             })
    }

    /*
    //This function processes events recieved from client devices.
    screenshot.currentUsers = function(params){
        var argProps = {
                'startDate':{'required':true,'type':'Number'},
                'endDate':{'required':true,'type':'Number'}
            },
            args = {};

        if (!(args = common.validateArgs(params.qstring.args, argProps))) {
            common.returnMessage(params, 400, 'Not enough args');
            return false;
        }

        common.db.collection('screenshot_'+params.qstring.app_id).find({et:{$gte:args.startDate, $lte:args.endDate}},{ $orderby: { et : -1 }}).toArray(function(error, result){
            if(!error){
                if(result){
                    common.returnOutput(params, result );
                }
                else{
                    common.returnOutput(params, []);
                }
            }
            else{
                common.returnOutput(params, []);
            }
        });
    };*/

    // setup screenshot recording new configuration
    screenshot.saveScreenPlaybackSetting = function(params){
        var argProps = {
                'audid':{'required':true,'type':'String'},
                'name':{'required':true,'type':'String'}
            },
            args = {};

        if (!(args = common.validateArgs(params.qstring.args, argProps))) {
            return common.returnMessage(params, 400, 'Not enough args');
        }

        args.st = false;
        args.isDeleted = false;
        args.createdAt = moment().valueOf();
        common.db.collection('setup_screenshot_'+params.qstring.app_id).insert(args, function(error, result){
            if(!error){
                result.status = "success";
                return common.returnOutput(params, result);
            }
            else{
                let result = {}
                result.status = "error";
                return common.returnOutput(params, result);
            }
        });
    };

    // delete screenshot configuration
    screenshot.deleteScreenPlaybackSetting = function(params){
        var argProps = {
                'id':{'required':true,'type':'String'}
            },
            args = {};

        if (!(args = common.validateArgs(params.qstring.args, argProps))) {
            return common.returnMessage(params, 400, 'Not enough args');
        }

        common.db.collection('setup_screenshot_' + params.qstring.app_id).update({_id:common.db.ObjectID(args.id)},{$set:{isDeleted:true, updatedAt: moment().valueOf()}}, function(error, result){
            if(!error){
                result.status = "success";
                return common.returnOutput(params, result);
            }
            else{
                let result = {}
                result.status = "error";
                return common.returnOutput(params, result);
            }
        });
    };

    // get screenshot current recording list
    screenshot.getScreenPlaybackSettings = function(params){
        common.db.collection('setup_screenshot_'+params.qstring.app_id).find({isDeleted:false},{name:1, createdAt:1, st:1},{allowDiskUse: true}).sort({ createdAt : -1 }).toArray(function(error, result){
            if(!error){
                result.status = "success";
                return common.returnOutput(params, result);
            }
            else{
                let result = {}
                result.status = "error";
                return common.returnOutput(params, result);
            }
        });
    };

    // change setup screenshot status
    screenshot.changeScreenPlaybackSetting = function(params){
      var argProps = {
                'id':{'required':true,'type':'String'},
                'st':{'required':true,'type':'Boolean'}
            },
            args = {};

        if (!(args = common.validateArgs(params.qstring.args, argProps))) {
            return common.returnMessage(params, 400, 'Not enough args');
        }

        common.db.collection('setup_screenshot_'+params.qstring.app_id).findOne({isDeleted:false, _id:common.db.ObjectID(args.id)}, function(error, result){
            if(!error){
                common.db.collection('audiencesegment_'+params.qstring.app_id).findOne({"_id":common.db.ObjectID(result.audid)},function(err, audiencesegments) {
                    if(err){
                        let result = {}
                        result.status = "Audience is not found";
                        return common.returnOutput(params, result);
                    }
                    else{
                        // payload
                        let payload = {};
                        payload.st = args.st;
                        payload.camp_id = args.id;
                        // get screen playback configuration and setting
                        payload.qa = common.config.screenPlaybackQuality;
                        payload.cmd = common.config.screenPlaybackCommand;
                        payload.url = common.config.screenPlaybackUrlDev;
                        payload.key = common.config.screenPlaybackAuthKeyDev;
                        if(common.config.IsProduction){
                            payload.url = common.config.screenPlaybackUrlProd;
                            payload.key = common.config.screenPlaybackAuthKeyProd;
                            payload.name = common.config.screenPlaybackHeaderKeyProd;
                        }

                        // send notification
                        sendNotification(params, audiencesegments.segmentinfo, payload);

                        //update screenshot setting status
                        common.db.collection('setup_screenshot_'+params.qstring.app_id).update({_id:common.db.ObjectID(args.id)},{$set:{st:args.st}}, function(error, updateRes){
                            if(error){
                                updateRes.status = "failed";
                                return common.returnOutput(params, updateRes);
                            }
                            else{
                                updateRes.status = "success";
                                return common.returnOutput(params, updateRes);
                            }
                        });
                    }
                });
            }
            else{
                let result = {};
                result.status = "Sorry, incorrect session recored setup";
                return common.returnOutput(params, result);
            }
        });
    };

    // send notification to users
    function sendNotification(params, segmentinfo, payload){
        //Build match criteria based on audience segment.
        var criteria = [];
        if(segmentinfo && segmentinfo.who && segmentinfo.who.length>0){
            criteria = segmentinfo.who;
        }
        if(segmentinfo && segmentinfo.where && segmentinfo.where.length>0){
            //Add only geo category items to criteria.
            segmentinfo.where.forEach(function(item){
                if(item.category=='Geo'){
                    criteria.push(item);
                }
            });
        }
        var match = common.constructMatchFromCriteria(criteria);
        //match.gcmid = {'$exists':true};
        match.active = true;

        // get GCM key and iOS APN
        campaignUtils.getGCMKeyAndiOSCert(params.qstring.app_id)
            .then((appKeyCert) =>{
                // get users GCM token or APN token
                campaignUtils.getUsersMsgToken(match, params.qstring.app_id)
                    .then(([gcmids, fcmids]) =>{
                        // check gcm key and platform for send android user push
                        if(appKeyCert.android.dev || appKeyCert.android.prod){
                            // check production gcm key if not exists use dev gcm key
                            var GCMKEY = (appKeyCert.android.prod)? appKeyCert.android.prod : appKeyCert.android.dev;
                            //sendGCM(GCMKEY, gcmids, payload)
                            campaignUtils.sendAndroidNotification(appKeyCert.fcmKey, GCMKEY, gcmids, fcmids, payload, false, 'setup_screenshot_'+params.qstring.app_id);
                        }

                        // define iOS APN property
                        var options = {
                            keyFile : "",
                            certFile : "",
                            debug : true
                        },
                        iosCert ='',
                        iosKey = '';

                        // dev mode certificates
                        if(appKeyCert.ios.dev.cert1 && appKeyCert.ios.dev.cert1!=""){
                            iosCert = appKeyCert.ios.dev.cert1;
                        }
                        if(appKeyCert.ios.dev.cert2 && appKeyCert.ios.dev.cert2!=""){
                            iosKey = appKeyCert.ios.dev.cert2;
                        }

                        //production mode data for push.
                        if(appKeyCert.ios.prod.cert1 && appKeyCert.ios.prod.cert1!=""){
                            iosCert = appKeyCert.ios.prod.cert1;
                        }
                        if(appKeyCert.ios.prod.cert2 && appKeyCert.ios.prod.cert2!=""){
                            iosKey = appKeyCert.ios.prod.cert2;
                        }

                        // check and validate iOS APN certificates
                        common.checkAppleCertificate(params.qstring.app_id, iosCert, iosKey, function(resCertificate){
                            if(resCertificate){
                                // include certificates certificates
                                options.certFile = path.join(__dirname,"../../../frontend/express/public/appcertificates/" + params.qstring.app_id +"/"+ iosCert);
                                options.keyFile = path.join(__dirname,"../../../frontend/express/public/appcertificates/" + params.qstring.app_id +"/"+ iosKey);
                                // send android push
                                sendAPN(options, gcmids, payload);
                            }
                            else{
                                 
                                return;
                            }
                        });
                    })
                    .catch((error) =>{
                        logger.error(`GCM or APN topen not found!  ${error}`);
                        return
                    });
            })
            .catch((error) =>{
                logger.error(`GCM key or APN cert Does not exist!  ${error}`);
                return
            });
    }

    // send GCM to end users
    // function sendGCM(gcmkey, gcmids, payload){
     
    //     if(gcmids.length > 100){
    //         while(gcmids.length > 0){
    //             var userGcms = gcmids.slice(0, 100);
    //             campaignUtils.sendGCMMessageWithCommand(gcmkey, userGcms, payload);
    //             gcmids.splice(0, 100);
    //         }
    //     }
    //     else{
    //         campaignUtils.sendGCMMessageWithCommand(gcmkey, gcmids, payload);
    //     }
    // }

    // send GCM to end users
    function sendAPN(options, tokens, payload){
        tokens.forEach(function(token){
            campaignUtils.sendAPNMessageWithPayload(options, tokens, payload);
        });
    }
}(screenshot));
module.exports = screenshot;
