/**
 * FCM nodejs module
 * @author Manish Yadav
 * @copyright Semusi Technologies PVT LTD
 */
'use strict'
const FCM = require('fcm-node'),
    Promise = require('bluebird'),
    logger = require('../../logger'),
    appiceConfig = require('./../config'),
    uuid = require('uuid'),
    semusiConfig = require('../../api/config'),
    sendAppInbox = require('./AppInbox.utils.js');
const https = require('https');
const admin = require('firebase-admin');
const HttpsProxyAgent = require('https-proxy-agent');
/**
 * Send FCM message
 * @param registrationToken use for token to be need send fcm message
 *   [token1, token2]
 * @param data has custom data key value object like 
 *   :::: your_custom_data_key: 'your_custom_data_value'
 * @param notification has title and body in object format that will visiable to end user 
 * {
        title: 'Title of your push notification',
        body: 'Body of your push notification'
    }
 * Return array that haven't got FCM or error if occured  
 */
exports.sendMessageWithPayload = function (fcmKey, registrationToken, dids, data, active, app_id, cid, campaigns, appId) {
    return new Promise((resolve, reject) => {
        try {
            let sdkvs = [];
            logger.info(`sendMessage call => ${appId}`);
            sendMessage(registrationToken, data, sdkvs, fcmKey, appId, dids, cid, campaigns)
                .then((response) => {
                    response = (typeof response === 'string') ? JSON.parse(response) : response;
                    return resolve(response)
                })
                .catch((error) => {
                    return reject(error)
                })
        } 
        catch (error) {
            return reject(error);
        }
    });
}

function sendNotificationForMulti(message, app_id, cid) {
    admin.messaging().sendMulticast(message)
        .then((response) => {
            logger.info(`Message sent successfully: ${response}`);
            campaignUtils.increaseCountResult(app_id, cid, 1);
        })
        .catch((err) => {
            logger.info("Error occurred during push notification:", err);
            logger.error(`Something has gone wrong! ${err.message}=====>campid===> ${cid}`);
        });
}

function sendNotificationForSingle(message, app_id, cid) {
    admin.messaging().send(message)
        .then((response) => {
            logger.info(`Message sent successfully: ${response}`);
            campaignUtils.increaseCountResult(app_id, cid, 1);
        })
        .catch((err) => {
            logger.info("Error occurred during push notification:", err);
            logger.error(`Something has gone wrong! ${err.message}=====>campid===> ${cid}`);
        });
}


