const Log = require('./log');
const Info = require('./info');
const db = require('../dbconn');
var Mailer = function (obj) { };
const nodemailer = require('nodemailer');
const { convert } = require('xmlbuilder2');
const connectionPools = {};

function getTransporter(outgoing_user_name, outgoing_password,mail_server) {
    if (!connectionPools[outgoing_user_name]) {
        // Create a new transporter if it doesn't exist
        connectionPools[outgoing_user_name] = nodemailer.createTransport({
            // service: 'gmail',
            host: mail_server,
            auth: {
                user: outgoing_user_name,
                pass: outgoing_password
            },
            tls: {
                rejectUnauthorized: false 
            }
        });
    }
    return connectionPools[outgoing_user_name];
}

Mailer.sendAutoReply = function (data) {
    if (!data || data.length === 0) {
        Log.outErrorLog('No data provided for sending auto-reply.');
        return Promise.resolve({ status: false, message: 'No data provided for sending auto-reply.' });
    }

    const emailPromises = [];
    for (let i = 0; i < data.length; i++) {
        const currentData = data[i];

        if (!currentData.to_email) {
            updateNoOfTry(currentData.conversation_id,currentData.no_of_try,currentData.queue_id)
            Log.outErrorLog(`Invalid Mail Data: Missing to_email. ${JSON.stringify(currentData)}`);
            continue;
        }

        Log.outErrorLog({ msg: `sending mail process on ${currentData.from_email} start here from mail id is ${currentData.outgoing_user_name} to mail id is ${currentData.to_email} and conversation id ${currentData.conversation_id}` });

        if (currentData.server_type === "" || currentData.server_type == null) {
            updateNoOfTry(currentData.conversation_id,currentData.no_of_try,currentData.queue_id)
            Log.outErrorLog(`Invalid Mail Data: server_type is required. conversation id is  ${currentData.conversation_id}`);
            continue;
        }

        if (currentData.server_type == "Pop3" || currentData.server_type == "IMap") {
            if (currentData.outgoing_user_name != "" && currentData.outgoing_password != "" && currentData.outgoing_mail_server != "" && currentData.outgoing_mail_server_port != "" && currentData.stop_outgoing_email == 0) {
                const transporter = getTransporter(currentData.outgoing_user_name, currentData.outgoing_password,currentData.outgoing_mail_server);
                const mailOptions = {
                    from: currentData.outgoing_user_name,
                    to: currentData.to_email,
                    cc: currentData.cc_email,
                    bcc: currentData.bcc_email,
                    subject: currentData.subject,
                    html: currentData.conversation,
                    headers: {
                        'Message-ID': currentData.email_message_id
                    },
                };

                if (currentData.refrence_id && currentData.refrence_id !== "") {
                    mailOptions.headers['References'] = [currentData.refrence_id];
                }

                if (currentData.attachmentArray && currentData.attachmentArray.length > 0) {
                    mailOptions.attachments = mailOptions.attachments || [];
                    mailOptions.attachments = mailOptions.attachments.concat(
                        currentData.attachmentArray.map(attachment => ({
                            filename: attachment.file_name,
                            path: attachment.file_url
                        }))
                    );
                }

                if (currentData.footer_name != "" && (currentData.footer_url != null || currentData.footer_url != "")) {
                    mailOptions.attachments = mailOptions.attachments || [];
                    mailOptions.attachments.push({
                        filename: currentData.footer_name,
                        path: `/var/www/html/tms_v2.0/api/uploads/queuefooter/queuefooter_${currentData.queue_id}/${currentData.footer_name}`,
                        cid: 'footer'
                    });
                }

                // --------block email for autoreply validation start here---------------
                if (currentData.conversation_type !== "reply" && currentData.conversation_type !== "forward" && currentData.conversation_type !== "escalation matrix") {
                    Log.outErrorLog(`"block_email_for_auto_reply",${currentData.block_email_for_auto_reply}`);
                    if (currentData.block_email_for_auto_reply != "") {
                        const blockEmailIds = currentData.block_email_for_auto_reply.split(',');
                        Log.outErrorLog(`"blockEmailIds",${blockEmailIds}`);
                        const matchedEmails = [];
                        const shouldSendEmail = !blockEmailIds.some(email => {
                            const emailFields = ['to'];
                            const matched = emailFields.some(field => mailOptions[field] && mailOptions[field].includes(email));
                            if (matched) {
                                matchedEmails.push(email);
                            }
                            return matched;
                        });
                        Log.outErrorLog(`${shouldSendEmail}`);
                        if (!shouldSendEmail) {
                            emailPromises.push(new Promise((resolve, reject) => {
                                let updArr = {
                                    'email_status': 'None'
                                };
                                let whArr = {
                                    'conversation_id': currentData.conversation_id
                                };
                                let mstTblName = `tms_conversation_master_${currentData.queue_id}`;
                                db.updateData(`${mstTblName}`, updArr, whArr)
                                    .then(function (response) {
                                        Log.outErrorLog({ msg: `${JSON.stringify(response)}` });
                                        if (response.status == true) {
                                            resolve({ status: true });
                                        } else {
                                            Log.outErrorLog({ error: response.err });
                                            reject({ status: false, data: null, err: response.err });
                                        }
                                    })
                                    .catch(function (error) {
                                        Log.outErrorLog({ error: error });
                                        reject({ status: false, data: null, err: error });
                                    });
                                Log.outErrorLog(`Email blocked due to block_email_for_auto_reply value ${matchedEmails.join(', ')}`);
                                resolve({ status: false, data: null, message: `Email blocked due to block_email_for_auto_reply value ${matchedEmails.join(', ')}` });
                            }));
                            continue;
                        }
                    }

                    // -----------block domain for autoreply validation start here--------------
                    if (currentData.block_domains_for_auto_reply != "") {
                        const blockDomains = currentData.block_domains_for_auto_reply.split(',');
                        Log.outErrorLog(`${blockDomains}`);
                        const matchedDomains = [];
                        const shouldSendBlockedDomainEmail = !blockDomains.some(domain => {
                            if (mailOptions.to && mailOptions.to.includes(domain)) {
                                matchedDomains.push(domain);
                                return true;
                            }
                            return false;
                        });

                        if (!shouldSendBlockedDomainEmail) {
                            emailPromises.push(new Promise((resolve, reject) => {
                                let updArr = {
                                    'email_status': 'None'
                                };
                                let whArr = {
                                    'conversation_id': currentData.conversation_id
                                };
                                let mstTblName = `tms_conversation_master_${currentData.queue_id}`;
                                db.updateData(`${mstTblName}`, updArr, whArr)
                                    .then(function (response) {
                                        Log.outErrorLog({ msg: `${JSON.stringify(response)}` });
                                        if (response.status == true) {
                                            resolve({ status: true });
                                        } else {
                                            Log.outErrorLog({ error: response.err });
                                            reject({ status: false, data: null, err: response.err });
                                        }
                                    })
                                    .catch(function (error) {
                                        Log.outErrorLog({ error: error });
                                        reject({ status: false, data: null, err: error });
                                    });
                                Log.outErrorLog(`Email blocked due to block_domains_for_ticket_generate value ${matchedDomains.join(', ')}`);
                                resolve({ status: false, data: null, message: `Email blocked due to block_domains_for_ticket_generate value ${matchedDomains.join(', ')}` });
                            }));
                            continue;
                        }
                    }
                }

                const emailPromise = transporter.sendMail(mailOptions)
                    .then((info) => {
                        Log.outErrorLog(`Email sent to ${currentData.to_email}: ${info.response}`);

                        let updArr = {
                            'email_status': 'Send'
                        };
                        let whArr = {
                            'conversation_id': currentData.conversation_id
                        };
                        let mstTblName = `tms_conversation_master_${currentData.queue_id}`;
                        return db.updateData(`${mstTblName}`, updArr, whArr)
                            .then(function (response) {
                                Log.outErrorLog({ msg: `${JSON.stringify(response)}` });
                                if (response.status == true) {
                                    return { status: true };
                                } else {
                                    Log.outErrorLog({ error: response.err });
                                    return { status: false, data: null, err: response.err };
                                }
                            })
                            .catch(function (error) {
                                Log.outErrorLog({ error: error });
                                return { status: false, data: null, err: error };
                            });
                    })
                    .catch((error) => {
                        updateNoOfTry(currentData.conversation_id,currentData.no_of_try,currentData.queue_id)
                        Log.outErrorLog(`Error sending email to ${currentData.to_email}: ${error.message}`);
                        return { status: false, message: `Error sending email to ${currentData.to_email}.` };
                    });

                emailPromises.push(emailPromise);
            } else {
                updateNoOfTry(currentData.conversation_id,currentData.no_of_try,currentData.queue_id)
                Log.outErrorLog({ msg: "Outgoing server details are required" });
                continue;
            }
        } else {
            updateNoOfTry(currentData.conversation_id,currentData.no_of_try,currentData.queue_id)
            Log.outErrorLog({ msg: "Exchange Not implemented" });
            continue;
        }
    }
    return Promise.all(emailPromises)
        .then((results) => {
            const allEmailsSent = results.every(result => result.status === true);
            if (allEmailsSent) {
                return { status: true, message: 'All emails sent successfully.' };
            } else {
                return { status: false, message: 'Error sending one or more emails.' };
            }
        })
        .finally(() => {
            Object.values(connectionPools).forEach(pool => pool.close());
        });
}

