require('dotenv').config();
const express = require('express');
const serverModel = require('./model/servermodel');
const Resp = require('./helper/response');
const Info = require('./helper/info');
const Log = require('./helper/log');
const mailOperation = require('./mailOperation');
const Mailer = require('./helper/mailer');
const Smsprocess = require('./helper/sms');
const Whatsapp = require('./helper/whatsapp');
const crypto = require('crypto');
const cors = require('cors');

const fs = require('fs');
const path = require('path');
const moment = require('moment');
const { Console } = require('console');

const allData = {};
const queueData = {};
const conversationType = {};
const outgoingMailData = {};
const queueIds = {};

const app = express();
app.use(cors());

function queueEmailServerDetails() {
   return new Promise(async (resolve, reject) => {
      try {
         const result = await serverModel.getData();
         if (result.status !== true || result.data.length === 0) {
            throw new Error('No data found.');
         }
         result.data.forEach((resultKey, index) => {
            allData[index] = {
               'queue_id': resultKey['queue_id'],
               'id': resultKey['id'],
               'server_type': resultKey['server_type'],
               'email': resultKey['email'],
               'display_name': resultKey['display_name'],
               'exchange_service': resultKey['exchange_service'],
               'incoming_user_name': resultKey['incoming_user_name'],
               'incoming_password': resultKey['incoming_password'],
               'outgoing_user_name': resultKey['outgoing_user_name'],
               'outgoing_password': resultKey['outgoing_password'],
               'incoming_mail_server': resultKey['incoming_mail_server'],
               'incoming_mail_server_port': resultKey['incoming_mail_server_port'],
               'incoming_enable_SSL': resultKey['incoming_enable_SSL'],
               'stop_incoming_email': resultKey['stop_incoming_email'],
               'outgoing_mail_server': resultKey['outgoing_mail_server'],
               'outgoing_mail_server_port': resultKey['outgoing_mail_server_port'],
               'outgoing_enable_SSL': resultKey['outgoing_enable_SSL'],
               'stop_outgoing_email': resultKey['stop_outgoing_email'],
               'security_protocol': resultKey['security_protocol'],
               'dont_read_mail_before': resultKey['dont_read_mail_before'],
               'max_reopen_days': resultKey['reopen_after'],
               'reopen_to_same_agent': resultKey['reopen_to_same_agent'],
               'block_email_for_ticket_generate': resultKey['block_email_for_ticket_generate'],
               'block_email_for_auto_reply': resultKey['block_email_for_auto_reply'],
               'block_domains_for_ticket_generate': resultKey['block_domains_for_ticket_generate'],
               'block_domains_for_auto_reply': resultKey['block_domains_for_auto_reply'],
               'forwarded_mail': resultKey['forwarded_mail'],
               'ticket_prefix': resultKey['ticket_prefix'],
               'tenant_id': resultKey['tenant_id'],
               'client_secret': resultKey['client_secret'],
               'client_oauth2_id': resultKey['client_oauth2_id'],
               'is_auth_enable': resultKey['is_auth_enable'],
               'token': resultKey['token'],
               'refresh_token': resultKey['refresh_token'],
               'dont_read_unread_mail': resultKey['dont_read_unread_mail'],
               'last_read_date': resultKey['last_read_date']
            };
         });
         resolve(allData);
      } catch (error) {
         console.log({ error: error });
         reject(error);
      }
   });
}

async function getQueueData() {
   try {
      for (key in allData) {
         let queue_id = allData[key].queue_id
         let id = allData[key].id
         let res = await serverModel.getQueueData(queue_id);
         if (res.status === true && res.data && res.defstatus && res.defpriority !== undefined && res.defclose !== undefined && res.queueIncMailStatus !== undefined) {
            queueData[queue_id] = {
               "data": res.data,
               "defstatus": res.defstatus,
               "defpriority": res.defpriority,
               "defclose": res.defclose,
               "queueIncMailStatus": res.queueIncMailStatus,
               "queueCatAndSubCat": res.queueCatAndSubCat
            }
         } else {
            console.log(`In getQueueData(${queue_id}) function all data is not present`, JSON.stringify(res))
         }
         let outgoingMailDataRes = await serverModel.outgoingMailData(queue_id, id);

         if (outgoingMailDataRes.status == true) {
            outgoingMailData[queue_id] = {
               "data": outgoingMailDataRes.data[0]
            }
         } else {
            console.log(`In outgoingMailData(${queue_id},${id}) function alldata is not present `, JOSN.stringify(outgoingMailDataRes))
         }

      }
      return { queueData, outgoingMailData };
   } catch (error) {
      console.log("An error occurred in getQueueData:", error);
      throw error;
   }
}

exports.handleQueueOperations = async () => {
   try {
      const res = await queueEmailServerDetails();

      if (Object.keys(res).length > 0) {

         const queueDataRes = await getQueueData();

         if (Object.keys(queueDataRes.queueData).length > 0 && (Object.keys(queueDataRes.outgoingMailData).length > 0)) {

            const conversationDataRes = await getConversationType();

            if (Object.keys(conversationDataRes.conversationType).length > 0) {

               const getQueueIdRes = await getQueueId()

               if (Object.keys(getQueueIdRes.queueIds.data)) {
                  return { status: true };
               } else {
                  console.log("No data available in getQueueIdRes");
               }

            } else {
               console.log("No data available in conversationDataRes");
            }

         }
      } else {
         console.log("No data available in queueEmailServerDetails");
      }
   } catch (err) {
      console.log("An error occurred queueEmailServerDetails:", err);
      throw err
   }
}

async function getConversationType() {
   try {
      let res = await serverModel.getConversationType();
      if (res.status == true) {
         Object.assign(conversationType, {
            "data": res.data
         });
         return { conversationType };
      } else {
         console.log(`No data Found getConversationType: ${res}`);
      }
   } catch (err) {
      console.log("An error occurred getConversationType:", err);
      throw err;
   }
}

async function getQueueId() {
   try {
      let res = await serverModel.getQueueId();
      if (res.status == true) {
         Object.assign(queueIds, {
            "data": res.data
         });
      } else {
         console.log(`No data Found getQueueId:${res}`);
      }
      return { queueIds }
   } catch (err) {
      console.log("An error occurred getQueueId:", err)
   }
}

// isReadingMail = false;

const readMail = function () {
   return new Promise((resolve, reject) => {
      if (Object.keys(allData).length > 0) {
         for (let i = 0; i < Object.keys(allData).length; i++) {
            let res = allData[i]
            console.log("res", res)
            if (res.server_type.toLowerCase() === 'pop3') {
               mailOperation.processPop3Mail(res, (error, mail) => {
                  if (error) {
                     Log.incErrorLog({ error: error });
                  }
               });
            } else if (res.server_type.toLowerCase() === 'exchange') { }
            else if (res.server_type.toLowerCase() === 'imap') {
               mailOperation.processIMAP(res, (error, mail) => {
                  if (error) {
                     Log.incErrorLog({ error: error });
                  } else if (mail != null) {
                     afterMailProcess(res, mail)
                  }
               });
            }
         }
         resolve({ status: true });
      } else {
         const errorMessage = "allData variable is empty.";
         Log.incErrorLog({ error: errorMessage });
         reject(new Error(errorMessage));
      }
   });
}



