let apnPush = {},
	apn = require('apn'),
	logger = require('../../logger'),
	common = require('./common.js'),
	sendAppInbox = require('./AppInbox.utils.js'),
	uuid = require('uuid'),
	campaignUtils = require('./campaign.utils.js'),
	moment = require('moment'),
	semusiConfig = require('../../api/config'),
    fs = require('fs'),
	dataConsumer = require('./common.data.consumer.js');

(function (apnPush) {

	let apnConnection;
	apnPush.pushNotification = function (optionsData, devices, data, app_id, cid, geo, activeCampaign, custom_UserIDArr, customArr) {
		logger.info(` Apn pushNotification =======optionsData:: ${JSON.stringify(optionsData)}========CampaignId =========${cid}`);
		let payload = [];
		let payloadData = data;
		let campaigns = activeCampaign;
		let segment = JSON.parse(activeCampaign.segmentinfo);
		if (activeCampaign.t == "IN-APP" || (segment.what.length > 0 && segment.who.length > 0) || segment.what.length > 0) {
			logger.info(`Apn Push Notification sending Inapp Push / WHO+WHat Condition ========CampaignId =========${cid}`)
			apnPush.sendInAppPush(app_id, devices, optionsData, cid);
		} else {
			// In case of Draft We won't send the push
			if( activeCampaign.st =='DRAFT'){
				logger.info(`Push Won't be sent In case of deactivaton In Apn `)
				return
			}
			if (geo == 1) {
				let childApproved;
				let childDeleted;
				let sdkDeletedFlag;
				if (activeCampaign.childIds && activeCampaign.childIds.length > 0) {
					if (activeCampaign.childIds.approved == true) {
						childApproved = true;
					} else {
						childApproved = false;
					}
					if (activeCampaign.childIds.deleted == true) {
						childDeleted = true;
					} else {
						childDeleted = false;
					}
					sdkDeletedFlag = activeCampaign.d;
				} else {
					sdkDeletedFlag = activeCampaign.d;
				}
				let obj = {};
				obj._id = activeCampaign._id;
				obj.tid = activeCampaign.tid;
				obj.t = activeCampaign.t;
				obj.sd = activeCampaign.sd;
				obj.ed = activeCampaign.ed;
				obj.ud = activeCampaign.ud;
				obj.d = sdkDeletedFlag;
				// If the values are not set , Set its default 
				obj.delayi = ( obj.delayi ) ?  obj.delayi : 0  ;
				obj.delays =  ( obj.delays ) ?  obj.delays : 0 ;
				obj.delayu =  ( obj.delayu ) ?  obj.delayu : "Seconds";
				obj.fre = {};
				if (activeCampaign.c_event) {
					obj.c_event = activeCampaign.c_event;
					obj.c_period = activeCampaign.c_period;
				}
				obj.fre.dp = 0;
				if (activeCampaign.d == false) {
					obj.fre = activeCampaign.fre;
					obj.fre.dp = 0;
					if (activeCampaign.daySelector == "ALLWEEK") {
						obj.allweek = true;
						obj.days = [];
					} else {
						obj.allweek = false;
						obj.days = activeCampaign.days;
					}
					if (activeCampaign.timeSelector == "ALLDAY") {
						obj.allday = true;
					} else {
						obj.allday = false;
						if (activeCampaign.time && activeCampaign.time.length > 0) {
							obj.time = {
								start: activeCampaign.time[0],
								end: activeCampaign.time[1]
							};
						} else {
							obj.time = {
								start: 8,
								end: 20
							};
						}

					}
				}
				let activePushObject = populatePushObject(activeCampaign.template);
				obj.data = activePushObject;
				obj.aud = JSON.parse(activeCampaign.segmentinfo);
				payload.push(obj);
			}

			logger.info(`==== Push into wihout geo section  ==== `);
			let camp_res = [];
			let dataArray = [];
			let appid = '';
			let nidData = uuid.v4();
			if (semusiConfig.serverDomain == 'https://gcc.appice.io' || semusiConfig.serverDomain == 'https://gccuatpanel.appice.io' || semusiConfig.serverDomain == 'https://gccpreprod.appice.io') {
				// else block for gcc panel appid'd
				let payloadData = data; // assign data 
				logger.info(`==== Push into GCC Section  ==== `);
				//get Expiry of Notification 
				common.db.collection('campaigns_' + app_id).findOne({
					_id: common.db.ObjectID(cid)
				}, function (err, campaigns) {
					let expiryDate = 0;
					if (campaigns.appinbox_et == 0) {
						 expiryDate = campaigns.ed;
					} else {
						 expiryDate = campaigns.appinbox_et;
					}
					devices.forEach(async function (item) {
						logger.info(`==== IOS GCM ID   ==== ${item.gcmid}=====>campid===> ${cid}`);
						if (item.gcmid) {
							//Get data From App_Settings 
							let options = {
								token: {
									key: optionsData.cert,
									keyId: optionsData.keyid,
									teamId: optionsData.teamid
								},
								production: optionsData.production
								//   production: false
							};
							//adding Proxy key in case it is enabled
							if (semusiConfig.proxyUrl && semusiConfig.proxyPORT) {
								options.proxy = {
									host: semusiConfig.proxyUrl,
									port: semusiConfig.proxyPORT
								}
							}
							//Create Connection
							let apnProvider = new apn.Provider(options);
							let note = new apn.Notification();
							note.expiry = Math.floor(Date.now() / 1000) + 3600;
							let responseData = JSON.parse(JSON.stringify(payloadData.toolData));
							//Initialise Variables
							let imageUrl = '';
							let offerId = '';
							let offerType = '';
							let keyword = '';
							let categoryId = '';
							//NotificationType 
							if (responseData.cdata.notificationType == undefined) {
								responseData.cdata.notificationType = '';
							} else {
								responseData.cdata.notificationType = parseInt(responseData.cdata.notificationType);
							}
							//ImageUrl 
							if (responseData.cdata.imageUrl != undefined) {
								imageUrl = responseData.cdata.imageUrl;
							}
							//OfferId
							if (responseData.cdata.offerId != undefined) {
								offerId = responseData.cdata.offerId;
							}
							//OfferType
							if (responseData.cdata.offerType != undefined) {
								offerType = responseData.cdata.offerType;
							}
							if (responseData.cdata.keyword != undefined) {
								keyword = decodeURI(responseData.cdata.keyword);
							}
							//CateogryId
							if (responseData.cdata.categoryId != undefined) {
								categoryId = parseInt(responseData.cdata.categoryId);
							} else {
								categoryId = 0;
							}
							// Badge
							if (responseData.cdata.badge != undefined) {
								responseData.cdata.badge = parseInt(responseData.cdata.badge);
							} else {
								responseData.cdata.badge = '';
							}
							//puzzle
							if (responseData.cdata.puzzle != undefined) {
								responseData.cdata.puzzle = parseInt(responseData.cdata.puzzle);
							} else {
								responseData.cdata.puzzle = '';
							}
							//promo Code
							if (responseData.cdata.promoCode != undefined) {
								responseData.cdata.promoCode = responseData.cdata.promoCode;
							} else {
								responseData.cdata.promoCode = '';
							}
							//Restaurant Id
							if (responseData.cdata.restaurantId != undefined) {
								responseData.cdata.restaurantId = responseData.cdata.restaurantId;
							} else {
								responseData.cdata.restaurantId = '';
							}
							if (responseData.cdata.th != undefined) {
								responseData.cdata.th = responseData.cdata.th;
							} else {
								responseData.cdata.th = '';
							}
							 //restaurantName 
							 if (responseData.cdata.restaurantName != undefined) {
								responseData.cdata.restaurantName = responseData.cdata.restaurantName;
							} else {
								responseData.cdata.restaurantName = '';
							}
							let nid = nidData;
							if (geo == 1) {
								note.badge = 1;
								note.mutableContent = 1;
								note.contentAvailable = 1;
								note.category = "imageIdentifier";
								note.payload = {
									"data": {
										"message": {
											"ai_tag": "ai_pn",
											"sp": "true",
											"activeCampaigns": payload
										}
									}
								};
								note.topic = optionsData.topic;
								if (campaigns.dlvy === 'd' || campaigns.dlvy === 'a') {
									logger.info(`Campaigns dlvy condition =====>campid===> ${cid}`);
									logger.info(`Campaign Push Payload for IOS ==>> ${JSON.stringify(note)}=====>campid===> ${cid}`);
									apnProvider.send(note, item.gcmid).then((result) => {
										logger.info(`==== Push Finished on Device geo ==== ${result}=====>campid===> ${cid}`);
										if (Array.isArray(result.sent) && result.sent.length) {
											campaignUtils.increaseCountResult(app_id, cid);
										}
									});
								}
							} else if (app_id == '5efc23b444776e69dbacdf02' || app_id == '5efc240122ab3a69da580e6f' || app_id == '5efc235b22ab3a69da580e69') {
								// Handle Delivery type from config
								let useridslength = (custom_UserIDArr ? custom_UserIDArr : customArr);
								logger.info(`==== User Ids Data =>==== ${JSON.stringify(useridslength)}=====>campid===> ${cid}`);
								let uattime = new Date();
								let uatepochTime = parseInt(uattime.getTime() / 1000);
								let adid = item.did;
								logger.info(`==== Deliery Type => =>==== ${JSON.stringify(campaigns)} =====>campid===> ${cid}`);
								if (campaigns.dlvy === 'i' || campaigns.dlvy === 'a') {
									logger.info(`====cdata before Delivery Campaign => =>==== ${responseData.cdata}=====>campid===> ${cid}`);
									let cDataObj = Object.keys(responseData.cdata);
									logger.info(`==== cDataObj => =>==== ${JSON.stringify(cDataObj)}=====>campid===> ${cid}`);
									cDataObj.forEach(function (key) {
										responseData.cdata[key] = responseData.cdata[key] ? responseData.cdata[key] : '';
									});
									for (let updateinboxData = 0; updateinboxData < useridslength.length; updateinboxData++) {
										let nid = nidData;
										let result = {
											"nid": nid,
											"mid": nid,
											"notificationId": nid,
											"campid": cid,
											"uat": uatepochTime,
											"ni": responseData.ni,
											"nm": responseData.nd,
											"nt": responseData.nh,
											"ct": "pn",
											"st": "unread",
											"et": parseInt(expiryDate / 1000),
											"ln": "en-us",
											"cdata": responseData.cdata
										};
										//Incase of asb Manipulatte the appinbox Payload
										if (responseData.ty === 'asb') {
											let fileExtension = responseData.and.m ? responseData.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 = responseData.cdata.th || '';
											} else {
												let fileName = responseData.and.b + (responseData.and.i[0] || "") + "." + (responseData.and.f || "");
												thumbnailUrl = fileName;
											}
										
											result.cdata.imageUrl = responseData.and.m || ''; // Full URL of media; default to empty string if missing
											result.cdata.th = thumbnailUrl;
										}
										logger.info(`==== ios inbox payload for iOS  => =>==== ${JSON.stringify(result)} =====>campid===> ${cid}`);
										sendAppInbox.saveUserIDAppInboxdata(app_id, adid, useridslength[updateinboxData], result);
									}
								}
								// Push handling
								let apnProvider = new apn.Provider(options);
								let deviceToken = item.gcmid;
								//Create an Note Function
								let note = new apn.Notification();
								note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
								note.badge = 1;
								note.mutableContent = 1;
								note.contentAvailable = 1;
								note.category = "imageIdentifier";
								note.alert = responseData.nd;
								note.title = responseData.nh;
								//RICH PUSH Check 
							if (responseData.ty == 'asb' ) {
								logger.info(`Rich Push Enabled for Campid ${cid}`)
								//get Rich Push payload
								note = await getRichPushPayload(note, responseData, cid)
							} else{
								logger.info(`Normal Push ${cid}`)
								note.payload = {
									campid: cid,
									accountNumber: useridslength,
									mid: nidData,
									NotificationID: nidData,
									title: responseData.nh,
									body: responseData.nd,
									linkAction: responseData.cdata.linkAction ? responseData.cdata.linkAction : '',
									longDescription: responseData.cdata.longDescription ? responseData.cdata.longDescription : '',
									linkUrl: responseData.cdata.linkUrl ? responseData.cdata.linkUrl : '',
									categoryId: "cat550039",
									linkText: responseData.cdata.linkText ? responseData.cdata.linkText : '',
									newsId: nidData,
									sectionTitle: responseData.cdata.sectionTitle ? responseData.cdata.sectionTitle : '',
									itemId: responseData.cdata.itemId ? responseData.cdata.itemId : '',
									sectionId: responseData.cdata.sectionId ? responseData.cdata.sectionId : '',
								}
								}
								note.topic = optionsData.topic;
								logger.info(`====  Push payload for iOS  => =>==== ${JSON.stringify(note)}=====>campid===> ${cid}`);
								logger.info(`==== campaigns.dlvy  => =>==== ${campaigns.dlvy}`);

								if (campaigns.dlvy === 'd' || campaigns.dlvy === 'a') {
									logger.info(`==== deviceToken => =>==== ${deviceToken}=====>campid===> ${cid}`);
						
									apnProvider.send(note, deviceToken).then((result) => {
										logger.info(`==== Push Finished on Device   => =>==== ${JSON.stringify(result)}=====>campid===> ${cid}`);
										if (Array.isArray(result.sent) && result.sent.length) {
											campaignUtils.increaseCountResult(app_id, cid);
										}
									});
								}
							} else {
								note.alert = payloadData.content;
								// Expires 1 hour from now.
								note.badge = 1;
								if (typeof payloadData.toolData.sound != "undefined" && payloadData.toolData.sound == false) {
									delete note.aps.sound;
								}
								note.mutableContent = 1;
								note.contentAvailable = 1;
								note.category = "imageIdentifier";
								note.title = responseData.nh;
								//RICH PUSH
							if (responseData.ty == 'asb' ) {
								//get Rich Push payload
								logger.info(`Rich Push Enabled for Campid ${cid}`)
								note = await getRichPushPayload(note, responseData, cid)
							} else{
								logger.info(`Normal Push for Campid ${cid}`)
								note.payload = {
									'nid': nid,
									'campId': cid,
									'messageFrom': 'Pay the Bill',
									"mediaType": "Image",
									"mediaUrl": decodeURIComponent(imageUrl),
									"categoryId": categoryId,
									"description": responseData.nd,
									"mediaType": "image",
									"mediaUrl": decodeURIComponent(imageUrl),
									"notificationId": cid,
									"notificationType": responseData.cdata.notificationType,
									"offerId": offerId,
									"offerType": offerType,
									"title": responseData.nh,
									"isFree": false,
									"badge": responseData.cdata.badge,
									"restaurantId": responseData.cdata.restaurantId,
									"puzzle": responseData.cdata.puzzle,
									"keyword": keyword,
									"filterKey": responseData.cdata.filterKey || '',
									"filterValue": responseData.cdata.filterValue || '',
									"additionalInfoValue":responseData.cdata.additionalInfoValue,
									"promoCode": responseData.cdata.promoCode,
									"restaurantName" : responseData.cdata.restaurantName
								};
							  }
								logger.info(`Note.payload============>${JSON.stringify(note.payload)}`)
								note.topic = optionsData.topic;
								//send Function                      
								let et = parseInt(expiryDate / 1000);
								let saveData = {
									"nid": nid,
									"mid": nid,
									"ni": decodeURIComponent(imageUrl),
									"nm": responseData.nd,
									"nt": responseData.nh,
									"ct": "pn",
									"st": "unread",
									"et": et,
									"ln": "en-us",
									"cdata": {
										"keyword": keyword,
										"offerId": offerId,
										"offerType": offerType,
										"notificationType": responseData.cdata.notificationType,
										"imageUrl": decodeURIComponent(imageUrl),
										"categoryId": categoryId,
										"badge": responseData.cdata.badge,
										"filterKey": responseData.cdata.filterKey || '',
										"filterValue": responseData.cdata.filterValue || '',
										"puzzle": responseData.cdata.puzzle,
										"promoCode": responseData.cdata.promoCode,
										"additionalInfoValue":responseData.cdata.additionalInfoValue,
										"restaurantId": responseData.cdata.restaurantId,
										"restaurantName": responseData.cdata.restaurantName
									}
								};
								//Incase of asb Manipulatte the appinbox Payload
								if (responseData.ty === 'asb') {
									let fileExtension = responseData.and.m ? responseData.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 = responseData.cdata.th || '';
									} else {
										let fileName = responseData.and.b + (responseData.and.i[0] || "") + "." + (responseData.and.f || "");
										thumbnailUrl = fileName;
									}
								
									saveData.cdata.imageUrl = responseData.and.m || ''; // Full URL of media; default to empty string if missing
									saveData.cdata.th = thumbnailUrl;
								}
								// Based on Campaign Notification Delivery flag       
								if (campaigns.dlvy === 'd' || campaigns.dlvy === 'a') {
									logger.info(`====Based on Campaign Notification Delivery flag =>=======>campid===> ${cid}`);
									logger.info(`Campaign Push Payload for IOS ==>> ${JSON.stringify(note)}=====>campid===> ${cid}`);
									apnProvider.send(note, item.gcmid).then((result) => {
										logger.info(`==== Push Finished on Device   => =>==== ${JSON.stringify(result)} =====>campid===> ${cid}`);
										logger.info(`====call from apn  => =>==== ${result.sent.length}`);
										if (Array.isArray(result.sent) && result.sent.length) {
											logger.info(`====call from apn=>==== `);
											campaignUtils.increaseCountResult(app_id, cid);
										}
									});
								}
								if (campaigns.dlvy === 'i' || campaigns.dlvy === 'a') {
									logger.info(`==== App Inbox Updated  =>====`);
									sendAppInbox.saveAppInboxData(app_id, item.did, saveData);
								}
							}
						} else {
							logger.info(`==== APN Token not found for push=>==== ${item} =====>campid===> ${cid}`);
						}
					});
					let data = {
						responses: camp_res
					};
					// Process Campaign Received Event - Server Send an event Directly into event Queue
					dataConsumer.processCampaignResponses([{
						appid: appid,
						dataArray: data
					}], function (status) { });
				});
			} else {
				// else block for US panel appid'd
				logger.info(`Panel Code From APN DIRECT=====>campid===> ${cid}`)
				//get Expiry of Notification 
				let expiryDate = 0;
				if (activeCampaign.appinbox_et == 0 || activeCampaign.appinbox_et == null || activeCampaign.appinbox_et == undefined) {
					expiryDate = activeCampaign.ed;
				} else {
					expiryDate = activeCampaign.appinbox_et;
				}
				devices.forEach(async function (item) {
					//let payloadData = data; // assign data 
					let responseData = JSON.parse(JSON.stringify(payloadData.toolData));
					let nid = nidData;
					let imageUrl = '';
					let offerId = '';
					let offerType = '';
					let keyword = '';
					let categoryId = '';
					//ImageUrl 
					if (responseData.cdata.imageUrl != undefined) {
						imageUrl = responseData.cdata.imageUrl;
					}
					//OfferId
					if (responseData.cdata.offerId != undefined) {
						offerId = responseData.cdata.offerId;
					}
					//OfferType
					if (responseData.cdata.offerType != undefined) {
						offerType = responseData.cdata.offerType;
					}
					if (responseData.cdata.keyword != undefined) {
						keyword = decodeURI(responseData.cdata.keyword);
					}
					//CateogryId
					if (responseData.cdata.categoryId != undefined) {
						categoryId = parseInt(responseData.cdata.categoryId);
					} else {
						categoryId = 0;
					}
					if (semusiConfig.appInboxAPPIDS.includes(app_id)) {
						logger.info(`AppInbpox for Panel Now Running In ApnDirect =====>campid===> ${cid}`)
						const userIdArr = common.getUserIdObject(item)
						let useridslength = (userIdArr == undefined ) ? [] : userIdArr
						logger.info(`==== User Ids Data =>==== ${JSON.stringify(useridslength)}`);

						let uattime = new Date();
						let uatepochTime = parseInt(uattime.getTime() / 1000);
						let adid = item.did;

						logger.info(`==== Deliery Type => =>==== ${JSON.stringify(campaigns)}=====>campid===> ${cid}`);
						if (campaigns.dlvy === 'i' || campaigns.dlvy === 'a') {
							logger.info(`====cdata before Delivery Campaign => =>==== ${responseData.cdata}`);
							let cDataObj = Object.keys(responseData.cdata);
							logger.info(`==== cDataObj => =>==== ${cDataObj}`);
							cDataObj.forEach(function (key) {
								responseData.cdata[key] = responseData.cdata[key] ? decodeURIComponent(responseData.cdata[key]) : '';
							});
							if (useridslength.length > 0) {
								//UserId Based AppInbox Now Running
								logger.info(`UserId Based AppInbox Now Running in ApnDirect =====>campid===> ${cid}`)
								let et = parseInt(expiryDate / 1000);
								for (let updateinboxData = 0; updateinboxData < useridslength.length; updateinboxData++) {
									let nid = nidData;
									let result = {
										"nid": nid,
										"mid": nid,
										"notificationId": nid,
										"campid": cid,
										"uat": uatepochTime,
										"ni": responseData.ni,
										"nm": responseData.nd,
										"nt": responseData.nh,
										"ct": "pn",
										"st": "unread",
										"et": et,
										"ln": "en-us",
										"cdata": responseData.cdata
									};
									//Incase of asb Manipulatte the appinbox Payload
									if (responseData.ty === 'asb') {
										let fileExtension = responseData.and.m ? responseData.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 = responseData.cdata.th || '';
										} else {
											let fileName = responseData.and.b + (responseData.and.i[0] || "") + "." + (responseData.and.f || "");
											thumbnailUrl = fileName;
										}
									
										result.cdata.imageUrl = responseData.and.m || ''; // Full URL of media; default to empty string if missing
										result.cdata.th = thumbnailUrl;
									}
									logger.info(`result for Appinbox in IOS ${result}`);
									logger.info(`IOS App Inbox Created In ApnDirect =====>campid===> ${cid}`)
									logger.info(`==== ios inbox payload for iOS  => =>==== ${JSON.stringify(result)}`);
									sendAppInbox.saveUserIDAppInboxdata(app_id, adid, useridslength[updateinboxData], result);
								}

							} else {
								// Did Based AppInboX
								logger.info(`Did Based AppInbox in ApnDirect======>campid===> ${cid}`)
								let et = parseInt(expiryDate / 1000);
								let saveData = {
									"nid": nid,
									"mid": nid,
									"ni": decodeURIComponent(imageUrl),
									"nm": responseData.nd,
									"nt": responseData.nh,
									"ct": "pn",
									"st": "unread",
									"et": et,
									"ln": "en-us",
									"cdata": {
										"keyword": keyword,
										"offerId": offerId,
										"offerType": offerType,
										"notificationType": responseData.cdata.notificationType,
										"imageUrl": decodeURIComponent(imageUrl),
										"categoryId": categoryId,
										"badge": responseData.cdata.badge,
										"puzzle": responseData.cdata.puzzle,
										"promoCode": responseData.cdata.promoCode,
										"filterKey": responseData.cdata.filterKey,
									"filterValue": responseData.cdata.filterValue,
										"restaurantId": responseData.cdata.restaurantId
									}
								};
								//Incase of asb Manipulatte the appinbox Payload
								if (responseData.ty === 'asb') {
									let fileExtension = responseData.and.m ? responseData.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 = responseData.cdata.th || '';
									} else {
										let fileName = responseData.and.b + (responseData.and.i[0] || "") + "." + (responseData.and.f || "");
										thumbnailUrl = fileName;
									}
								
									saveData.cdata.imageUrl = responseData.and.m || ''; // Full URL of media; default to empty string if missing
									saveData.cdata.th = thumbnailUrl;
								}
								logger.info(`saveData for Appinbox in IOS ${saveData}========campid =========${cid}`);
								if (campaigns.dlvy === 'i' || campaigns.dlvy === 'a') {
									logger.info(`==== Did Based App Inbox Updated in Apn Direct  ====>=====>campid===> ${cid}`);
									sendAppInbox.saveAppInboxData(app_id, item.did, saveData);
								}
							}

						}
					}else{
						logger.info(`AppInbox Disabled for this App========CampaignId =========${cid}`)
					}
					logger.info(`item.gcmid==> ${item.gcmid}`);
					if (item.gcmid) {
						let options = {};
						if (optionsData.ios_auth_type == 'p12') {
							options = {
								cert: fs.readFileSync(optionsData.pemFileName, 'utf-8'),
								key: fs.readFileSync(optionsData.pemKeyFileName, 'utf-8'),
								passphrase: optionsData.ios_passphrase,
								production: optionsData.production 
							};
						} else {
							options = {
								token: {
									key: optionsData.cert,
									keyId: optionsData.keyid,
									teamId: optionsData.teamid
								},
								production: optionsData.production
							};
						}
						//adding Proxy key in case it is enabled
						if (semusiConfig.proxyUrl && semusiConfig.proxyPORT) {
							options.proxy = {
								host: semusiConfig.proxyUrl,
								port: semusiConfig.proxyPORT
							}
						}
						let apnProvider = new apn.Provider(options);
						let note = new apn.Notification();
						note.expiry = 1648622643; // Expires 1 hour from now.
						if (payloadData.toolData.badge == true) {
							note.badge = 1;
						}
						if (typeof payloadData.toolData.sound != "undefined" && payloadData.toolData.sound == false) {
							delete note.aps.sound;
						}
						//note.category = "AINotification"; and "actions": [] hide due to follow btn issue 

						//  adding content-available for non sbic App 
						if(app_id!=="5f1408a7d35ea1a37c531e5b" && app_id !== "5fa41afe6fc1e678a8344311"){
							note.contentAvailable=1;
						}

						let responseData = JSON.parse(JSON.stringify(payloadData.toolData));
						// adding mutableContent based on eni value 
						if(respnseData.eni !== ''){
							note.mutableContent = 1;
						}
						note.topic = optionsData.topic;
						logger.info(`responseData=>> ${JSON.stringify(responseData)}=====>campid===> ${cid}`);
						note.alert = { "body": responseData.nd, "title": responseData.nh };
							//RICH PUSH
				    if(responseData.ty == 'asb'){
				    	logger.info(`Rich Push Enabled for Campid ${cid}`)
				    	note = await getRichPushPayload(note,responseData,cid)
				    }else{
						note.payload = { "data": { "message": { "ai_tag": "ai_pn", "campid": payloadData.campid, "nh": responseData.nh, "nd": responseData.nd, "ni": responseData.ni, "end": responseData.end, "eni": responseData.eni, "eurl": responseData.eurl, "et": responseData.et, "cdata": payloadData.toolData.cdata, "mid": nidData, "nid": nidData } } }
					}
					logger.info(`Campaign Push Payload for IOS ==>> ${JSON.stringify(note)}=====>campid===> ${cid}`);
						
						if (campaigns.dlvy === 'd' || campaigns.dlvy === 'a') {
							apnProvider.send(note, item.gcmid).then((result) => {
								logger.info(`========= IOS PUSH SENT LOGS =======> ${JSON.stringify(result)}=====>campid===> ${cid}`);
								if (Array.isArray(result.sent) && result.sent.length) {
									campaignUtils.increaseCountResult(app_id, cid);
								}
							});
						}
						/* remove boi-demo payload */
					} else {
						logger.info(`APN Token not found for push =>> ${item}`);
					}
				});
				let dataRes = { responses: camp_res };
				dataConsumer.processCampaignResponses([{ appid: appid, dataArray: dataRes }], function (status) {

				});
			}
		}
	}


	apnPush.pushTransactional = function (options, devices, payload) {
		apnConnection = new apn.Connection(options);
		let camp_res = [];
		let dataArray = [];
		let appid = '';
		devices.forEach(function (item) {
			if (item) {
				let myDevice = new apn.Device(item);
				let note = new apn.Notification();
				note.payload = payload;
				note.badge = 1;
				note.expiry = Math.floor(Date.now() / 1000) + 86400; // Expires 1 Day from now.
				note.alert = payload.nh;
				logger.info(`note apns=> ${note}`)
				let responseData = apnConnection.pushNotification(note, myDevice); // send direct push
				// silent push start
				note1 = new apn.Notification();
				//note1.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
				note1.payload = { 'COMMAND': "#CAMPAIGNUPDATE", aps: { "content-available": true } };

				apnConnection.pushNotification(note1, myDevice);
				logger.info(`responseData=> ${responseData}`);
			}
			else {
				logger.info(`APN Token not found for push  => ${item}`);
			}
		});
		let data = { responses: camp_res };
		dataConsumer.processCampaignResponses([{ appid: appid, dataArray: data }], function (status) {

		});
	}

	async function getRichPushPayload(note, responseData, cid) {

		logger.info(`Creating Rich PUSH for APN`)

		if (responseData.and == undefined) {
			responseData.and = { "m": responseData.eni };
		}


		note.payload = {
			data: {
				message: {
					"ai_tag": "ai_pn",
					"camp_id": cid,
					"tid": "64df33b591482ebcd5f10f5f",
					"nh": responseData.nh,
					"nd": responseData.n,
					"ni": responseData.ni,
					"end": "",
					"eni": responseData.eni,
					"ty": "asb",
					"and": responseData.and,
					"eurl": responseData.eurl,
					"et": responseData.et,
					"actions": responseData.actions,
					"cdata": responseData.cdata,
				}
			}
		};
		return note

	}
	async function populatePushObject(template) {
		let data = {};
		data.nh = template.notificationHeader;
		data.nd = template.notificationDescription;
		data.ni = template.notificationImage;
		data.end = template.expandedNotificationDescription;
		data.eni = template.expandedNotificationImage;
		data.eurl = template.externalUrl;
		data.et = template.notificationType;
		data.actions = template.actions;
		data.sound = template.sound;
		data.vibrate = template.vibrate;
		data.badge = template.badge;
		if (template.cdata) {
			let cdataObj = template.cdata

			cdataObj = await common.getCdataObj(template.cdata)
			data.cdata = cdataObj;
		}
		return data;
	}

	apnPush.sendInAppPush = function (appid, devices, options, cid) {
		logger.info(`Sending In App Push Code initiated =======CampaignId =========${cid}`)
		let template;
		apnPush.getActiveCmpData(appid, cid).then((cmpData) => {
			apnPush.sendCommonPush(cmpData, options, devices, appid, cid).then((success) => {
				logger.info(`send in app push=> ${JSON.stringify(success)}=====>campid===> ${cid}`);
			})
				.catch(error => {
					logger.info(`error catch common in app push=> ${error}=====>campid===> ${cid}`);
				});
		})
			.catch(error => {
				logger.info(`error send in app push=> ${error}=====>campid===> ${cid}`);
			});

	}

	// function toget cmp data  to send inapp push 
	apnPush.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) {
						let cmpLenght = result[0].data.length;
						resolve(result[0].data[cmpLenght - 2]);
					} else {
						reject(err);
					}
				});

			}, 2000);
		})
	}

	apnPush.sendCommonPush = function (data, optionsData, devices, app_id, cid) {
		return new Promise((resolve, reject) => {
			//delete sql query before seding payload
			if (data.aud.userQ != undefined) {
				delete data.aud.userQ;
			}
			if (data.aud.q != undefined) {
				delete data.aud.q;
			}

			//config prepare with data
			devices.forEach(function (item) {
				logger.info(`item.gcmid==> ${item.gcmid}`);
				if (item.gcmid) {
					let options = {};
					if (optionsData.ios_auth_type == 'p12') {
						options = {
							cert: fs.readFileSync(optionsData.pemFileName, 'utf-8'),
							key: fs.readFileSync(optionsData.pemKeyFileName, 'utf-8'),
							passphrase: optionsData.ios_passphrase,
							production: optionsData.production 
						};
					} else {
						options = {
							token: {
								key: optionsData.cert,
								keyId: optionsData.keyid,
								teamId: optionsData.teamid
							},
							production: optionsData.production
						};
					}
					//adding Proxy key in case it is enabled
					if (semusiConfig.proxyUrl && semusiConfig.proxyPORT) {
						options.proxy = {
							host: semusiConfig.proxyUrl,
							port: semusiConfig.proxyPORT
						}
					}
					let apnProvider = new apn.Provider(options);
					let note = new apn.Notification();
					note.expiry = Math.floor(Date.now() / 1000) + 3600; // Expires 1 hour from now.
					//note.badge = 0;
					//note.mutableContent = 1;
					//note.sound = "ping.aiff";
					note.alert = "";
					note.topic = optionsData.topic;
					note.contentAvailable = 1;

					// If the values are not set , Set its default 
					data.delayi = ( data.delayi ) ?  data.delayi : 0  ;
					data.delays =  ( data.delays ) ?  data.delays : 0 ;
					data.delayu =  ( data.delayu ) ?  data.delayu : "Seconds";
					// data._id = "62eba7ba14bf6c61caa76f07";
					note.payload = {
						"data": {
							"message": {
								"ai_tag": "ai_pn",
								"activeCampaigns": [data],
								"sp": "true"
							}
						}
					};
					logger.info(`Campaign With Silent Push Payload for IOS ==>> ${JSON.stringify(note)}=====>campid===> ${cid}`);
						//  adding content-available for non sbic App 
						if(app_id!=="5f1408a7d35ea1a37c531e5b" && app_id == "5fa41afe6fc1e678a8344311"){
							note.contentAvailable=1;
						}
				
					apnProvider.send(note, item.gcmid).then((result) => {
						logger.info(`========= IOS SENT LOGS =======> ${JSON.stringify(result)}=====>campid===> ${cid}`);
						if (Array.isArray(result.sent) && result.sent.length) {
							campaignUtils.increaseCountResult(app_id, cid);
						}
						resolve(result);
					});

				} else {
					logger.info(`APN Token not found for push =>> ${item}=====>campid===> ${cid}`);
					reject("GCM ID NOT FOUND");
				}
			});
		})
	}
}(apnPush));

module.exports = apnPush;