// send FCM message and return reponse or error
let sendMessage = function (registrationToken, data, sdkvs, jsonFile, app_id, dids, cid, campaigns) {
    return new Promise(async (resolve, reject) => {
        const campaignUtils = require('./campaign.utils.js');
        try {
            logger.info(` FCM sendMessage ========CampaignId =========${cid}`);

            // Firebase initialization
            if (admin.apps.length === 0) {
                const adminConfig = {
                    credential: admin.credential.cert(jsonFile),
                };

                let http_proxy = semusiConfig.http_proxy;
                if (http_proxy) {
                    const agent = new HttpsProxyAgent(http_proxy);
                    adminConfig.httpAgent = agent;
                }

                admin.initializeApp(adminConfig);
            }

            let segment = JSON.parse(campaigns.segmentinfo);
            if(campaigns.t == "IN-APP" || (segment.what.length > 0 && segment.who.length > 0) || segment.what.length > 0){
                //Case of Inapp, Who+What or WHAT only 
                logger.info(`Case Inapp =======> ${campaigns.t == "IN-APP"} ========OR ===  SEGMENT====> ${JSON.stringify(segment)}`)
                logger.info(`=======CampaignId =========${cid}`)
                //Case of Inapp, Who+What or WHAT only 
                logger.info(`Case Inapp =======> ${campaigns.t == "IN-APP"} ========OR ===  SEGMENT====> ${JSON.stringify(segment)}`)
                logger.info(`=======CampaignId =========${cid}`)
                sendMessage.sendInAppPush(app_id,registrationToken,jsonFile,cid,campaigns);
            }
            else{
                // In case of Draft We won't send the push
                if( campaigns.st =='DRAFT'){
                    logger.info(`Push Won't be sent In case of deactivaton In FCM`)
                    return
                }
                // this else part works for Normal push
                logger.info(`app id  :: +> ${app_id}`);
                delete data.aud;
                /* remove boi-demo payload */
                // PASTED CODE STARTS
                if (semusiConfig.serverDomain == 'https://gcc.appice.io' || semusiConfig.serverDomain == 'https://gccuatpanel.appice.io' || semusiConfig.serverDomain == 'https://gccpreprod.appice.io') {
                    //Notification Type
                    if (app_id == '5efc23b444776e69dbacdf02' || app_id == '5efc240122ab3a69da580e6f' || app_id == '5efc235b22ab3a69da580e69') {

                        logger.info("GCC Appid's started");
                        //Send 1k Devices at One Time to FCM
                        sendMessage.getUserIds(app_id, dids).then(async (userids) => {
                                // constructing only one nid for device
                                const nid = uuid.v4();
                                let userId = [];
                                let onlyUserids = [];            //creating onlyUserids only
                                userids.forEach(u => {
                                    userId.push({
                                        did : u.did,
                                        UserId : common.getUserIdObject(u)
                                    });
                                });
                                //Checking if User details are present
                                if(userId && userId.length > 0){
                                    onlyUserids = userId.map((item) => item.UserId)
                                }
                                logger.info(`userId===>${JSON.stringify(userId)}`)
                                let useridslength = onlyUserids;
                                let adid = dids[0];
                                let uattime = new Date();
                                let uatepochTime = parseInt(uattime.getTime() / 1000);

                                userId.forEach((user) => {
                                    if(user.UserId && user.UserId.length > 0){
                                        let et = 0;
                                        if (campaigns.appinbox_et == 0 || campaigns.appinbox_et == null || campaigns.appinbox_et == undefined) {
                                            et = parseInt(campaigns.ed / 1000); //appinbox Expiry time   
                                        }else{
                                            et = parseInt(campaigns.appinbox_et / 1000);
                                        }
                                        let result = {
                                            "nid": nid,
                                            "mid": nid,
                                            "notificationId": nid,
                                            "campid": cid,
                                            "uat": uatepochTime,
                                            "ni": data.ni,
                                            "nm": data.nd,
                                            "nt": data.nh,
                                            "ct": "pn",
                                            "st": "unread",
                                            "et": et,
                                            "ln": "en-us",
                                            "cdata": data.cdata
                                        };
                                        //Incase of asb Manipulatte the appinbox Payload
                                        if (data.ty === 'asb') {
                                            let fileExtension = data.and.m ? data.and.m.split('.').pop() : null;
                                            let fileType = fileExtension || ""; // Default to empty string if no extension is found
                                            let thumbnailUrl = '';

                                            //For Mp4 there will be no frame in the and so we will pick from cdata
                                            if (fileType === 'mp4') {
                                                thumbnailUrl = data.cdata.th || '';
                                            } else {
                                                let fileName = data.and.b + (data.and.i[0] || "") + "." + (data.and.f || "");
                                                thumbnailUrl = fileName;
                                            }

                                            result.cdata.imageUrl = data.and.m || ''; // Full URL of media; default to empty string if missing
                                            result.cdata.th = thumbnailUrl;
                                        }
                                        logger.info(`android inbox Created =====>campid===> ${cid}`)

                                        if (campaigns.dlvy === 'i' || campaigns.dlvy === 'a') {
                                            user?.UserId.forEach((item) => {
                                                sendAppInbox.saveUserIDAppInboxdata(app_id, user.did, item, result);
                                            })
                                        }
                                    }
                                })
                                let message ={}
                                if (data.ty == 'asb') {
                                    logger.info(`Rich Push  for Campid  ${cid}`)
                                    message = await getRichPushPayload (message,registrationToken,cid,data)
                                } else {
                                    logger.info(`Normal Push  for Campid  ${cid}`)
                                    const messageData = {
                                        campid: cid,
                                        accountNumber: JSON.stringify(useridslength.flat()).replace(/\\/g, ''),
                                        mid: nid,
                                        NotificationID: nid,
                                        title: data.nh,
                                        body: data.nd,
                                        linkAction: data.cdata.linkAction || '',
                                        longDescription: data.cdata.longDescription || '',
                                        linkUrl: data.cdata.linkUrl || '',
                                        categoryId: data.cdata.categoryId || '',
                                        linkText: data.cdata.linkText || '',
                                        newsId: '099f74c1-c7f3-49f9-8cb3-e8d38a2239c4',
                                        sectionTitle: data.cdata.sectionTitle || '',
                                        itemId: data.cdata.itemId || '',
                                        sectionId: data.cdata.sectionId || '',
                                        imageUrl: data.cdata.imageUrl || '',
                                        mediaType: "image"
                                    };

                                    message = {
                                        [registrationToken.length > 1 ? 'tokens' : 'token']: registrationToken.length > 1 ? registrationToken : registrationToken[0],
                                        android: {
                                            data: messageData
                                        }
                                    };

                                }
                                // handle Delivery Type
                                if (campaigns.dlvy === 'd' || campaigns.dlvy === 'a') {
                                    logger.info(`Campaign Push Payload for Android ==>> ${JSON.stringify(message)}======> campid===>${cid}`);
                                    if(registrationToken.length > 1 ){
                                        sendNotificationForMulti(message, app_id, cid);
                                    }else{
                                        sendNotificationForSingle(message, app_id, cid);
                                    }
                                }
                            })
                            .catch(error => {
                                logger.error(`Error Catched ===>${error}`)

                                return;
                            });
                    } else if (app_id == '5e3880a5838d70064cd27049' || app_id == '5e9d7222d065bd6887eb5a5f') {
                        let imageUrl;
                        logger.info("==================== Smiles Prod App ========");
                        if (data.cdata.notificationType == undefined) {
                            data.cdata.notificationType = '';
                        } else if (data.cdata.notificationType === null) {
                            data.cdata.notificationType = "";
                        } else {
                            data.cdata.notificationType = data.cdata.notificationType;
                        }
                        //Image URL
                        if (data.cdata.imageUrl == undefined) {
                            data.cdata.imageUrl = "";
                        } else if (data.cdata.imageUrl === null) {
                            data.cdata.imageUrl = "";
                        } else {
                            data.cdata.imageUrl = decodeURIComponent(data.cdata.imageUrl);
                        }
                        //Offer Type
                        if (data.cdata.offerType == undefined) {
                            data.cdata.offerType = "";
                        } else if (data.cdata.offerType === null) {
                            data.cdata.offerType = "";
                        } else {
                            data.cdata.offerType = data.cdata.offerType;
                        }
                        // Offer Id
                        if (data.cdata.offerId == undefined) {
                            data.cdata.offerId = "";
                        } else if (data.cdata.offerId === null) {
                            data.cdata.offerId = "";
                        } else {
                            data.cdata.offerId = data.cdata.offerId;
                        }
                        //Keyword
                        if (data.cdata.keyword == undefined) {
                            data.cdata.keyword = "";
                        } else if (data.cdata.keyword === null) {
                            data.cdata.keyword = "";
                        } else {
                            data.cdata.keyword = decodeURI(data.cdata.keyword);
                        }
                        //CateogryId
                        if (data.cdata.categoryId == undefined) {
                            data.cdata.categoryId = 0;
                        } else if (data.cdata.categoryId === null) {
                            data.cdata.categoryId = "";
                        } else {
                            data.cdata.categoryId = data.cdata.categoryId;
                        }
                        //Badge
                        if (data.cdata.badge == undefined) {
                            data.cdata.badge = "";
                        } else if (data.cdata.badge === null) {
                            data.cdata.badge = "";
                        } else {
                            data.cdata.badge = data.cdata.badge;
                        }
                        //puzzle
                        if (data.cdata.puzzle == undefined) {
                            data.cdata.puzzle = "";
                        } else if (data.cdata.puzzle === null) {
                            data.cdata.puzzle = "";
                        } else {
                            data.cdata.puzzle = data.cdata.puzzle;
                        }
                        //promo Code
                        if (data.cdata.promoCode == undefined) {
                            data.cdata.promoCode = "";
                        } else if (data.cdata.promoCode === null) {
                            data.cdata.promoCode = "";
                        } else {
                            data.cdata.promoCode = data.cdata.promoCode;
                        }
                        //restaurantId
                        if (data.cdata.restaurantId == undefined) {
                            data.cdata.restaurantId = "";
                        } else if (data.cdata.restaurantId === null) {
                            data.cdata.restaurantId = "";
                        } else {
                            data.cdata.restaurantId = data.cdata.restaurantId;
                        }
                        //orderType
                        if (data.cdata.orderType != undefined) {
                            data.cdata.orderType = data.cdata.orderType;
                        } else {
                            data.cdata.orderType = '';
                        }
                        //filterValue 
                        if (data.cdata.filterValue != undefined) {
                            data.cdata.filterValue = data.cdata.filterValue;
                        } else {
                            data.cdata.filterValue = '';
                        }
                        //filterKey 
                        if (data.cdata.filterKey != undefined) {
                            data.cdata.filterKey = data.cdata.filterKey;
                        } else {
                            data.cdata.filterKey = '';
                        }
                        //restaurantName 
                        if (data.cdata.restaurantName != undefined) {
                            data.cdata.restaurantName = data.cdata.restaurantName;
                        } else {
                            data.cdata.restaurantName = '';
                        }
                        // Adding th key for the case of ASB
                        if (data.cdata.th != undefined) {
                            data.cdata.th = data.cdata.th;
                        } else {
                            data.cdata.yh = '';
                        }
                        let nid = uuid.v4();
                        let et;
                        let messageData;
                        //Call Through Loop (This Code will Move into Worker) - As this is not executable for a longer Segment
                        for (let i = 0; i < dids.length; i++) {
                            let didData = dids[i];
                            // Fetch Campaign Meta data
                            if (campaigns.appinbox_et == 0 || campaigns.appinbox_et == null || campaigns.appinbox_et == undefined) {
                                et = parseInt(campaigns.ed / 1000); //appinbox Expiry time   
                            } else {
                                et = parseInt(campaigns.appinbox_et / 1000);
                            }
                            let saveData = {
                                "campid": cid,
                                "notificationId": nid,
                                "mid": nid,
                                "nid": nid,
                                "ni": data.cdata.imageUrl,
                                "nm": data.nd,
                                "nt": data.nh,
                                "ct": "pn",
                                "st": "unread",
                                "et": et,
                                "ln": "en-us",
                                "cdata": {
                                    mediaType: "image",
                                    "restaurantId": data.cdata.restaurantId,
                                    "keyword": data.cdata.keyword,
                                    "offerId": data.cdata.offerId,
                                    "offerType": data.cdata.offerType,
                                    "notificationType": data.cdata.notificationType,
                                    "imageUrl": data.cdata.imageUrl,
                                    "categoryId": data.cdata.categoryId,
                                    "badge": data.cdata.badge,
                                    "puzzle": data.cdata.puzzle,
                                    "promoCode": data.cdata.promoCode,
                                    "description": data.nd,
                                    "title": data.nh,
                                    "filterValue": data.cdata.filterValue,
                                    "orderType": data.cdata.orderType,
                                    "additionalInfoValue": data.cdata.additionalInfoValue,
                                    "filterKey": data.cdata.filterKey,
                                    "restaurantName":data.cdata.restaurantName
                                }
                            };
                            //Incase of asb Manipulatte the appinbox Payload
                            if (data.ty === 'asb') {
                                let fileExtension = data.and.m ? data.and.m.split('.').pop() : null;
                                let fileType = fileExtension || ""; // Default to empty string if no extension is found
                                let thumbnailUrl = '';

                                //For Mp4 there will be no frame in the and so we will pick from cdata
                                if (fileType === 'mp4') {
                                    thumbnailUrl = data.cdata.th || '';
                                } else {
                                    let fileName = data.and.b + (data.and.i[0] || "") + "." + (data.and.f || "");
                                    thumbnailUrl = fileName;
                                }

                                saveData.cdata.imageUrl = data.and.m || ''; // Full URL of media; default to empty string if missing
                                saveData.cdata.th = thumbnailUrl;
                            }
                            if (campaigns.dlvy === 'i' || campaigns.dlvy === 'a') {
                                sendAppInbox.saveAppInboxData(app_id, didData, saveData);
                            }
                        }
                        //Send 1k Devices at One Time to FCM
                        if (data.ty == 'asb') {
                            logger.info(`Rich Push  for Campid  ${cid}`)
                            message = await getRichPushPayload (message,registrationToken,cid,data)
                        } else {
                            logger.info(`Normal Push  for Campid  ${cid}`)
                            messageData = {
                                campid: String(cid || ""),
                                mid: String(nid || ""),
                                reward: "Get Unlimited Deals with Smiles!",
                                notificationType: String(data.cdata.notificationType || ""),
                                restaurantId: String(data.cdata.restaurantId || ""),
                                imageUrl: "",
                                mediaType: "image",
                                eventShareProperties: "itemId=abc",
                                notificationId: '1212',
                                categoryId: String(data.cdata.categoryId || ""),
                                title: String(data.nh || ""),
                                description: String(data.nd || ""),
                                shareRewardsAmount: '11',
                                shareRewardsType: "Smiles points",
                                sharingText: "Why spend more when you can subscribe to Unlimited Buy 1 Get 1 starting from AED 20 per month and get all the vouchers for free! Subscribe today and save more with Smiles!",
                                badge: '1',
                                puzzle: String(data.cdata.puzzle || ""),
                                offerType: String(data.cdata.offerType || ""),
                                offerId: String(data.cdata.offerId || ""),
                                keyword: String(data.cdata.keyword || ""),
                                promoCode: String(data.cdata.promoCode || ""),
                                filterValue: String(data.cdata.filterValue || ""),
                                orderType: String(data.cdata.orderType || ""),
                                additionalInfoValue: String(data.cdata.additionalInfoValue || ""),
                                filterKey: String(data.cdata.filterKey || ""),
                                restaurantName: String(data.cdata.restaurantName || "")                                
                            }
                        }

                        let  message = {
                            [registrationToken.length > 1 ? 'tokens' : 'token']: registrationToken.length > 1 ? registrationToken : registrationToken[0],
                            android: {
                                data: messageData
                            }
                        };

                        if (campaigns.dlvy === 'd' || campaigns.dlvy === 'a') {
                            logger.info(`Campaign Push Payload for Android ==>> ${JSON.stringify(message)}======> campid===>${cid}`);
                            if(registrationToken.length > 1 ){
                                sendNotificationForMulti(message, app_id, cid);
                            }else{
                                sendNotificationForSingle(message, app_id, cid);
                            }
                        }
                    }else{
                        let messageData;
                        sdkvs[0] = 7011;
                        logger.info(`registrationToken 2 ==>  ${registrationToken}`);
                        logger.info(`data 2 =>>  ${JSON.stringify(data)}`);
                        if (sdkvs[0] >= appiceConfig.androidsdkv) {
                            data.ai_tag = 'ai_pn';
                            messageData = { "message": JSON.stringify(data) }
                        } else {
                            messageData = {
                                "message": JSON.stringify({
                                    "pushtype": "direct",
                                    "content": data,
                                    "ai_tag": "ai_pn"
                                })
                            }
                        }
                        let message = {}
                        if (data.ty == 'asb') {
                            logger.info(`Rich Push  for Campid  ${cid}`)
                            message = await getRichPushPayload (message,registrationToken,cid,data)
                        } else {
                            logger.info(`Normal Push  for Campid  ${cid}`)
                            if(registrationToken.length > 1 ){
                                message = {
                                    tokens: registrationToken,
                                    data: messageData
                                };
                            }else{
                                message = {
                                    token: registrationToken[0],
                                    data: messageData
                                };
                            }
                        }

                        logger.info(`Campaign Push Payload for Android ==>> ${JSON.stringify(message)}======> campid===>${cid}`);
                        if (campaigns.dlvy === 'd' || campaigns.dlvy === 'a') {
                            if(registrationToken.length > 1 ){
                                sendNotificationForMulti(message, app_id, cid);
                            }else{
                                sendNotificationForSingle(message, app_id, cid);
                            }
                        }
                    }
                } else {
                    // PASTED CODE ENDS
                    logger.info(`Panel Code FROM FCM `)
                    let nid = uuid.v4();
                    if(semusiConfig.appInboxAPPIDS.includes(app_id)){
                        logger.info(`AppInbpox for Panel Now Running in FCM ====> =====>campid===> ${cid}`)

                        //Send 1k Devices at One Time to FCM
                        sendMessage.getUserIds(app_id, dids).then((userids) => {
                            let userId = [];
                            userids.forEach(u => {
                                userId.push({
                                    did : u.did,
                                    UserId : common.getUserIdObject(u)
                                });
                            });
                            let useridslength = userId;
                            let adid = dids[0];
                            let uattime = new Date();
                            let uatepochTime = parseInt(uattime.getTime() / 1000);
                            logger.info(`userId =>`, userId)
                            userId.forEach((user) => {
                                if(user.UserId && user.UserId.length > 0){
                                    //UserId Based AppInbox Now Running
                                    logger.info(`UserId Based AppInbox Now Running in FCM =============>=====>campid===> ${cid}`)
                                    // Nid Dynamically Generation
                                    let et = '';
                                    if (campaigns.appinbox_et == 0 || campaigns.appinbox_et == null || campaigns.appinbox_et == undefined) {
                                        et = parseInt(campaigns.ed / 1000); //appinbox Expiry time   
                                    }else{
                                        et = parseInt(campaigns.appinbox_et / 1000);
                                    }
                                    let result = {
                                        "nid": nid,
                                        "mid": nid,
                                        "notificationId": nid,
                                        "campid": cid,
                                        "uat": uatepochTime,
                                        "ni": data.ni,
                                        "nm": data.nd,
                                        "nt": data.nh,
                                        "ct": "pn",
                                        "st": "unread",
                                        "et": et,
                                        "ln": "en-us",
                                        "cdata": data.cdata
                                    };
                                    logger.info(`Android App Inbox Created In FCM ======>campid===> ${cid}`)
                                    //Incase of asb Manipulatte the appinbox Payload
                                    if (data.ty === 'asb') {
                                        let fileExtension = data.and.m ? data.and.m.split('.').pop() : null;
                                        let fileType = fileExtension || ""; // Default to empty string if no extension is found
                                        let thumbnailUrl = '';

                                        //For Mp4 there will be no frame in the and so we will pick from cdata
                                        if (fileType === 'mp4') {
                                            thumbnailUrl = data.cdata.th || '';
                                        } else {
                                            let fileName = data.and.b + (data.and.i[0] || "") + "." + (data.and.f || "");
                                            thumbnailUrl = fileName;
                                        }

                                        result.cdata.imageUrl = data.and.m || ''; // Full URL of media; default to empty string if missing
                                        result.cdata.th = thumbnailUrl;
                                    }
                                    if (campaigns.dlvy === 'i' || campaigns.dlvy === 'a') {
                                        user?.UserId.forEach((item) => {
                                            logger.info(`User id based AppInbox setting now=======CampaignId =========${cid}`)
                                            sendAppInbox.saveUserIDAppInboxdata(app_id, user.did, item, result);
                                        })
                                    }
                                }else{
                                    // Did Based AppInboX
                                    logger.info(`Did Based AppInbox in FCM=======>campid===> ${cid}`)
                                    if (data.cdata.notificationType == undefined) {
                                        data.cdata.notificationType = '';
                                    } else if (data.cdata.notificationType === null) {
                                        data.cdata.notificationType = "";
                                    } else {
                                        data.cdata.notificationType = data.cdata.notificationType;
                                    }
                                    //Image URL
                                    if (data.cdata.imageUrl == undefined) {
                                        data.cdata.imageUrl = "";
                                    } else if (data.cdata.imageUrl === null) {
                                        data.cdata.imageUrl = "";
                                    } else {
                                        data.cdata.imageUrl = decodeURIComponent(data.cdata.imageUrl);
                                    }
                                    //Offer Type
                                    if (data.cdata.offerType == undefined) {
                                        data.cdata.offerType = "";
                                    } else if (data.cdata.offerType === null) {
                                        data.cdata.offerType = "";
                                    } else {
                                        data.cdata.offerType = data.cdata.offerType;
                                    }
                                    // Offer Id
                                    if (data.cdata.offerId == undefined) {
                                        data.cdata.offerId = "";
                                    } else if (data.cdata.offerId === null) {
                                        data.cdata.offerId = "";
                                    } else {
                                        data.cdata.offerId = data.cdata.offerId;
                                    }
                                    //Keyword
                                    if (data.cdata.keyword == undefined) {
                                        data.cdata.keyword = "";
                                    } else if (data.cdata.keyword === null) {
                                        data.cdata.keyword = "";
                                    } else {
                                        data.cdata.keyword = decodeURI(data.cdata.keyword);
                                    }
                                    //CateogryId
                                    if (data.cdata.categoryId == undefined) {
                                        data.cdata.categoryId = 0;
                                    } else if (data.cdata.categoryId === null) {
                                        data.cdata.categoryId = "";
                                    } else {
                                        data.cdata.categoryId = data.cdata.categoryId;
                                    }
                                    //Badge
                                    if (data.cdata.badge == undefined) {
                                        data.cdata.badge = "";
                                    } else if (data.cdata.badge === null) {
                                        data.cdata.badge = "";
                                    } else {
                                        data.cdata.badge = data.cdata.badge;
                                    }
                                    //puzzle
                                    if (data.cdata.puzzle == undefined) {
                                        data.cdata.puzzle = "";
                                    } else if (data.cdata.puzzle === null) {
                                        data.cdata.puzzle = "";
                                    } else {
                                        data.cdata.puzzle = data.cdata.puzzle;
                                    }
                                    //promo Code
                                    if (data.cdata.promoCode == undefined) {
                                        data.cdata.promoCode = "";
                                    } else if (data.cdata.promoCode === null) {
                                        data.cdata.promoCode = "";
                                    } else {
                                        data.cdata.promoCode = data.cdata.promoCode;
                                    }
                                    //restaurantId
                                    if (data.cdata.restaurantId == undefined) {
                                        data.cdata.restaurantId = "";
                                    } else if (data.cdata.restaurantId === null) {
                                        data.cdata.restaurantId = "";
                                    } else {
                                        data.cdata.restaurantId = data.cdata.restaurantId;
                                    }
                                    //orderType
                                    if (data.cdata.orderType != undefined) {
                                        data.cdata.orderType = data.cdata.orderType;
                                    } else {
                                        data.cdata.orderType = '';
                                    }
                                    //filterValue 
                                    if (data.cdata.filterValue != undefined) {
                                        data.cdata.filterValue = data.cdata.filterValue;
                                    } else {
                                        data.cdata.filterValue = '';
                                    }
                                    //filterKey 
                                    if (data.cdata.filterKey != undefined) {
                                        data.cdata.filterKey = data.cdata.filterKey;
                                    } else {
                                        data.cdata.filterKey = '';
                                    }
                                    if (data.cdata.th != undefined) {
                                        data.cdata.th = data.cdata.th;
                                    } else {
                                        data.cdata.th = '';
                                    }
                                    let nid = uuid.v4();
                                    let et;
                                    //Call Through Loop (This Code will Move into Worker) - As this is not executable for a longer Segment
                                    // Fetch Campaign Meta data
                                    if (campaigns.appinbox_et == 0 || campaigns.appinbox_et == null || campaigns.appinbox_et == undefined) {
                                        et = parseInt(campaigns.ed / 1000); //appinbox Expiry time   
                                    } else {
                                        et = parseInt(campaigns.appinbox_et / 1000);
                                    }
                                    let saveData = {
                                        "campid": cid,
                                        "notificationId": uuid.v4(),
                                        "mid": nid,
                                        "nid": nid,
                                        "ni": data.cdata.imageUrl,
                                        "nm": data.nd,
                                        "nt": data.nh,
                                        "ct": "pn",
                                        "st": "unread",
                                        "et": et,
                                        "ln": "en-us",
                                        "cdata": {
                                            mediaType: "image",
                                            "restaurantId": data.cdata.restaurantId,
                                            "keyword": data.cdata.keyword,
                                            "offerId": data.cdata.offerId,
                                            "offerType": data.cdata.offerType,
                                            "notificationType": data.cdata.notificationType,
                                            "imageUrl": data.cdata.imageUrl,
                                            "categoryId": data.cdata.categoryId,
                                            "badge": data.cdata.badge,
                                            "puzzle": data.cdata.puzzle,
                                            "promoCode": data.cdata.promoCode,
                                            "description": data.nd,
                                            "title": data.nh,
                                            "filterValue": data.cdata.filterValue,
                                            "orderType": data.cdata.orderType,
                                            "filterKey": data.cdata.filterKey
                                        }
                                    };
                                    //Incase of asb Manipulatte the appinbox Payload
                                    if (data.ty === 'asb') {
                                        let fileExtension = data.and.m ? data.and.m.split('.').pop() : null;
                                        let fileType = fileExtension || ""; // Default to empty string if no extension is found
                                        let thumbnailUrl = '';

                                        //For Mp4 there will be no frame in the and so we will pick from cdata
                                        if (fileType === 'mp4') {
                                            thumbnailUrl = data.cdata.th || '';
                                        } else {
                                            let fileName = data.and.b + (data.and.i[0] || "") + "." + (data.and.f || "");
                                            thumbnailUrl = fileName;
                                        }

                                        saveData.cdata.imageUrl = data.and.m || ''; // Full URL of media; default to empty string if missing
                                        saveData.cdata.th = thumbnailUrl;
                                    }
                                    logger.info(`saveData for Appinbox in FCM ${saveData}`);
                                    if (campaigns.dlvy === 'i' || campaigns.dlvy === 'a') {
                                        logger.info(`==== Did Based App Inbox Updated in FCM  ====>=====>campid===> ${cid}`);
                                        sendAppInbox.saveAppInboxData(app_id, user.did, saveData);
                                    }
                                }
                            })
                        })
                    }else{
                        logger.info(`AppInbox Disabled for this App========CampaignId =========${cid}`)
                    }
                    logger.info(`sdkvs :: ${sdkvs}`);
                    logger.info(`appiceConfig:: ${appiceConfig.androidsdkv}`);
                    logger.info(`appiceConfig.androidsdkv ::${appiceConfig.androidsdkv}`);
                    let messageData;
                    sdkvs[0] = 7011;
                    logger.info(`registrationToken 2 ==>  ${registrationToken}`);
                    logger.info(`data 2 =>>  ${JSON.stringify(data)}`);
                    data.nid = nid;
                    data.mid = nid;
                    if (sdkvs[0] >= appiceConfig.androidsdkv) {
                        data.ai_tag = 'ai_pn';
                        messageData = { "message": JSON.stringify(data) }
                    } else {
                        messageData = {
                            "message": JSON.stringify({
                                "pushtype": "direct",
                                "content": data,
                                "ai_tag": "ai_pn"
                            })
                        }
                    }
                    let message ={}
                    if (data.ty == 'asb') {
                        logger.info(`Rich Push  for Campid  ${cid}`)
                        message = await getRichPushPayload (message,registrationToken,cid,data)

                    } else {
                        logger.info(`Normal Push for Campid ${cid}`)
                        //normal Exisitng payload
                        if(registrationToken.length > 1 ){
                            message = {
                                tokens: registrationToken,
                                data: messageData
                            };
                        }else{
                            message = {
                                token: registrationToken[0],
                                data: messageData
                            };
                        }

                    }

                    logger.info(`Campaign Push Payload for Android ==>> ${JSON.stringify(message)}======> campid===>${cid}`);
                    if (campaigns.dlvy === 'd' || campaigns.dlvy === 'a') {
                        if(registrationToken.length > 1 ){
                            sendNotificationForMulti(message, app_id, cid);
                        }else{
                            sendNotificationForSingle(message, app_id, cid);
                        }

                    }
                }
            }
        }
        catch (error) {
            return reject(error);
        }
    });
}