var afterMailProcess = function (allData, mail) {
   let queue_id = allData.queue_id;
   if (queueData[queue_id].data && queueData[queue_id].defstatus && queueData[queue_id].defpriority != undefined && queueData[queue_id].defclose != undefined && queueData[queue_id].queueIncMailStatus && conversationType && conversationType.data.id !== undefined) {
      var queueMasterData = queueData[queue_id].data;
      var defStatusData = queueData[queue_id].defstatus;
      var defPriorityData = queueData[queue_id].defpriority;
      var defclose = queueData[queue_id].defclose;
      var queueIncMailStatus = queueData[queue_id].queueIncMailStatus
      var defconversationType = conversationType.data.id
      var defCatSubData = queueData[queue_id].queueCatAndSubCat
      if ('replyTicketDataList' in mail) { // if reply data is found in the ticket then reopen or new ticket 

         const { replyTicketDataList } = mail
         var ticketUnqId = replyTicketDataList[0].ticket_unique_id;
         var conversationStatus = replyTicketDataList[0].status_id;
         var conversationDate = replyTicketDataList[0].conversation_date;
         var conversationId = replyTicketDataList[0].conversation_id;
         var mailDate = mail.headerData.date
         const diffInDays = moment(mailDate).diff(moment(conversationDate), 'days');

         serverModel.updateNewStatus(ticketUnqId, allData.queue_id).then((updateRes) => {
            if (updateRes.status == true) {
               if (defclose.split(',').includes(conversationStatus.toString())) {// if ticket is closd then condition
                  if (diffInDays <= allData.max_reopen_days && allData.max_reopen_days != 0) { // reopen case 
                     var emailBody = Buffer.from(mail.bodyData, 'base64').toString('utf-8');
                     emailBody = emailBody.replace(/\n/g, '<br>')
                     allData['emailBody'] = emailBody;
                     ruleProcess(allData, ticketUnqId)

                     if (queueIncMailStatus != "") {
                        let status_id = queueIncMailStatus
                        serverModel.updateMailStatusAfterClose(allData.queue_id, status_id, ticketUnqId, mail.headerData.date).then((updateResult) => {
                           if (updateResult.status == true) {
                              serverModel.getConversationData(conversationId, allData.queue_id, ticketUnqId).then((conversationResult) => {
                                 if (conversationResult.status == true) {
                                    var conversationData = conversationResult.data;
                                    serverModel.saveReplyToMialData(conversationData, mail, allData, ticketUnqId, status_id).then((result) => {
                                       if (result.status == true) {
                                          if (queueMasterData.auto_reply == 1) {
                                             //get templateData of queueIncMailStatus
                                             serverModel.getStatusData(status_id, allData.queue_id).then((result) => {
                                                if (result.status == true) {
                                                   let reopenStatusData = result.data
                                                   if (reopenStatusData[0].template_id != null || reopenStatusData[0].template_id != undefined) {
                                                      reopenStatusData[0].ticket_link = `<a href="http://localhost:4200/ticket-search?backLink=ticket-search&queue_id=${allData.queue_id}&ticket_unique_id=${ticketUnqId}">${reopenStatusData[0].status_name}</a>`
                                                      let outgoingData = outgoingMailData[queue_id].data;
                                                      let dynamic_master_name = "tms_dynamicform_fields_" + allData.queue_id;

                                                      //get ticketdata of the reopen ticket start here
                                                      serverModel.getTicketDetails(ticketUnqId, allData.queue_id).then((ticketDetailsRes) => {
                                                         if (ticketDetailsRes.status == true) {
                                                            var ticketDetails = ticketDetailsRes.data
                                                            const { headerData } = mail;
                                                            if (reopenStatusData[0].customer_email == 1) { // customer mail
                                                               const uuid = generateUUID() + outgoingData.outgoing_mail_server + '>';
                                                               const msg_id = generateMsgId(uuid)
                                                               serverModel.setEmailSmsTemplate("mail", reopenStatusData, ticketDetails, mail, outgoingData, dynamic_master_name).then((finalTemplate) => {
                                                                  if (finalTemplate.status == true) {
                                                                     // let emailSubject = finalTemplate.emailSubject
                                                                     let emailBody = finalTemplate.emailBody
                                                                     let conversationData = {
                                                                        'queue_id': outgoingData.queue_id,
                                                                        'from_email': outgoingData.outgoing_user_name,
                                                                        'to_email': ticketDetails[0].to_email,
                                                                        'cc_email': ticketDetails[0].cc_email,
                                                                        'subject': headerData.subject !== undefined
                                                                           ? headerData.subject
                                                                           : null,
                                                                        'status_id': ticketDetails[0].status_id,
                                                                        'priority_id': ticketDetails[0].priority_id,
                                                                        'email_status': 'New',
                                                                        'uuid': uuid,
                                                                        'msg_id': msg_id,
                                                                        'conversation': emailBody,
                                                                        'account_id': outgoingData.id
                                                                     }

                                                                     serverModel.saveMailData("auto reply email", conversationData, ticketDetails[0].ticket_id, ticketDetails[0].ticket_unique_id).then((result) => {
                                                                        if (result.status == true) {
                                                                           createMailJsonFile(conversationData);
                                                                        }
                                                                     });
                                                                  }
                                                               })
                                                            }
                                                            // if (reopenStatusData[0].customer_sms == 1) { // customer sms
                                                            //    if (ticketDetails[0].mobile_no == null || ticketDetails[0].mobile_no == '') {
                                                            //       Log.incErrorLog(`Customer mobile no not found for sending SMS ticket_id : ${ticketDetails[0].ticket_unique_id}`);
                                                            //       return;
                                                            //    }
                                                            // }
                                                            if (reopenStatusData[0].customer_wp == 1) { // customer whatsapp
                                                               const uuid = generateUUID() + outgoingData.outgoing_mail_server + '>';
                                                               const msg_id = generateMsgId(uuid)
                                                               if (ticketDetails[0].mobile_no == null || ticketDetails[0].mobile_no == '') {
                                                                  Log.incErrorLog(`Customer mobile no not found for sending whatsapp ticket_id : ${ticketDetails[0].ticket_unique_id}`);
                                                                  return;
                                                               } else {
                                                                  serverModel.setEmailSmsTemplate("customer_wp", reopenStatusData[0], ticketDetails, mail, outgoingData, dynamic_master_name).then((finalTemplate) => {
                                                                     if (finalTemplate.status == true) {
                                                                        var smsBody = finalTemplate.smsBody
                                                                        let conversationData = {
                                                                           'queue_id': outgoingData.queue_id,
                                                                           'from_email': null,
                                                                           'to_email': null,
                                                                           'cc_email': null,
                                                                           'mobile_no': ticketDetails[0].mobile_no,
                                                                           'person_name': ticketDetails[0].person_name,
                                                                           'status_id': ticketDetails[0].status_id,
                                                                           'priority_id': ticketDetails[0].priority_id,
                                                                           'subcategory_id': ticketDetails[0].subcategory_id,
                                                                           'category_id': ticketDetails[0].category_id,
                                                                           'whatsapp_status': 'New',
                                                                           'uuid': uuid,
                                                                           'msg_id': msg_id,
                                                                           'conversation': smsBody,
                                                                        }
                                                                        serverModel.saveMailData("auto reply whatsapp", conversationData, ticketDetails[0].ticket_id, ticketDetails[0].ticket_unique_id).then((result) => {
                                                                           if (result.status == true) {
                                                                              createMailJsonFile(conversationData);
                                                                           }
                                                                        })

                                                                     }
                                                                  })
                                                               }
                                                            }
                                                            if (reopenStatusData[0].user_email == 1) { // agent mail
                                                               const uuid = generateUUID() + outgoingData.outgoing_mail_server + '>';
                                                               const msg_id = generateMsgId(uuid)

                                                               ticketDetails[0].user_email_subject = reopenStatusData[0].user_email_subject

                                                               ticketDetails[0].user_email_template = reopenStatusData[0].user_email_template

                                                               serverModel.setEmailSmsTemplate("user_mail", ticketDetails[0], '', mail, outgoingData, dynamic_master_name).then((finalTemplate) => {
                                                                  if (finalTemplate.status == true) {
                                                                     let emailSubject = finalTemplate.emailSubject
                                                                     let emailBody = finalTemplate.emailBody
                                                                     let conversationData = {
                                                                        'queue_id': outgoingData.queue_id,
                                                                        'from_email': outgoingData.outgoing_user_name,
                                                                        'to_email': ticketDetails[0].agent_email_id,
                                                                        'subject': emailSubject,
                                                                        'status_id': ticketDetails[0].status_id,
                                                                        'priority_id': ticketDetails[0].priority_id,
                                                                        'email_status': 'New',
                                                                        'uuid': uuid,
                                                                        'msg_id': msg_id,
                                                                        'conversation': emailBody,
                                                                        'account_id': outgoingData.id
                                                                     }
                                                                     serverModel.saveMailData("auto reply email", conversationData, ticketDetails[0].ticket_id, ticketDetails[0].ticket_unique_id).then((result) => {
                                                                        if (result.status == true) {
                                                                           createMailJsonFile(conversationData);
                                                                        }
                                                                     });
                                                                  }
                                                               })
                                                            }
                                                            // if (reopenStatusData[0].user_sms == 1) { // agent sms
                                                            // }
                                                            // if (reopenStatusData[0].user_wp == 1) { // agent whatsapp

                                                            //    const uuid = generateUUID() + outgoingData.outgoing_mail_server + '>';
                                                            //    const msg_id = generateMsgId(uuid)
                                                            //    if (ticketDetails[0].mobile_no == null || ticketDetails[0].mobile_no == '') {
                                                            //       Log.incErrorLog(`Agent Mobile  no not found for sending whatsapp ticket_id : ${ticketDetails[0].ticket_unique_id}`);
                                                            //       return;
                                                            //    } else {serverModel.setEmailSmsTemplate("customer_wp", reopenStatusData[0], ticketDetails, mail, outgoingData, dynamic_master_name).then((finalTemplate) => {
                                                            //    })
                                                            //    }
                                                            // }
                                                         }
                                                      })

                                                      //get ticketdata of the reopen ticket ends here
                                                   } else {
                                                      Log.incErrorLog(`No template found for reopen status in queue_id : ${allData.queue_id}`);
                                                   }
                                                }
                                             })
                                          }
                                          return;
                                       }
                                    });
                                 }
                              });
                           }


                        })

                     } else {
                        Log.incErrorLog(`Incomming mail status is required (After Ticket Closed) queue_id : ${allData.queue_id}`);
                     }
                     // only conversation entry with incomming_mail_status as status
                  }
                  else { // new ticket case
                     serverModel.getTicketId(allData.queue_id).then((result) => {
                        if (result.data != '') {
                           var ticketNo = result.data.ticketNo
                           // serverModel.getTicketSeries(allData.queue_id).then((result) => {
                           //     if (result.data.ticket_prefix != "") {
                           let ticketSeries = allData.ticket_prefix;
                           let ticket_prefix = [ticketSeries.substring(0, ticketSeries.indexOf('[')), ticketSeries.substring(ticketSeries.indexOf('['))];
                           var series = generateSeries(ticketSeries, ticketNo);
                           if (series.status == true) {
                              if (series.data != "") {
                                 var series = series.data
                                 const prefixArr = {
                                    "ticket_prefix": ticket_prefix[0],
                                    "ticket_series": series,
                                    "ticket_no": ticketNo
                                 }
                                 serverModel.ticketData(allData, mail, prefixArr, queueMasterData, defStatusData.status_id, defPriorityData, defconversationType, defCatSubData).then((result) => {
                                    if (result.status == true) {
                                       var ticket_unique_id = result.data
                                       var emailBody = Buffer.from(mail.bodyData, 'base64').toString('utf-8');
                                       emailBody = emailBody.replace(/\n/g, '<br>')
                                       allData['emailBody'] = emailBody;
                                       ruleProcess(allData, ticket_unique_id)
                                    }
                                    if (queueMasterData.auto_reply == 1) {
                                       if (Object.keys(outgoingMailData).length > 0) {
                                          loadEmailTemplateData(outgoingMailData[queue_id].data, mail, defStatusData, ticket_unique_id)
                                       }

                                    }
                                 });

                              } else {
                                 Log.incErrorLog("Ticket Prefix is required");
                              }
                           }

                        }
                     });
                  }
               }
               else { // if ticket is not closd then condition
                  serverModel.getConversationData(conversationId, allData.queue_id, ticketUnqId).then((conversationResult) => {
                     if (conversationResult.status == true) {
                        var conversationData = conversationResult.data;
                        serverModel.saveReplyToMialData(conversationData, mail, allData, ticketUnqId).then((result) => {
                           if (result.status == true) {
                              return;
                           }
                        });
                     }
                  });
               }
            }
         });
      } else { // new ticket entry
         serverModel.getTicketId(queue_id).then((result) => {
            if (result.data != '') {
               var ticketNo = result.data.ticketNo
               let ticketSeries = allData.ticket_prefix;
               let ticket_prefix = [ticketSeries.substring(0, ticketSeries.indexOf('[')), ticketSeries.substring(ticketSeries.indexOf('['))];
               var series = generateSeries(ticketSeries, ticketNo);
               if (series.status == true && series.data != "") {
                  var series = series.data
                  const prefixArr = {
                     "ticket_prefix": ticket_prefix[0],
                     "ticket_series": series,
                     "ticket_no": ticketNo
                  }
                  serverModel.ticketData(allData, mail, prefixArr, queueMasterData, defStatusData.status_id, defPriorityData, defconversationType, defCatSubData).then((result) => {
                     if (result.status == true) {
                        var ticket_unique_id = result.data
                        var emailBody = Buffer.from(mail.bodyData, 'base64').toString('utf-8');
                        emailBody = emailBody.replace(/\n/g, '<br>')
                        allData['emailBody'] = emailBody;
                        ruleProcess(allData, ticket_unique_id) // check rule for new ticket
                     }
                     if (queueMasterData.auto_reply == 1) {
                        if (allData.block_email_for_auto_reply != "") {
                           const blockEmailIds = allData.block_email_for_auto_reply.split(',');
                           let from_email = mail.headerData.from['value'][0].address
                           const isBlocked = blockEmailIds.some(blockedEmail => from_email.includes(blockedEmail));

                           if (isBlocked) {
                              Log.incErrorLog(` ${from_email} this From Email is blocked For Auto Reply in queue_id ${queue_id}`);
                              return;
                           }
                        }
                        if (allData.block_domains_for_auto_reply != "") {
                           const blockDomains = allData.block_domains_for_auto_reply.split(',');
                           let from_email = mail.headerData.from['value'][0].address
                           let isBlocked = blockDomains.some(domain => from_email.includes(domain));
                           if (isBlocked) {
                              Log.incErrorLog(` ${from_email} this From Email has blocked  Domain For Auto Reply in queue_id ${queue_id}`);
                              return;
                           }
                        }
                        if (Object.keys(outgoingMailData).length > 0) {
                           loadEmailTemplateData(outgoingMailData[queue_id].data, mail, defStatusData, ticket_unique_id) // load template data on ticket
                        } else {
                           console.log(`outgoingMailData not found`)
                        }
                     }

                  })
               } else {
                  console.log("series is required");
                  // series is required
               }
            }
         });
      }
   } else {
      console.log(`queueData is required ${queueData[queue_id]}`)
   }
}