function updateNoOfTry(conversation_id,no_of_try,queueId){
    
    let noOfTry = parseInt((no_of_try == null) ? 0 : no_of_try) + 1;
    let updStrArr = {
        'no_of_try' : noOfTry
    }
    let whArr = {
        'conversation_id': conversation_id
    };
    let mstTblName = `tms_conversation_master_${queueId}`;
    return db.updateData(`${mstTblName}`, updStrArr, whArr)
    .then(function (response) {
        Log.outErrorLog({ msg: `${JSON.stringify(response)}` });
        if (response.status == true) {
            return { status: true };
        } else {
            Log.outErrorLog({ error: response.err });
            return { status: false, data: null, err: response.err };
        }
    })
    .catch(function (error) {
        Log.outErrorLog({ error: error });
        return { status: false, data: null, err: error };
    });

}

Mailer.SendBulkEmail = async function (data, outgoingData, queueId) {
    const transporter = getTransporter(outgoingData.outgoing_user_name, outgoingData.outgoing_password);
    const mailOptions = {
        from: data.from_email,
        to: data.to_emails,
        subject: data.subject,
        html: data.conversation,
    };
    
    const emailPromises = [];
    const emailPromise = transporter.sendMail(mailOptions)
        .then((info) => {
            Log.outErrorLog(`Email sent to ${data.to_email}: ${info.response}`);

            let updArr = {
                'email_status': 'Send'
            };
            let whArr = {
                'id': data.id
            };
            let mstTblName = `bulk_escalation_data_${queueId}`;
            db.updateData(`${mstTblName}`, updArr, whArr)
                .then(function (response) {
                    Log.outErrorLog({ msg: `${JSON.stringify(response)}` });
                    if (response.status == true) {
                        return { status: true };
                    } else {
                        Log.outErrorLog({ error: response.err });
                        return { status: false, data: null, err: response.err };
                    }
                })
                .catch(function (error) {
                    Log.outErrorLog({ error: error });
                    return { status: false, data: null, err: error };
                });
            return { status: true, message: `Email sent to ${data.to_emails} successfully.` };
        })
        .catch((error) => {
            Log.outErrorLog(`Error sending email to ${data.to_emails}: ${error.message}`);
            return { status: false, message: `Error sending email to ${data.to_emails}.` };
        });
    emailPromises.push(emailPromise);
    const results = await Promise.all(emailPromises);
    const allEmailsSent = results.every(result => result.status === true);
    if (allEmailsSent) {
        return { status: true, message: 'All emails sent successfully.' };
    } else {
        return { status: false, message: 'Error sending one or more emails.' };
    }
}

module.exports = Mailer;