var netcoreEmailAPI = {},
    common = require('./../../utils/common.js'),
    logger = require('../../../logger'),
    cacheApi = require('./../../utils/semusi.cache.js'),
    request = require('request'),
    moment = require('moment'),
    winstonLogger = require('./../../utils/winston'),
    commonEvent = require('./../../utils/common.event.js'),
    async = require('async');

let nodemailer = require('nodemailer');
let errorHandler = require('./../../utils/error.handler.js');

let appData={};


(function (netcoreEmailAPI) {
    //set app data
    netcoreEmailAPI.setAppData = function(data){
        appData = data;
    }

    //set app data
    netcoreEmailAPI.getAppData = function(){
        return appData
    }

    // get all apps ids
    netcoreEmailAPI.getAllAppsIds = function(appdata, callback){
        //isAppDeleted:"true"
        let appid = appdata.app_id;
        netcoreEmailAPI.setAppData(appdata);

        common.db.collection('apps').find({_id:common.db.ObjectID(appid),isAppDeleted:"false",emailCfg:{$exists: true}},{_id:1,emailCfg:1}).toArray(function (err, apps){
            if(err){
                callback(err, null);
            }
            else{
                callback(null,apps);
            }
        });
    }

    netcoreEmailAPI.processActiveCampaigns = function(apps, fncallback){
        async.each(apps, function(app, callback){
            let match = {}
            match.sd = {$lte:common.getCurrentEpochTime()*1000};
            match.ed = {$gte:common.getCurrentEpochTime()*1000};
            match.st = "ACTIVE";
            match.t = 'Email';
            //match.isRun = {$exists:false};
            let app_id = app._id;
            logger.info(`camp match ${match}`)
            common.db.collection('campaigns_'+ app._id).aggregate([
                {$match:match},
                {$sort:{ud: -1,_id:1}}

            ],function(err,campaigns){
                logger.info(`campaigns=> ${campaigns}`);
                if(err){
                    logger.error(`error=> ${err}`); 
                    callback();
                }
                else{
                    logger.info(`get campaigns=> ${campaigns}`);
                    async.each(campaigns, function(camp, callback){
                        // validate campaign on hrs bases
                        let currentEpoch = common.getCurrentEpochTime();

                        if(camp.diff.indexOf("+") >= 0){
                            currentEpoch = parseInt(currentEpoch) + parseInt(camp.diff);
                        }
                        else{
                            currentEpoch = parseInt(currentEpoch) - parseInt(camp.diff)
                        }

                        logger.info(`currentEpoch ${currentEpoch} :: camp email=> ${camp._id}`);
                        let currentHrs = moment(currentEpoch*1000).format('HH');
                        logger.info(`${parseInt(camp.time[0])} <= ${parseInt(currentHrs)} && ${parseInt(camp.time[1])} >= ${parseInt(currentHrs)}`)
                        if( parseInt(camp.time[0]) <= parseInt(currentHrs) && parseInt(camp.time[1]) >= parseInt(currentHrs) ){
                            logger.info('start camp loop') 
                            async.parallel([
                                function(callback){
                                    logger.info('get audiencesegment')
                                    common.db.collection('audiencesegment_'+app_id).findOne({_id:common.db.ObjectID(camp.aud), "isDeleted":false}, function(err, audience){
                                        if(err){
                                            callback(err)
                                        }
                                        else{
                                            camp.segmentinfo = audience.segmentinfo;
                                            callback();
                                        }
                                    })
                                }
                            ],function(err){
                                if(err){
                                    logger.error(`error in audience segment => ${err}`)
                                    callback(err);
                                }
                                else{
                                    let match = {"active": true, "user_info":{$exists:true}}, isProcess = true;
                                    // process who
                                    camp.segmentinfo.who.forEach(function(who){
                                        match[who.operand] = {};
                                        match[who.operand]["$"+who.operator] = who.value;
                                    });
                                    // process where
                                    camp.segmentinfo.where.forEach(function(wheres){
                                        match[wheres.operand] = {};
                                        match[wheres.operand]["$"+wheres.operator] = wheres.value;
                                    });
                                    // process where
                                    camp.segmentinfo.when.forEach(function(when){
                                        match[when.operand] = {};
                                        match[when.operand]["$"+when.operator] = when.value;
                                    });

                                    // validate event
                                    if(camp.segmentinfo.what.length > 0
                                        && camp.segmentinfo.when.length == 0
                                        && camp.segmentinfo.where.length == 0
                                        && camp.segmentinfo.who.length == 0 ){
                                        isProcess = false;
                                    }

                                    if(isProcess){
                                        //app users
                                        logger.info(`fetch user data >> ${app_id}`);
                                        logger.info(`match ==>> ${match}`);
                                        common.db.collection('app_users'+app_id).find(match,{"user_info":1, did:1, tz:1, le:1, _id:1}).toArray(function (err, deviceids) {
                                                if(err){
                                                    logger.error(`user not found => ${err}`)
                                                    callback();
                                                }
                                                else{
                                                    let deviceArr = [];
                                                    logger.info(`push to >> ${deviceids}`);
                                                    let credentials = app.emailCfg[camp.e_cfg];
                                                    if(deviceids && deviceids.length>0){
                                                        for (let i = 0; i < deviceids.length ;i++) {
                                                            if(deviceids[i].user_info && deviceids[i].user_info.e){
                                                                let msg = camp.m_cont.replace(/<!-- ngIf: tobj.messageContent -->/g,"");
                                                                msg = camp.m_cont.replace(/<!-- end ngIf: tobj.messageContent -->/g,"");
                                                                msg = camp.m_cont.replace(/<!-- ngIf: tobj.messageContent --><!-- end ngIf: tobj.messageContent -->/g,"");

                                                                //deviceArr.push(deviceids[i].user_info.e);
                                                                if(camp.e_cfg == 'netcore'){
                                                                    logger.info(`camp.e_cfg >> ${camp.e_cfg}`);   
                                                                    netcoreEmailAPI.sendEmailWithNetcore(deviceids[i], msg, app_id, credentials, camp._id, camp.m_sub)
                                                                }
                                                            }
                                                        }

                                                       /* if(deviceArr.length > 0){
                                                            // send message through netcore
                                                            if(camp.e_cfg == 'netcore'){
                                                                netcoreEmailAPI.sendEmailWithNetcore(deviceArr, msg, app_id, credentials)
                                                            }
                                                        }*/
                                                        callback();
                                                    }
                                                    else{
                                                        callback();
                                                    }
                                                }
                                        });
                                    }
                                    else{
                                        callback();
                                    }
                                }
                            });
                        }
                        else{
                            callback();
                        }

                    }, function(err, result){
                        if(err){
                            logger.error(`error in campaigns => ${err}`);
                            callback(false);
                        }
                        else{
                            logger.info(`done campaigns`);  
                            callback();
                        }
                    });
                }
            });
        }, function(err, result){
            if(err){
                logger.error(`error in app => ${err}`); 
                fncallback(false)
            }
            else{
                logger.info('send email via apps');
                fncallback(true);
            }
        });
    }

    netcoreEmailAPI.updateCampaign = function(appid,campid){
        logger.info("call email updateCampaign")
        common.db.collection('campaigns_'+ appid).update({_id:common.db.ObjectID(campid)},{$set:{isRun:true}}, function(err, update){
            if(!err){
                logger.info(`update email campaign ==>>> ${campid}`);   
            }
            else
            {
                logger.error(`email update error => ${err}`);
            }
        });
    }

    netcoreEmailAPI.sendEmailWithNetcore = function(user, msg, app_id, credential, campid, subject){
        let to = user.user_info.e;
        let transporter = nodemailer.createTransport("SMTP",{
            service: 'SendGrid',
            host: credential.smpt_h, // hostname
            secureConnection: false, // use SSL
            port: parseInt(credential.smpt_po), // port for secure SMTP
            auth: {
                user: credential.smpt_un,
                pass: credential.smpt_ps
            }
        });
        // let transporter = nodemailer.createTransport("SMTP", {
        //     service: "SendGrid",
        //     auth: {
        //         user: "",
        //         pass: "***"
        //     }
        // });

        let aData = netcoreEmailAPI.getAppData();
        // add hidden image for check view email event
        msg += '<img style="display:none;" src="'+semusiConfig.host+'/i/campaigns/updateEmailStats?app_id='+app_id+'&app_key='+aData.app_key+'&api_key='+aData.api_key+'&userid='+user._id+'&campid='+campid+'" style="height:1px; width:1px;" />';

        // Message object
        let message = {
            // sender info
            from: "appICE <hello@appice.com>",
            // Comma separated list of recipients
            to: to,
            // Subject of the message
            subject: subject, //
            /*
            headers: {
                'X-Laziness-level': 1000
            },*/

            // plaintext body
            //text: 'Hello to myself!',

            // HTML body
            html:msg
        }

        user.campid = campid;
        user.app_id = app_id;
        user.user_id = user._id;
        user.key = "Campaign_Received";
        logger.info('send event')
        commonEvent.sendEvent(user);

        //let url = semusiConfig.netcoreConfig.API;
         
        transporter.sendMail(message, function (error) {
            if (error) {
                logger.error(`Error sending email=> ${error.message}`);
                netcoreEmailAPI.createCallBackLog(app_id,{email:to, campid:campid, status:"failed", error:error.message})
                return;
            }
            else{
                logger.info("done ");
                netcoreEmailAPI.createCallBackLog(app_id,{email:to, campid:campid, status:"success"})
                user.campid = campid;
                user.app_id = app_id;
                user.user_id = user._id;
                user.key = "Campaign_Received";
                logger.info('send event')
                commonEvent.sendEvent(user);
            }
        });

        // update campaign
        netcoreEmailAPI.updateCampaign(app_id, campid);
    }

    netcoreEmailAPI.createCallBackLog = function(app_id, data){
        // let logDir = semusiConfig.callbackLog;
        // let fileName = logDir + "/email_"+ app_id + "_" + moment().year()+''+(moment().month()+1)+''+moment().date()+".log";
        // let log = fs.createWriteStream(fileName, {'flags': 'a'});
        // // use {'flags': 'a'} to append and {'flags': 'w'} to erase and write a new file
        // log.end(JSON.stringify(data,null,4)+",");
        winstonLogger.init('email_'+app_id, true);
        winstonLogger.writeData(data);
    }

    netcoreEmailAPI.eventCampaign = function(campid, app_id, eventName){
        let match = {}
        match.st = "ACTIVE";
        match.t = 'Email';
        match._id = common.db.ObjectID(campid);
        common.db.collection('campaigns_'+ app_id).findOne(match,function(err,campaign){
            if(err){
                logger.error(`app campaign not found in EventCampaign  => ${err}`); 
                 
            }
            else{
                if(campaign){
                    // get audience segment information
                    common.db.collection('audiencesegment_'+app_id).findOne({_id:common.db.ObjectID(campaign.aud), "isDeleted":false}, function(err, audience){
                        if(err){
                            logger.error(`audience sengment not found!  => ${err}`); 
                        }
                        else{
                            let match = {"active": true, "user_info":{$exists:true}}, isProcess = false;
                            campaign.segmentinfo = audience.segmentinfo;
                            // process where
                            campaign.segmentinfo.what.forEach(function(what){
                               if(what.operand == eventName){
                                    isProcess = true;
                               }
                            });

                            logger.info('fetch user data')
                            if(isProcess){
                                common.db.collection('app_users'+app_id).aggregate([
                                    {$match: match},
                                    {$project:{"user_info":1}}
                                ],function (err, deviceids) {
                                    if(err){
                                        logger.error(`user not found!  => ${err}`);  
                                    }
                                    else{
                                        let deviceArr = [];

                                        if(deviceids && deviceids.length>0){
                                            for (let i = 0; i < deviceids.length ;i++) {
                                                if(deviceids[i].user_info && deviceids[i].user_info.e){
                                                    deviceArr.push(deviceids[i].user_info.e);
                                                }
                                            }
                                            //deviceArr = deviceArr.replace(/,/g,"|");
                                            let msg = campaign.m_cont.replace(/<!-- ngIf: tobj.messageContent -->/g,"");
                                            let credentials = {
                                                                "un" : "2000166216",
                                                                "ps" : "abmtts"
                                                            };//app.emailCfg[campaign.e_cfg];
                                            // send message through netcore
                                            if(campaign.e_cfg == 'netcore'){
                                                netcoreEmailAPI.sendEmailWithNetcore(deviceArr, msg, app_id, credentials)
                                            }
                                        }
                                    }
                                });
                            }
                            else{
                                logger.info(`event not mached  ${eventName}`);
                            }
                        }
                    })
                }
            }
        });
    }

    // Email states callback
    netcoreEmailAPI.updateViewStats = function(params){
        logger.info(`updateViewStats params.qstring => ${params.qstring}`); 
        common.db.collection('app_users'+params.qstring.app_id).findOne({_id:params.qstring.userid},{did:1, tz:1, le:1, _id:1},function (err, user) {
            if(err){
                logger.error(`user not found => ${err}`);
                return common.returnMessage(params, 200, 'Failed');
            }
            else{
                if(user){
                    user.campid = params.qstring.campid;
                    user.app_id = params.qstring.app_id;
                    user.user_id = user._id;
                    user.key = "Campaign_Viewed";
                    logger.info('send event')
                    commonEvent.sendEvent(user);
                }
                return common.returnMessage(params, 200, 'Success');
            }
        });
    }

}(netcoreEmailAPI));

module.exports = netcoreEmailAPI