var loadEmailTemplateData = function (emailidData, mailData, defStatusData, ticketId) {
   if (defStatusData.template_id != null) {
      serverModel.getTemplateData(defStatusData.template_id, emailidData.queue_id).then((templateResult) => {
         if (templateResult.status == true && templateResult.data.length > 0) {
            var templateData = templateResult.data;
            serverModel.getTicketDetails(ticketId, emailidData.queue_id).then((ticketDetailsRes) => {
               if (ticketDetailsRes.status == true) {
                  var ticketDetails = ticketDetailsRes.data

                  serverModel.getStatusName(ticketDetails[0].status_id, emailidData.queue_id).then((StatusNameRes) => {
                     if (StatusNameRes.status == true) {
                        var statusName = StatusNameRes.data;
                        ticketDetails[0].ticket_link = `<a href="http://localhost:4200/ticket-search?backLink=ticket-search&queue_id=${ticketDetails[0].queue_id}&ticket_unique_id=${ticketId}">${statusName.status_name}</a>`


                        if (defStatusData.customer_email == 1) {
                           let dynamic_master_name = "tms_dynamicform_fields_" + emailidData.queue_id;
                           serverModel.setEmailSmsTemplate("mail", templateData, ticketDetails, mailData, emailidData, dynamic_master_name).then((finalTemplate) => {
                              if (finalTemplate.status == true) {
                                 var emailSubject = finalTemplate.emailSubject
                                 var emailBody = finalTemplate.emailBody
                                 const { headerData } = mailData;
                                 const uuid = generateUUID() + emailidData.outgoing_mail_server + '>';
                                 const msg_id = generateMsgId(uuid)
                                 let conversationData = {
                                    'queue_id': emailidData.queue_id,
                                    'from_email': emailidData.outgoing_user_name,
                                    'to_email': ticketDetails[0].from_email,
                                    'cc_email': ticketDetails[0].cc_email,
                                    'subject': emailSubject,
                                    'status_id': ticketDetails[0].status_id,
                                    'priority_id': ticketDetails[0].priority_id,
                                    'email_status': 'New',
                                    'uuid': uuid,
                                    'msg_id': msg_id,
                                    'conversation': emailBody,
                                    'account_id': emailidData.id
                                 }

                                 serverModel.saveMailData("auto reply email", conversationData, ticketDetails[0].ticket_id, ticketDetails[0].ticket_unique_id).then((result) => {
                                    if (result.status == true) {
                                       createMailJsonFile(conversationData, mailData, result.data, ticketDetails[0].ticket_id, ticketDetails[0].ticket_unique_id);
                                    }
                                 });
                              }
                           });
                        }
                        // if (defStatusData.customer_sms == 1) {
                        //     let dynamic_master_name = "tms_dynamicform_fields_" + emailidData.queue_id;
                        //     serverModel.setEmailSmsTemplate("customer_sms", templateData, ticketDetails, mailData, emailidData, dynamic_master_name).then((finalTemplate) => {
                        //         if (finalTemplate.status == true) {
                        //             var smsBody = finalTemplate.smsBody
                        //             const { headerData } = mailData;
                        //             const uuid = generateUUID() + emailidData.outgoing_mail_server + '>';
                        //             const msg_id = generateMsgId(uuid)
                        //             let conversationData = {
                        //                 'queue_id': emailidData.queue_id,
                        //                 'status_id': ticketDetails[0].status_id,
                        //                 'priority_id': ticketDetails[0].priority_id,
                        //                 'sms_status': 'New',
                        //                 'email_status': '',
                        //                 'uuid': uuid,
                        //                 'msg_id': msg_id,
                        //                 'conversation': smsBody,
                        //                 'account_id': emailidData.id
                        //             }

                        //             serverModel.saveMailData("auto reply sms", conversationData, ticketDetails[0].ticket_id, ticketDetails[0].ticket_unique_id).then((result) => {
                        //                 if (result.status == true) {
                        //                     console.log("conversationData",conversationData)
                        //                     createMailJsonFile(conversationData);
                        //                 }
                        //             });
                        //         }
                        //     });
                        // }
                     }
                  })
               }
            });
         } else {
            Log.incErrorLog("No template Assigned for queue id :" + emailidData.queue_id);
            // console.log("No template Assigned fro queue id :" + emailidData.queue_id);
         }
      })
   }
}