async function getRichPushPayload(message, registrationToken, cid, data) {
    logger.info(`Creating Rich PUSH for FCM`)

    message = {
        registration_ids: registrationToken[0],
        priority: "high",
        content_available: true,
        data: {
            "message": JSON.stringify({
                "camp_id": cid,
                "tid":data.tid,
                "nh": data.nh,
                "nd": data.nd,
                "ni": data.ni,
                "end": "",
                "eni": data.eni,
                "ty": "asb",
                "and": data.and,
                "eurl": data.eurl,
                "et": data.et,
                "actions": data.actions,
                "cdata": data.cdata,
                "ai_tag": 'ai_pn',
            }),

        }
    };

    return message

}
sendMessage.getUserIds = function (appid, dids) {
    let match = {};
    match.p = "Android";
    match.did = {
        $in: dids
    };
    logger.info(`match==>  ${match}`);
    return new Promise((resolve, reject) => {
        try {
            let nosql = (match.nosql) ? match.nosql : match;
            common.db.collection('app_users' + appid).find(nosql, {
                _id: 0,
                did: 1,
                _custom_UserID: 1,
                _custom_UserId:1,
                _custom: 1
            }).toArray(function (err, users) {
                if (err) {
                    logger.error(`err from getUserIds::>>>${err}`);
                    return reject(err);
                } else {
                    return resolve(users);
                }
            });
        } catch (e) {
            logger.error(`catch error ::>>>${e.message}`);
            return reject(e);
        }
    })
}
//function for send push for IN-APP campaign
sendMessage.sendInAppPush = function (appid, registrationToken,jsonFile,cid,campaigns) {
    logger.info(`Sending In App Push Code initiated =======CampaignId =========${cid}`)
    //function call for get active cmp data
    sendMessage.getActiveCmpData(appid,cid).then((cmpData) =>{
            //function call for send push with all data and config via common push function
            sendMessage.sendCommonPush(appid,cid, jsonFile, registrationToken,campaigns).then((success) =>{
                    logger.info(`============ send in app push success ====>=====>campid===> ${cid}`);
                })
                .catch(error =>{
                    logger.error(`catch error ::>>>${error}=====>campid===> ${cid}`);
                });
        })
        .catch(error =>{
            logger.error(`catch error ::>>>${error}=====>campid===> ${cid}`);
        });

}
// function toget cmp data  to send inapp push 
sendMessage.getActiveCmpData = function(appId, cid){
	return new Promise((resolve, reject) =>{
        setTimeout(function(){ 
        common.db.collection('activecampaign_' +appId).find({'_id':common.db.ObjectID(appId), },{ data: 1}).toArray(function(err, result){
            if(!err){
                //filter active cmp from db
                let  activeCmp = result[0].data.filter(function (cmp) {
                    return cmp._id == cid;
                    });
                resolve(activeCmp);
            }else{
                reject(err);
            }  
            }); 
        }, 2000);
   })
}

