var campaignCommon = {},
    moment = require('moment'),
    logger = require('../../logger'),
    semusiConfig = require('./../config'),
    common = require('./common'),
    gcm = require('node-gcm'),
    cacheApi = require('./semusi.cache.js'),
    async = require('async'),
    templateApi = require('./../parts/mgmt/templates');

(function (campaignCommon) {
    campaignCommon.validateCampaignUser = function(appid, campid, did, callback){
        logger.info(`campaignuser_ => ${appid}:::: campid => ${campid} :: did => ${did}`);
        cacheApi.client.hget("campaignuser_"+appid+""+campid, did, function(err, data){
            logger.error(`error=> ${err}`);
            logger.info(`data  :: +> ${data}`);
            if(err){
                callback(err, false, null);
            }
            else{
                data = JSON.parse(data);
                if(data && data.st != undefined && data.st === false){
                    // update user status
                    data.st = true;
                    cacheApi.client.hset("campaignuser_"+appid+""+campid, did, JSON.stringify(data), function(err, res){
                        logger.error(`error=> ${err}`);
                        logger.info(`res  :: +> ${res}`);  
                    });
                    callback(null, true, data);
                }
                else{
                    callback(null, false, data);
                }
            }
        });
    }

    campaignCommon.validateCampaignEvent = function(appid, campid, event, did, user_id, userCache){
        logger.info(`campaignevent_ => ${appid}:::: campid => ${campid} :: did => ${did}`);
        cacheApi.client.hgetall("campaignevent_"+appid+""+campid, function(err, campEvents){
            logger.error(`error=> ${err}`);
            logger.info(`Events  :: +> ${event}`);
            if(err){
                logger.error(`campaignevent error=> ${err}`);
            }
            else{
                if(campEvents){
                    logger.info("check event into event list");
                    if(campEvents[event]){
                        logger.info("found event into event list");
                        // let currentEvent = JSON.parse(events[event]);
                        // if(currentEvent.operator == 'eq'){
                        //     // prepare query for keen
                        //     let eventKeys = Object.keys(events);
                        //     let steps = [];
                        //     eventKeys.forEach(function(keyName){
                        //         if(keyName != event){
                        //             let item = JSON.parse(events[keyName])
                        //             let obj={
                        //                 "event_collection": 'event_'+params.qstring.app_id+"_"+item.operand,
                        //                 "with_actors" : false,
                        //                 "actor_property": 'user_id',
                        //                 "timeframe": "previous_15_days",
                        //                 filters:[]
                        //             };
                        //             if(item.operator){
                        //                 // add event into filter
                        //                 // let filter={};
                        //                 // filter.property_name = 'key';
                        //                 // filter.operator = (item.value)?item.operator:'$ne';
                        //                 // filter.property_value = item.operand;
                        //                 // obj.filters.push(filter);
                        //                 // add user into filter
                        //                 let filter={};
                        //                 filter.property_name = 'did';
                        //                 filter.operator = 'eq';
                        //                 filter.property_value = did;
                        //                 obj.filters.push(filter);
                        //             }
                        //             steps.push(obj);
                        //         }
                        //     });

                         
                        //     keen.getFunnelResults(steps,function(data){
                         
                        //         campaignCommon.addUserAndSendPush(appid, campid, did, user_id);
                        //     });
                        // };
                        if(userCache && userCache.e && userCache.st == undefined){
                            logger.info("st is undefined into user list");
                            userEvents = JSON.parse(userCache.e);
                            isEventExists = false;
                            //userEvents.forEach(function(uEvent){
                            let currentEvent = JSON.parse(events[event]);
                            for(let i=0; i<userEvents.length; i++){
                                logger.info(`userEvents[i].k => ${userEvents[i].k }  event==> ${event}`)  
                                if(userEvents[i].k == event){
                                    isEventExists = true;
                                    logger.info(`check process status and segment type ::> ${userEvents[i].p} <<=>> ${currentEvent.value}`);
                                    if(userEvents[i].p && currentEvent.value){
                                        userEvents[i].p = false;
                                        userEvents[i].s = true;
                                    }
                                    break;
                                }
                            }

                            if(!isEventExists){
                                logger.info("event is not exists");
                                campaignCommon.addEventUserList(appid, campid, did, event, user_id, userEvents, campEvents);
                            }
                        }
                        else{
                            logger.info("user not exists");
                            campaignCommon.addEventUserList(appid, campid, did, event, user_id, false, campEvents);
                        }
                    }
                }
            }
        });
    }

    campaignCommon.addEventUserList = function(appid, campid, did, event, user_id, userEvents, campEvents){
        let importMulti = cacheApi.client.multi();
        if(userEvents){
            logger.info("user has event and validate events");
            // validate campaign event and user event for send campaign
            let isSendCamp = true;
            campEvents.forEach(function(campEvent){
                for(let i=0; i<userEvents.length; i++){
                    logger.info(`condtion check :: ${(campEvent.value && userEvents[i].p === false) || (campEvent.value === false && userEvents[i].p)}`)
                    if( (campEvent.value && userEvents[i].p === false) || (campEvent.value === false && userEvents[i].p) ){
                    }
                    else{
                        isSendCamp = false;
                    }
                    break;
                }
            });

            let obj = {e:userEvents};
            // send campaign to user
            if(isSendCamp){
                logger.info(`${appid} :: send campaign :: ${user_id}`);
                obj.st = false;
                campaignCommon.sendPush(appid, user_id);
            }
            logger.info(`old user object update:: => ${obj}`);
            // update event process and status in cache
            importMulti.hmset("campaignuser_"+appid+""+campid, did, JSON.stringify(obj));
            importMulti.exec(function(err,results){
                if (err) {
                    logger.info(`campid:: ${campid}`);
                    logger.error(` error while process event import in cache ==>> ${err}`);
                } else {
                    logger.info(`done campaign :: ${results}`);
                }
            });
        }
        else{
            logger.info("add new user into list");
            let eventLists = [];
            // dump all event into new user list
            campEvents.forEach(function(item){
                if(item.operand == event){
                    eventLists.push({k:item.operand,p:false,s:true});
                }
                else{
                    eventLists.push({k:item.operand,p:true,s:false});
                }
            });
            logger.info(`new user event list:: ${eventLists}`);
            importMulti.hmset("campaignuser_"+appid+""+campid, did, JSON.stringify({e:eventLists}));
            importMulti.exec(function(err,results){
                if (err) {
                    logger.info(`campid ::${campid}`);
                    logger.error(`error::  error while process event in cache => ${err}`);
                } else {
                    logger.info(`done campaign ::${results}`); 
                }
            });
        }
    }

    campaignCommon.sendPush = function(appid, user_id){
        // add user into cache
        common.db.collection('apps').findOne({"_id":common.db.ObjectID(appid), "isAppDeleted":"false","gcm_key": { $exists: true, $ne: null }},function(err,appData){
            if(err){
                logger.error(`apps error=> ${err}`);  
            }
            else{
                common.db.collection('app_users'+appid).findOne({_id:user_id},{"gcmid":1},function(err, userData){
                    if(!err && userData && userData.gcmid){
                        let sender = new gcm.Sender(appData.gcm_key);
                        let message = new gcm.Message();
                        message.addData('message',"#CAMPAIGNUPDATE");
                        message.delay_while_idle = 1;
                        sender.sendNoRetry(message, [userData.gcmid], function (err, result) {
                            logger.error(`error=> ${err}`);
                            logger.info(`results:: ${result}`);
                            logger.info(`GCM-Push sent to:: ${userData.gcmid}`);
                        });
                    }
                });
            }
        });
    }

    // check live campaign while user did it
    campaignCommon.checkLiveEventCampaign = function(event){
        cacheApi.getKey(event.key + "_" + event.appid, function(err, data){
            if(!err && (data != null && data != '') ) {
                data = JSON.parse(data);
                cacheApi.addToSadd('delayed_campaigns', event.key + "_" + event.appid + "_" + event.did, function(response){
                    if(response){
                        logger.info(`event.etime:: ${event.etime}`);   
                        cacheApi.deleteKey(event.key + "_" + event.appid + "_" + event.did, function(){
                            cacheApi.setKey(event.key + "_" + event.appid + "_" + event.did, JSON.stringify({did:event.did, evt:event.key, camp: data, appid: event.appid, etime:event.etime}));
                            cacheApi.expire(event.key + "_" + event.appid + "_" + event.did, parseInt(data.delaySec));
                        });
                    }
                });
            }
        });
    }

    // Dealyed campaign watcher
    campaignCommon.delayedCampaignWatcher = function(){
        // get delayed campaigns users list
        cacheApi.getMembers("delayed_campaigns", function(err, keys){
            logger.error(`checkLiveEvents watcher err => ${err}`);
            logger.info(`keys  :: +> ${keys}`);
            if(!err && (keys != null && keys != '') ) {
                let importMulti = cacheApi.client.multi();
                let isExecute = false;
                let popKeys = [];
                let campaignsObj = {}

                logger.info(`keys  :: +> ${keys}`);
                async.forEach(keys, function(key, callback){
                    // check user event expire time
                    cacheApi.checkExpireTime(key, function(time){
                        logger.info(`key => ${key} && time =>> ${time}`);  
                        if(time <= 60 || time <= 65){
                            // get expire user data
                            cacheApi.getKey(key, function(err, campData){
                                if(!err && (campData != null && campData != '')){
                                    logger.error(`error => ${err}`);
                                    logger.info(`campData  :: +> ${campData}`);
                                    campData = JSON.parse(campData);
                                    if(campData.evt){
                                        isExecute = true;
                                        let events = [{k:campData.evt,p:false,s:true, et:campData.etime}];
                                        let obj = {st:false, e:events}
                                        logger.info(`hmset key campaignuser_::  ${campData.appid}  :: ${campData.camp._id} :: ${campData.did}`)
                                        importMulti.hmset("campaignuser_"+campData.appid+""+campData.camp._id, campData.did, JSON.stringify(obj));
                                        popKeys.push(key);

                                        // if campaign does not exists
                                        if(campaignsObj[campData.appid+""+campData.camp._id] === undefined){
                                            campaignsObj[campData.appid+""+campData.camp._id] = []; //campData.camp;
                                        }

                                        campaignsObj[campData.appid+""+campData.camp._id].push({campData: campData.camp, appid : campData.appid, did: campData.did})
                                    }
                                    else{
                                        // send silent GCM and APN push
                                        let params = {
                                                        qstring:{
                                                                app_id:campData.appid
                                                            }
                                                        }
                                        // stringify segment information
                                        // if(campData.camp.segmentinfo){
                                        //     campData.camp.segmentinfo = JSON.stringify(campData.camp.segmentinfo);
                                        // }

                                        // send push notification
                                        templateApi.silentPushForCampaignUpdate(params, campData.camp, "#CAMPAIGNUPDATE", true);

                                        // remove memeber form delayed_campaigns list
                                        cacheApi.removeMember("delayed_campaigns", key, function(error, result){
                                            if(error){
                                                logger.error(`Error while remove delayed_campaigns member==>>>> ${error}`) 
                                            }
                                        });
                                    }
                                }
                                callback();
                            });
                        }
                        else{
                            callback();
                        }
                    });
                }, function(error, result){
                    if(error){
                        logger.error(`watcher execution error=> ${error}`);
                    }
                    else{
                      isExecute = false;
                        if(isExecute){ // add users event into live event
                            importMulti.exec(function(err,results){
                                if (err) {
                                    logger.error(`error whiel import bulk record in cache => ${err}`);
                                    logger.info(`datais.campid:: => ${datais.campid}`);     
                                } else {
                                    logger.info(`done campaign:: => ${results}`); 
                                }

                                // run loop based on object keys that has appid and campid
                                Object.keys(campaignsObj).forEach(function(campObj){

                                    // get campaigns
                                    campaignsObj[campObj].forEach(function(camp){
                                        // send silent GCM and APN push
                                        let params = {
                                                        qstring:{
                                                                app_id:camp.appid
                                                            }
                                                        }
                                        // stringify segment information
                                        if(camp.campData.segmentinfo){
                                            camp.campData.segmentinfo = JSON.stringify(camp.campData.segmentinfo);
                                        }
                                        // send push notification
                                        templateApi.silentPushForCampaignUpdate(params, camp.campData, "#CAMPAIGNUPDATE", true, camp.did);
                                    });
                                });

                                // remove user from popKeys
                                popKeys.forEach(function(key){
                                    // remove memeber form delayed_campaigns list
                                    cacheApi.removeMember("delayed_campaigns", key, function(error, result){
                                        if(error){
                                            logger.error(`Error while remove delayed_campaigns member==>> ${error}`);   
                                        }
                                    });
                                })
                            });
                        }
                    }
                });
            }
        });
    }

}(campaignCommon));
module.exports = campaignCommon;