var ruleProcess = async function (allData, ticket_unique_id) {
   try {

      const result = await serverModel.getRuleMasterData(allData.queue_id);

      if (result.status == true) {
         const ruleMasterData = result.data;

         if (ruleMasterData.length > 0) {
            const ticketDetailsRes = await serverModel.getTicketDetails(ticket_unique_id, allData.queue_id);

            if (ticketDetailsRes.status == true) {
               const ticketDetails = ticketDetailsRes.data;
               for (let index = 0; index < ruleMasterData.length; index++) {
                  let AnyCond = false;
                  let AllCond = false;
                  let resultKey = ruleMasterData[index];
                  let ruleId = resultKey['rule_id'];
                  const ruleConditionRes = await serverModel.getRuleCondition(allData.queue_id, ruleId);

                  if (ruleConditionRes.status == true) {
                     const ruleConditionData = ruleConditionRes.data;

                     if (ruleConditionData.length > 0) {
                        if (resultKey['match'] == "match_any") {
                           for (let j = 0; j < ruleConditionData.length; j++) {
                              var key = ruleConditionData[j];

                              switch (key['evaluate_on']) {
                                 case "From Email":
                                    if (checkCondition(ticketDetails[0].from_email, key['operator'], key['evaluate_value'])) {
                                       AnyCond = true;
                                       break;
                                    }
                                    break;
                                 case "To Email":
                                    if (checkCondition(ticketDetails[0].to_email, key['operator'], key['evaluate_value'])) {
                                       AnyCond = true;
                                       break;
                                    }
                                    break;
                                 case "CC Email":
                                    if (checkCondition(ticketDetails[0].cc_email, key['operator'], key['evaluate_value'])) {
                                       AnyCond = true;
                                       break;
                                    }
                                    break;
                                 case "Subject":
                                    if (checkCondition(ticketDetails[0].subject, key['operator'], key['evaluate_value'])) {
                                       AnyCond = true;
                                       break;
                                    }
                                    break;
                                 case "Priority":
                                    if (checkCondition(ticketDetails[0].priority_id, key['operator'], key['evaluate_value'])) {
                                       AnyCond = true;
                                       break;
                                    }
                                    break;
                                 case "Mail Body":
                                    if (checkCondition(allData.emailBody, key['operator'], key['evaluate_value'])) {
                                       AnyCond = true;
                                       break;
                                    }
                                    break;
                              }
                           }
                        } else if (resultKey['match'] == "match_all") {

                           for (let j = 0; j < ruleConditionData.length; j++) {
                              var anykey = ruleConditionData[j];

                              switch (anykey['evaluate_on']) {
                                 case "From Email":
                                    AllCond = checkCondition(ticketDetails[0].from_email, anykey['operator'], anykey['evaluate_value']);
                                    break;
                                 case "To Email":
                                    AllCond = checkCondition(ticketDetails[0].to_email, anykey['operator'], anykey['evaluate_value'])
                                    break;
                                 case "CC Email":
                                    AllCond = checkCondition(ticketDetails[0].cc_email, anykey['operator'], anykey['evaluate_value'])
                                    break;
                                 case "Subject":
                                    AllCond = checkCondition(ticketDetails[0].subject, anykey['operator'], anykey['evaluate_value'])
                                    break;
                                 case "Priority":
                                    AllCond = checkCondition(ticketDetails[0].priority_id, anykey['operator'], anykey['evaluate_value'])
                                    break;
                                 case "Mail Body":
                                    AllCond = checkCondition(allData.emailBody, anykey['operator'], anykey['evaluate_value'])
                                    break;
                              }
                              if (!AllCond) {
                                 break;
                              }
                           }
                        }
                     }
                  }
                  if (AnyCond || AllCond) {
                     PerformRuleAction(allData.queue_id, ticket_unique_id, ruleId, allData.id);
                  }
               }
            }
         }
      }
   } catch (error) {
      // Handle errors here
      Log.incErrorLog(error);
   }
};

var checkCondition = function (EvaluateOn, Operator, EvaluateValue) {
   var res = false;
   if (!EvaluateOn || !EvaluateValue) {
      res = false;
   } else {
      var evaluateOnArray = EvaluateOn.includes(',') ? EvaluateOn.split(',').map(value => value.trim()) : [EvaluateOn];
      var evaluateValueArray = EvaluateValue.includes(',') ? EvaluateValue.split(',').map(value => value.trim()) : [EvaluateValue];

      if (Operator.toUpperCase() === "IS") {
         if (evaluateOnArray.some(value => evaluateValueArray.includes(value))) {
            res = true;
         }
      } else if (Operator.toUpperCase() === "IS NOT") {
         if (!evaluateOnArray.some(value => evaluateValueArray.includes(value))) {
            res = true;
         }
      } else if (Operator.toUpperCase() === "CONTAINS") {

         if (evaluateOnArray.some(evaluateOnValue => evaluateValueArray.some(evaluateValue => evaluateOnValue.includes(evaluateValue)))) {
            res = true;
         }
      } else if (Operator.toUpperCase() === "DOES NOT CONTAIN") {
         if (!evaluateOnArray.some(evaluateOnValue => evaluateValueArray.some(evaluateValue => evaluateOnValue.includes(evaluateValue)))) {
            res = true;
         }
      }
   }
   return res;
}

var PerformRuleAction = function (queue_id, TicketId, RuleId, acc_id) {
   serverModel.getRulesAction(queue_id, RuleId).then((ruleActionData) => {
      if (ruleActionData.status == true) {
         var ruleAction = ruleActionData.data;
         if (Object.keys(ruleAction).length > 0) {
            serverModel.callRuleAction(queue_id, TicketId, RuleId, ruleAction.action, ruleAction.action_value, acc_id).then((result) => {
               if (result.status == true) {
                  Log.incErrorLog("rule action performed");
               }
            });
         }
      }
   })
}