sendMessage.sendCommonPush = function(app_id,cid, jsonFile, registrationToken,campaigns){
	return new Promise((resolve, reject) =>{
        //if(semusiConfig.SilentPushEnable.length > 0 ){ comment for now this check not working 
            logger.info(`Silent Push Enabled with updated Payload from Environment 726`)

            sendMessage.checknSetPush(app_id,cid,registrationToken,jsonFile)
         // }
   })
}  

sendMessage.checknSetPush = function (app_Id, cid,registrationToken,jsonFile) {
 return new Promise((resolve, reject) =>{
  //function call for get active cmp data
  sendMessage.getActiveCmpData(app_Id, cid).then((cmpData) => {
    const campaignUtils = require('./campaign.utils.js');
      if (cmpData[0].aud) {
        let cmpAud = cmpData[0].aud;

                    //Prepare payload with the ActiveCampaign And SP key 
                    let ai_tag = 'ai_pn';
                    //delete sql query before seding payload
                    if(cmpData[0].aud.userQ != undefined){
                        delete cmpData[0].aud.userQ;
                      }
                      if(cmpData[0].aud.q != undefined){
                        delete cmpData[0].aud.q;
                      }
                    // If the values are not set , Set its default 
                    cmpData[0].delayi =  ( cmpData[0].delayi ) ?   cmpData[0].delayi : 0  ;
                    cmpData[0].delays =  ( cmpData[0].delays ) ?   cmpData[0].delays : 0 ;
                    cmpData[0].delayu =  ( cmpData[0].delayu ) ?   cmpData[0].delayu : "";

                      // value of message key has to be stringfied entirely 
                    const silentData = {
                        message: JSON.stringify({ activeCampaigns: cmpData, "ai_tag": ai_tag, "sp": "true" })
                    }
                    let message;
                    if(registrationToken.length > 1 ){
                        message = {
                            tokens: registrationToken,
                          android: { 
                            data:silentData
                           } 
                        };
                    }else{
                        message = {
                            token: registrationToken[0],
                            android: { 
                                data:silentData
                              } 
                        };
                    }
                    
                      logger.info(`Campaign With Silent Push Payload for Android ==>> ${JSON.stringify(message)}======> campid===>${cid}`);
            
                      if(registrationToken.length > 1 ){
                        sendNotificationForMulti(message, app_Id, cid);
                        }else{
                        sendNotificationForSingle(message, app_Id, cid);
                        }
                  }
                })
            .catch((error) => {
                logger.error(`catch error ::>>>${error}`);
            });
    })
};


exports.sendMessage = sendMessage;