const assignUser = () => {
   return new Promise((resolve, reject) => {
      if (queueIds.data.length > 0) {
         for (let index = 0; index < queueIds.data.length; index++) {
            let resultKey = queueIds.data[index];
            serverModel.autoMailAssign(resultKey['id'], resultKey['auto_assign_setting']).then((result) => {
               if (result.status == true) {
                  Log.asgnErrorLog(` ${JSON.stringify(result.data)}`);
               } else {
                  Log.assign(`${result} ${queueIds.data[index]}`)
                  // console procedure error
               }
            })
         }
         resolve({ status: true })
      } else {
         const errorMessage = "queue id is required";
         Log.incErrorLog({ error: errorMessage });
         reject(new Error(errorMessage));
      }
   })
}

const escalationProcess = async function () {
   try {
      if (queueIds.data.length === 0) {
         const errorMessage = "Queue id is required";
         Log.escErrorLog({ error: errorMessage });
         throw new Error(errorMessage);
      }

      for (const resultKey of queueIds.data) {
         const queueId = resultKey['id'];

         if (queueData.hasOwnProperty(queueId) && queueData[queueId].data.escalation === 1) {
            const result = await serverModel.escalationProcess(queueId);

            if (result.status === true && Object.keys(result.data).length > 0) {
               for (const key of Object.keys(result.data)) {
                  let escData = result.data[key];
                  escData.last_updated_on = setDateFormat(escData.last_updated_on)
                  let outgoingData = outgoingMailData[queueId].data;
                  let dynamic_master_name = "tms_dynamicform_fields_" + escData.queue_id;
                  if (escData.send_email == 1) {
                     const uuid = generateUUID() + outgoingData.outgoing_mail_server + '>';
                     const msg_id = generateMsgId(uuid)
                     escData.ticket_link = `<a href="http://localhost:4200/ticket-search?backLink=ticket-search&queue_id=${escData.queue_id}&ticket_unique_id=${escData.ticket_unique_id}">${escData.status_name}</a>`
                     serverModel.setEmailSmsTemplate("user_mail", escData, '', '', '', dynamic_master_name).then((finalTemplate) => {
                        var emailSubject = finalTemplate.emailSubject
                        var emailBody = finalTemplate.emailBody
                        if (finalTemplate.status == true && finalTemplate.emailSubject != "" && emailBody != "") {
                           serverModel.updateTicketEscalation(escData.ticket_unique_id, escData.escalation_level, escData.queue_id).then((updateRes) => {
                              if (updateRes.status == true) {
                                 var conversationData = {
                                    'queue_id': escData.queue_id,
                                    'from_email': outgoingData.outgoing_user_name,
                                    'to_email': (escData.category_id == escData.ticket_category_id) ? escData.cat_email : escData.emails,
                                    // 'cc_email': escData.cc_email,
                                    'subject': emailSubject,
                                    'status_id': escData.status_id,
                                    'priority_id': escData.priority_id,
                                    'email_status': 'New',
                                    'uuid': uuid,
                                    'msg_id': msg_id,
                                    'conversation': emailBody,
                                    'account_id': outgoingData.id
                                 }
                                 serverModel.saveMailData("escalation matrix", conversationData, escData.ticket_id, escData.ticket_unique_id).then((result) => {
                                    if (result.status == true) {
                                       createMailJsonFile(conversationData);
                                    }
                                 });
                              }
                           })
                        } else {
                           Log.escErrorLog(`No User Email template found ${queueId}`);
                        }
                     })
                  }
                  if (escData.send_sms == 1) {
                     const uuid = generateUUID() + outgoingData.outgoing_mail_server + '>';
                     const msg_id = generateMsgId(uuid)
                     serverModel.setEmailSmsTemplate("user_sms", escData, '', '', '', dynamic_master_name).then((finalTemplate) => {
                        var smsBody = finalTemplate.smsBody
                        if (finalTemplate.status == true && finalTemplate.smsBody != "") {
                           serverModel.updateTicketEscalation(escData.ticket_unique_id, escData.escalation_level, escData.queue_id).then((updateRes) => {
                              if (updateRes.status == true) {
                                 let conversationData = {
                                    'queue_id': escData.queue_id,
                                    'from_email': outgoingData.outgoing_user_name,
                                    'to_email': escData.emails,
                                    // 'cc_email': escData.cc_email,
                                    'subject': emailSubject,
                                    'status_id': escData.status_id,
                                    'priority_id': escData.priority_id,
                                    'email_status': null,
                                    'sms_status': 'New',
                                    'uuid': uuid,
                                    'msg_id': msg_id,
                                    'conversation': smsBody,
                                    'account_id': outgoingData.id
                                 }
                                 serverModel.saveMailData("escalation matrix", conversationData, escData.ticket_id, escData.ticket_unique_id).then((result) => {
                                    if (result.status == true) {
                                       createMailJsonFile(conversationData);
                                    }
                                 });
                              }
                           })
                        } else {
                           Log.escErrorLog(`No User Sms template found ${queueId}`);
                        }
                     })
                  }
                  if (escData.send_email_agent == 1 && (escData.agent_email != '' || escData.agent_email != null)) {
                     const uuid = generateUUID() + outgoingData.outgoing_mail_server + '>';
                     const msg_id = generateMsgId(uuid)
                     serverModel.setEmailSmsTemplate("agent_escalation_mail", escData, '', '', '', dynamic_master_name).then((finalTemplate) => {
                        var emailSubject = finalTemplate.emailSubject
                        var emailBody = finalTemplate.emailBody
                        if (finalTemplate.status == true && finalTemplate.emailSubject != "" && emailBody != "") {
                           serverModel.updateTicketEscalation(escData.ticket_unique_id, escData.escalation_level, escData.queue_id).then((updateRes) => {
                              if (updateRes.status == true) {
                                 var conversationData = {
                                    'queue_id': escData.queue_id,
                                    'from_email': outgoingData.outgoing_user_name,
                                    'to_email': escData.agent_email,
                                    'subject': emailSubject,
                                    'status_id': escData.status_id,
                                    'priority_id': escData.priority_id,
                                    'email_status': 'New',
                                    'uuid': uuid,
                                    'msg_id': msg_id,
                                    'conversation': emailBody,
                                    'account_id': outgoingData.id
                                 }
                                 serverModel.saveMailData("escalation matrix", conversationData, escData.ticket_id, escData.ticket_unique_id).then((result) => {
                                    if (result.status == true) {
                                       createMailJsonFile(conversationData);
                                    }
                                 });
                              }
                           })
                        } else {
                           Log.escErrorLog(`No User Email template found ${queueId}`);
                        }
                     })
                  }
               }
            } else {
               Log.escErrorLog(`No Escalation Data found in queue ${queueId}`);
            }
         } else {
            const errorMessage = `Escalation Not enabled on queue Id ${queueId}`;
            Log.escErrorLog({ error: errorMessage });
         }
      }
   } catch (error) {
      Log.escErrorLog({ error: error });
      console.error(error);
   }
};

const processBulkEscalation = async function () {
   try {
      if (queueIds.data.length === 0) {
         const errorMessage = "Queue id is required";
         Log.escErrorLog({ error: errorMessage });
         throw new Error(errorMessage);
      }

      for (const resultKey of queueIds.data) {
         const queueId = resultKey['id'];
         if (queueData.hasOwnProperty(queueId) && queueData[queueId].data.escalation === 1 && queueData[queueId].data.bulk_escalation == 1 && queueData[queueId].data.bulk_escalation_template != null) {
            var bulkTemplate = '';
            var bulkTemplateSubject = ''
            serverModel.getBulkEscaltionTemplateData(queueData[queueId].data.bulk_escalation_template, queueId).then((bulkTemplateRes) => {
               if (bulkTemplateRes.status == true) {
                  var bulkTemplateData = bulkTemplateRes.data
                  bulkTemplate = bulkTemplateData[0].user_email_template
                  bulkTemplateSubject = bulkTemplateData[0].user_email_subject
               }
            })
            const result = await serverModel.escalationProcess(queueId);
            if (result.status === true && Object.keys(result.data).length > 0) {
               for (const key of Object.keys(result.data)) {
                  var escData = result.data[key];
                  escData.last_updated_on = setDateFormat(escData.last_updated_on)
                  var outgoingData = outgoingMailData[queueId].data;
                  const uuid = generateUUID() + outgoingData.outgoing_mail_server + '>';
                  const msg_id = generateMsgId(uuid)
                  var dynamic_master_name = "tms_dynamicform_fields_" + escData.queue_id;

                  escData.ticket_link = `<a href="http://localhost:4200/ticket-search?backLink=ticket-search&queue_id=${escData.queue_id}&ticket_unique_id=${escData.ticket_unique_id}">${escData.status_name}</a>`

               }
               serverModel.setEmailSmsTemplateBulkEscalation("user_mail", result.data, dynamic_master_name, bulkTemplate, bulkTemplateSubject).then((finalTemplate) => {
                  console.log("finalTemplate", finalTemplate)
                  var emailSubject = finalTemplate.emailSubject
                  var emailBody = finalTemplate.emailBody
                  // if (finalTemplate.status == true && emailSubject != "" && emailBody != "") {
                  //    const uniqueEmails = new Set(result.data.map(item => item.emails));
                  //    const uniqueEmailsArray = [...uniqueEmails];
                  //    const toEmails = uniqueEmailsArray.join(', ');
                  //    let insertData = {
                  //       email_status: 'New',
                  //       from_email: outgoingData.outgoing_user_name,
                  //       to_emails: toEmails,
                  //       subject: emailSubject,
                  //       conversation: emailBody
                  //    }
                  //    let masterName = `bulk_escalation_data_${queueId}`
                  //    serverModel.insertBulkTicketData(masterName, insertData).then((result) => {
                  //       if (result.status == true) {
                  //          var insertId = result.data
                  //          insertData.id = insertId
                  //          Log.escErrorLog(`Bulk Escalation Data inserted Successfully ${queueId}`);
                  //       }
                  //    })
                  //    sendBulkEscalationMail(insertData, outgoingData, queueId)
                  // } else {
                  //    Log.escErrorLog(`No Bulk Escalation template found ${queueId}`);
                  // }
               })
            } else {
               Log.escErrorLog(`No Bulk Escalation Data found in queue ${queueId}`);
            }
         } else {
            const errorMessage = `Bulk Escalation Not enabled on queue Id ${queueId}`;
            Log.escErrorLog({ error: errorMessage });
         }
      }
   } catch (error) {
      Log.escErrorLog({ error: error });
      console.error(error);
   }
}

async function sendBulkEscalationMail(insertData, outgoingData, queueId) {
   try {
      const result = await Mailer.SendBulkEmail(insertData, outgoingData, queueId);
      if (result && result.status === true) {
         Log.escErrorLog(`Bulk Escalation Mail Send Successfully id:- ${insertData.id}`);
      }
   } catch (error) {
      console.error('Error sending mails:', error);
   }
}


function createMailJsonFile(data, mailData = null, conversationId = null, ticket_id = null, ticket_unique_id = null) {
   if (Object.keys(data).length > 0) {
      const currentDate = new Date();
      const formattedDate = currentDate.toISOString();
      var conversation = data.conversation
      const jsonArray = {
         headerData: {
            'message-id': data.uuid,
            date: formattedDate,
            subject: data.subject
         },
         bodyData: '',
         attachmentData: []
      };

      const regex = /<img.*?src="data:image\/(.*?);base64,(.*?)".*?>/g;
      let match;
      let processedConversation = conversation;
      while ((match = regex.exec(conversation)) !== null) {
         jsonArray.attachmentData.push(match[2]);
         processedConversation = processedConversation.replace(match[0], '');
      }
      jsonArray.bodyData = Buffer.from(processedConversation).toString('base64');

      if (data.to_email) {
         jsonArray.headerData.to = {
            value: [{ address: data.to_email.trim() }]
         };
      }

      if (data.cc_email) {
         jsonArray.headerData.cc = {
            value: [{ address: data.cc_email.trim() }]
         };
      }

      if (data.from_email) {
         jsonArray.headerData.from = {
            value: [{ address: data.from_email.trim() }]
         };
      }
      if (data.attachmentArray && data.attachmentArray.length > 0) {
         data.attachmentArray.forEach(attachment => {
            jsonArray.attachmentData.push({
               filename: attachment.name,
               contentType: attachment.type
            });
         });
      }


      var mainfolderpath = path.join(__dirname, "mail_json_file");
      const folderName = data.msg_id;
      const today = new Date();

      const todayISOString = new Date(today.getTime() - (today.getTimezoneOffset() * 60000)).toISOString().slice(0, 10);


      const todayFolderPath = path.join(mainfolderpath, todayISOString);
      const folderPath = path.join(todayFolderPath, folderName);

      if (!fs.existsSync(todayFolderPath)) {
         fs.mkdirSync(todayFolderPath);
         fs.chmodSync(todayFolderPath, 0o777);
         Log.incErrorLog(`Folder created: ${todayFolderPath}`);
      } else {
         Log.incErrorLog(`Folder already exists: ${todayFolderPath}`);
      }

      if (!fs.existsSync(folderPath)) {
         fs.mkdirSync(folderPath);
         fs.chmodSync(folderPath, 0o777);
         Log.incErrorLog(`Folder created: ${folderPath}`);
      } else {
         Log.incErrorLog(`Folder already exists: ${folderPath}`);
      }


      var finalpath = path.join(folderPath, `${data.msg_id}.json`);

      try {
         var attachmentData = [];

         if (mailData && Array.isArray(mailData.attachmentData)) {
            for (const attachmentType of mailData.attachmentData) {
               attachmentData.push({
                  filename: attachmentType.filename,
                  contentType: attachmentType.contentType,
                  content: Buffer.from(attachmentType.attachmentContent, 'base64')
               });
            }
         } else {
            Log.incErrorLog('mailData or mailData.attachmentData is null or not an array createMailJsonFile function');
         }

         // for (const attachmentType of mailData.attachmentData) {
         //    attachmentData.push({
         //       filename: attachmentType.filename,
         //       contentType: attachmentType.contentType,
         //       content:Buffer.from(attachmentType.attachmentContent, 'base64')
         //    });
         // }

         // if (jsonArray.attachmentData.length > 0) {
         //    for (let i = 0; i < jsonArray.attachmentData.length; i++) {
         //       const attachment = jsonArray.attachmentData[i];
         //       const attachmentContent = Buffer.from(attachment, 'base64');
         //       attachmentData[i].content = attachmentContent;
         //    }

         for (let i = 0; i < attachmentData.length; i++) {
            var mainfolderpath = path.join(__dirname, "mail_json_file");
            const folderName = data.msg_id;
            const today = new Date();

            const todayISOString = new Date(today.getTime() - (today.getTimezoneOffset() * 60000)).toISOString().slice(0, 10);

            const todayFolderPath = path.join(mainfolderpath, todayISOString);
            const folderPath = path.join(todayFolderPath, folderName);

            try {
               if (!fs.existsSync(todayFolderPath)) {
                  fs.mkdirSync(todayFolderPath);
                  fs.chmodSync(todayFolderPath, 0o777);
                  Log.incErrorLog(`Folder created for attachment: ${todayFolderPath}`);
               }

               if (!fs.existsSync(folderPath)) {
                  fs.mkdirSync(folderPath);
                  fs.chmodSync(folderPath, 0o777);
                  Log.incErrorLog(`Folder created for attachment: ${folderPath}`);
               }

               const attachmentFilePath = path.join(folderPath, attachmentData[i].filename);
               attachmentData[i]['attachmentFilePath'] = `${todayISOString}/${folderName}/`

               fs.writeFile(attachmentFilePath, attachmentData[i].content, (err) => {
                  if (err) {
                     Log.incErrorLog(`Error saving attachment ${attachmentData[i].filename}: ${err}`);
                     //  return callback(err, null);
                  } else {
                     Log.incErrorLog(`Attachment ${attachmentData[i].filename} saved successfully.`);
                  }
               });
            } catch (err) {
               Log.incErrorLog(`Error creating folders or writing attachment: ${err}`);
               // return callback(err, null);
            }
         }
         // }
         var insertAttachmentData = [];
         if (attachmentData.length > 0) {
            jsonArray.attachmentData.splice(0, jsonArray.attachmentData.length);
            if (conversationId != null && ticket_id != null && ticket_unique_id != null) {
               for (let i = 0; i < attachmentData.length; i++) {
                  const attachment = attachmentData[i];
                  let filePath = attachment.attachmentFilePath;
                  let fileName = path.basename(filePath, '.json');
                  let finalUrl = path.join(path.dirname(filePath), fileName, attachment.filename);
                  insertAttachmentData.push({
                     'attachement_name': '"' + attachment.filename + '"',
                     'content_type': '"' + attachment.contentType + '"',
                     'ticket_id': '"' + ticket_id + '"',
                     'ticket_unique_id': '"' + ticket_unique_id + '"',
                     'conversation_id': '"' + conversationId + '"',
                     'attachement_filepath': '"' + finalUrl + '"'
                  });

                  jsonArray.attachmentData.push({
                     "filename": attachment.filename,
                     "contentType": attachment.contentType
                  });
               }
            }
         }
         if (insertAttachmentData.length > 0) {
            serverModel.insertAttachmentData(insertAttachmentData, data.queue_id).then((result) => {
               if (result.status == 'success') {

               }
            })

         }
         const json = JSON.stringify(jsonArray, null, 2);
         fs.writeFileSync(finalpath, json);
         fs.chmodSync(finalpath, 0o777);
         return true;
      } catch (error) {
         Log.incErrorLog({ error: error });
         return false;
      }
   } else {
      return false;
   }
}



// let isProcessing = false;
// const sendMail = function () {
//    // if (isProcessing) {
//    //     console.log("Previous data processing is not completed yet");
//    //     return;
//    // }

//    // isProcessing = true;
//    return new Promise((resolve, reject) => {
//       if (queueIds.data.length > 0) {
//          let QueueId = [];
//          for (let index = 0; index < queueIds.data.length; index++) {
//             let resultKey = queueIds.data[index];
//             QueueId.push(resultKey['id']);
//          }
//          if (QueueId.length > 0) {
//             let dataArray = [];
//             for (let index = 0; index < QueueId.length; index++) {
//                let result_queue_id = QueueId[index];
//                serverModel.getNewEmailStatusData(result_queue_id).then((ticketRes) => {
//                   if (ticketRes.status == true) {
//                      if (ticketRes.data.length > 0) {
//                         Array.prototype.push.apply(dataArray, ticketRes.data);
//                         // processMailData(dataArray, () => {
//                         //     isProcessing = false;
//                         // })
//                         processMailData(dataArray)
//                      } else {
//                         Log.outErrorLog(`No mail data found in queue id ${result_queue_id}.`)
//                         // console.log('No mail data found.');
//                      }
//                   }
//                   // else {
//                   //     Log.outErrorLog({ msg: 'No mail data found.' })
//                   //     // console.log('No mail data found.');
//                   // }
//                });
//             }
//          }
//          resolve({ status: true })
//       } else {
//          const errorMessage = "queue id is required";
//          Log.incErrorLog({ error: errorMessage });
//          reject(new Error(errorMessage));
//       }
//    })
// }

const sendMail = async function () {
   try {
      if (queueIds.data.length === 0) {
         const errorMessage = "queue id is required";
         Log.incErrorLog({ error: errorMessage });
         throw new Error(errorMessage);
      }

      let QueueId = queueIds.data.map(resultKey => resultKey['id']);
      if (QueueId.length === 0) return { status: true };

      let dataArray = [];
      for (const result_queue_id of QueueId) {
         try {
            const ticketRes = await serverModel.getNewEmailStatusData(result_queue_id);
            if (ticketRes.status && ticketRes.data.length > 0) {
               dataArray.push(...ticketRes.data);
            } else {
               Log.outErrorLog(`No mail data found in queue id ${result_queue_id}.`);
            }
         } catch (error) {
            console.error(`Error retrieving mail data for queue id ${result_queue_id}:`, error);
         }
      }

      if (dataArray.length > 0) {
         await processMailData(dataArray);
      }

      return { status: true };
   } catch (error) {
      console.error('Error in sendMail function:', error);
      throw error;
   }
};

const sendNotification = function () {
   return new Promise((resolve, reject) => {
      resolve({ status: true });
   });
}

// var processMailData =  function (data) {
const processMailData = async (data) => {
   if (data.length > 0) {
      const accumulatedData = [];
      for (let index = 0; index < data.length; index++) {
         let res = data[index];
         let jsonFileName = res.json_file_name;
         if (jsonFileName != null) {
            // get conversation and attachment from the json file start here
            const jsonFolderName = 'mail_json_file/' + res.folderdate + '/' + jsonFileName.replace('.json', '')
            const filePath = path.join(__dirname, jsonFolderName, jsonFileName);

            if (fs.existsSync(filePath)) {
               const fileData = fs.readFileSync(filePath, 'utf8');
               let jsonData = JSON.parse(fileData);
               let encodedData = jsonData.bodyData
               const bodyData = Buffer.from(encodedData, 'base64').toString('utf-8');
               if (!res.conversation) {
                  res.conversation = '';
               }
               if (bodyData) {
                  res.conversation = bodyData;
               }
               let attachmentData = jsonData.attachmentData;
               const attachmentPath = path.join(__dirname, 'mail_json_file', res.folderdate, jsonFileName.replace('.json', ''));
               if (fs.existsSync(attachmentPath)) {
                  if (attachmentData && attachmentData.length > 0) {
                     let attachmentArray = attachmentData.map(attachment => ({
                        file_name: attachment.filename,
                        file_url: path.join(attachmentPath, attachment.filename)
                     }));
                     res.attachmentArray = attachmentArray;
                  }
               }
            } else {
               Log.errorLog(`File does not exist: ${filePath}`);
               console.log('File does not exist:', filePath);
            }
            var resData = { ...res };
            accumulatedData.push(resData);
         }
      }
      if (accumulatedData.length > 0) {
         return Mailer.sendAutoReply(accumulatedData)
            .then((result) => {
               if (result && result.status === true) {
               } else {
               }
            })
            .catch((error) => {
               console.error('Error sending mails:', error);
            });
      } else {
         Log.outErrorLog(`No valid json_file_name found in the data.`);
         return Promise.resolve(); // Return a resolved Promise if no valid data
      }
   }
}
// callback();
var generateSeries = function (ticketSeries, ticketNo) {
   var res = '';
   res = ticketSeries.replace('[M]', new Date().toLocaleString('default', { month: 'short' }).toUpperCase());
   res = res.replace('[m]', (new Date().getMonth() + 1).toString().padStart(2, '0'));
   res = res.replace('[d]', new Date().getDate().toString().padStart(2, '0'));
   res = res.replace('[D]', new Date().toLocaleString('default', { weekday: 'short' }));
   res = res.replace('[Y]', new Date().getFullYear().toString());
   res = res.replace('[y]', new Date().getFullYear().toString().substr(-2));
   res = res.replace('[Y+1]', (new Date().getFullYear() + 1).toString());
   res = res.replace('[y+1]', (new Date().getFullYear() + 1).toString().substr(-2));
   var finalTicketSeries = res + ticketNo;
   if (finalTicketSeries.length > 20) {
      res = '0';
      ticketNo = '0';
      Log.errorLog("Ticket Prefix should not be greter than 20 characters");
      console.log(err, "Ticket Prefix should not be greter than 20 characters")
      return { status: false, err: "Ticket Prefix should not be greter than 20 characters" }
   } else {
      return { status: true, data: finalTicketSeries }
   }
}

function generateUUID() {
   const uuid = crypto
      .createHash('md5')
      .update(crypto.randomBytes(16))
      .digest('hex');

   return `<${uuid.substr(0, 8)}-${uuid.substr(8, 4)}-${uuid.substr(12, 4)}-${uuid.substr(16, 4)}-${uuid.substr(20)}@`;
}

function generateMsgId(uuid) {
   var charmessageId = uuid.replace(/[<>\-.]/g, '');
   var msgId = charmessageId.split('@')[0]
   return msgId;
}

const updateVariable = async () => {
   try {
      await exports.handleQueueOperations();
      return { status: true };
   } catch (error) {
      return { status: false };
   }
}

const sendSMS = function () {
   return new Promise((resolve, reject) => {
      if (queueIds.data.length > 0) {
         let QueueId = [];
         for (let index = 0; index < queueIds.data.length; index++) {
            let resultKey = queueIds.data[index];
            QueueId.push(resultKey['id']);
         }
         if (QueueId.length > 0) {
            let dataArray = [];
            for (let index = 0; index < QueueId.length; index++) {
               let result_queue_id = QueueId[index];
               serverModel.getNewSMSStatusData(result_queue_id).then((ticketRes) => {
                  if (ticketRes.status == true) {
                     if (ticketRes.data.length > 0) {
                        Array.prototype.push.apply(dataArray, ticketRes.data);
                        processSMSData(dataArray)
                     } else {
                        Log.smsErrorLog(`No SMS data found in queue id ${result_queue_id}.`)
                     }
                  }
               });
            }
         }
         resolve({ status: true })
      } else {
         const errorMessage = "queue id is required";
         Log.smsErrorLog({ error: errorMessage });
         reject(new Error(errorMessage));
      }
   })
}

var processSMSData = function (data) {
   if (data.length > 0) {
      for (let index = 0; index < data.length; index++) {
         let res = data[index];
         let jsonFileName = res.json_file_name;
         if (jsonFileName != null) {
            // get conversation and attachment from the json file start here
            const jsonFolderName = 'mail_json_file/' + res.folderdate + '/' + jsonFileName.replace('.json', '')
            const filePath = path.join(__dirname, jsonFolderName, jsonFileName);

            if (fs.existsSync(filePath)) {
               const fileData = fs.readFileSync(filePath, 'utf8');
               let jsonData = JSON.parse(fileData);
               let encodedData = jsonData.bodyData
               const bodyData = Buffer.from(encodedData, 'base64').toString('utf-8');

               if (!res.conversation) {
                  res.conversation = '';
               }
               if (bodyData) {
                  res.conversation = bodyData;
               }
            } else {
               Log.errorLog(`File does not exist: ${filePath}`);
               console.log('File does not exist:', filePath);
            }
            Smsprocess.sendAutoReply(res).then((result) => {
               if (result.status == true) {
                  Log.smsErrorLog({ msg: `SMS send successfully to ${res.to_email}` })
                  // console.log("mail send successfully to " + res.to_email)
               }
            });
         }
      }
   }
}

const sendWhatsapp = function () {
   return new Promise((resolve, reject) => {
      if (queueIds.data.length > 0) {
         let QueueId = [];
         for (let index = 0; index < queueIds.data.length; index++) {
            let resultKey = queueIds.data[index];
            QueueId.push(resultKey['id']);
         }
         if (QueueId.length > 0) {
            let dataArray = [];
            for (let index = 0; index < QueueId.length; index++) {
               let result_queue_id = QueueId[index];
               serverModel.getNewWhatsappStatusData(result_queue_id).then((ticketRes) => {
                  if (ticketRes.status == true) {
                     if (ticketRes.data.length > 0) {
                        Array.prototype.push.apply(dataArray, ticketRes.data);
                        processWhatsappData(dataArray)
                     } else {
                        Log.whatsappErrorLog(`No Whatsapp data found in queue id ${result_queue_id}.`)
                     }
                  }
               });
            }
         }
         resolve({ status: true })
      } else {
         const errorMessage = "queue id is required";
         Log.whatsappErrorLog({ error: errorMessage });
         reject(new Error(errorMessage));
      }
   })
}

var processWhatsappData = function (data) {
   if (data.length > 0) {
      for (let index = 0; index < data.length; index++) {
         let res = data[index];
         let jsonFileName = res.json_file_name;
         if (jsonFileName != null) {
            const jsonFolderName = 'mail_json_file/' + res.folderdate + '/' + jsonFileName.replace('.json', '')
            const filePath = path.join(__dirname, jsonFolderName, jsonFileName);

            if (fs.existsSync(filePath)) {
               const fileData = fs.readFileSync(filePath, 'utf8');
               let jsonData = JSON.parse(fileData);
               let encodedData = jsonData.bodyData
               const bodyData = Buffer.from(encodedData, 'base64').toString('utf-8');

               if (!res.conversation) {
                  res.conversation = '';
               }
               if (bodyData) {
                  res.conversation = bodyData;
               }
            } else {
               Log.errorLog(`File does not exist: ${filePath}`);
               console.log('File does not exist:', filePath);
            }
            Whatsapp.sendAutoReply(res).then((result) => {
               if (result.status == true) {
                  Log.whatsappErrorLog({ msg: `Whatsapp send successfully to ${res.to_email}` })
               }
            });
         }
      }
   }
}

function setDateFormat(dateVal) {
   let value = new Date(dateVal)
   let localTime = new Date(value.getTime() + (330 * 60 * 1000));
   return localTime.toISOString().slice(0, 19).replace('T', ' ');
}

exports.handlerTokenCompanyObj = async () => {
   try {
      await exports.handleQueueOperations();
      return { status: true };
   } catch (error) {
      return { status: false };
   }
};



exports.handlerReadMail = (req, res) => {
   readMail().then(function (result) {
      Resp.sendResponse(res, true, "readMail API called", null, 200);
   }).catch((err) => {
      console.log("readMail error:", err)
   })
}

exports.handlerAssignUser = (req, res) => {
   assignUser().then(function (result) {
      Resp.sendResponse(res, true, "assignUser API called", null, 200);
   }).catch((err) => {
      console.log("assignUser error:", err)
   })
}

exports.handlerEscalationProcess = (req, res) => {
   escalationProcess().then(function (result) {
      Resp.sendResponse(res, true, "escalationProcess API called", null, 200);
   }).catch((err) => {
      console.log("escalationProcess error:", err)
   })
}

exports.handlerSendMail = (req, res) => {
   sendMail().then(function (result) {
      Resp.sendResponse(res, true, "sendMail API called", null, 200);
   }).catch((err) => {
      console.log("sendResponse error:", err)
   })
}

exports.handlerUpdateVariable = (req, res) => {
   updateVariable().then(function (result) {
      Resp.sendResponse(res, true, "updateVariable API called", null, 200);
   }).catch((err) => {
      console.log("updateVariable error:", err);
   })
}

exports.handlerSendNotification = (req, res) => {
   sendNotification().then(function (result) {
      Resp.sendResponse(res, true, "sendNotification API called", result, 200);
   }).catch((err) => {
      console.log("sendNotification error:", err);
   })
}

exports.handlerSendSMS = (req, res) => {
   sendSMS().then(function (result) {
      Resp.sendResponse(res, true, "sendSMS API called", null, 200);
   }).catch((err) => {
      console.log("sendResponse error:", err)
   })
}

exports.handlerSendWhatsapp = (req, res) => {
   sendWhatsapp().then(function (result) {
      Resp.sendResponse(res, true, "sendWhatsapp API called", null, 200);
   }).catch((err) => {
      console.log("sendResponse error:", err)
   })
}

exports.handlerBulkEscalation = (req, res) => {
   processBulkEscalation().then(function (result) {
      Resp.sendResponse(res, true, "processBulkEscalation API called", null, 200);
   }).catch((err) => {
      console.log("sendResponse error:", err)
   })
}

const updateSmsApiHeaders = async () => {
   try {
      const tokenResponse = await Smsprocess.callOtherApiForToken();
      const token = tokenResponse.token;
      if (tokenResponse.status === true && tokenResponse.token) {
         const tokenStore = { Authorization: `Bearer ${token}` };
         const tokenStoreString = JSON.stringify(tokenStore);
         const updateResponse = await serverModel.updateSmsApiHeaders(tokenStoreString);
         if (updateResponse.status === true) {
            console.log("SMS API headers updated successfully.");
            await updateVariable();
         } else {
            console.log("Failed to update SMS API headers:", updateResponse);
         }
      } else {
         console.log("Failed to fetch token from external API:", tokenResponse);
      }
   } catch (error) {
      console.error("Error in updateSmsApiHeaders:", error);
   }
};

exports.handleUpdateSmsApiHeaders = async (req, res) => {
   try {
      await updateSmsApiHeaders();
      Resp.sendResponse(res, true, "SMS API headers updated successfully", null, 200);
   } catch (error) {
      console.error("Error in handleUpdateSmsApiHeaders:", error);
      Resp.sendResponse(res, false, "Failed to update SMS API headers", null, 500
      );
   }
};


setInterval(readMail, 30000);
setInterval(assignUser, 60000);
setInterval(sendMail, 70000);
// setInterval(escalationProcess, 10000);
// setInterval(sendSMS, 90000);
// setInterval(sendWhatsapp, 60000);
// setInterval(updateSmsApiHeaders, 2.5 * 60 * 60 * 1000); // Call every 2.5 hours



