const tools = require('./tools/general');
const telegrambot = require('./telegram/telegrambot');

require('./config/config');

const Email = require('email-templates');

const { decode } = require('entities');

const i18n = require('i18n');

const { ObjectId } = require('mongodb');
const { Settings } = require('./models/settings');
const { TemplEmail } = require('./models/templemail');
const { DestNewsletter } = require('./models/destnewsletter');
const { Discipline } = require('./models/discipline');

const previewEmail = require('preview-email');
const nodemailer = require('nodemailer');

const OrdersCart = require('./models/orderscart');

const { MyEvent } = require('./models/myevent');
const { MailingList } = require('./models/mailinglist');
const { Newstosent } = require('./models/newstosent');

const server_constants = require('./tools/server_constants');

const shared_consts = require('./tools/shared_nodejs');

const { User } = require('./models/user');

const { MsgTemplate } = require('./models/msg_template');

const transport_preview = nodemailer.createTransport({
  jsonTransport: true,
});

// ==========================================
// TEMPLATE EMAIL HTML
// ==========================================
const generaTemplateEmailInvito = () => {
  const { to, usernameInvitante, linkRegistrazione, nomeApp, baseUrl } = params;

  // Template HTML basato sul file pug fornito
  return `
<!DOCTYPE html>
<html lang="it">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    
    body {
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
      background-color: #f5f5f5;
      padding: 20px;
      line-height: 1.6;
    }
    
    .header-logo {
      width: 80px;
      height: auto;
      margin-bottom: 16px;
      display: block;
      margin-left: auto;
      margin-right: auto;
    }
    
    .email-container {
      max-width: 600px;
      margin: 0 auto;
      background: white;
      border-radius: 12px;
      box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
      overflow: hidden;
    }
    
    .email-header {
      background: linear-gradient(135deg, #027be3 0%, #0056b3 100%);
      color: white;
      padding: 40px 24px;
      text-align: center;
    }
    
    .email-header h1 {
      margin: 0 0 8px 0;
      font-size: 28px;
      font-weight: 600;
    }
    
    .email-header p {
      margin: 0;
      font-size: 16px;
      opacity: 0.95;
    }
    
    .welcome-icon {
      font-size: 48px;
      margin-bottom: 16px;
    }
    
    .email-body {
      padding: 32px 24px;
    }
    
    .intro-text {
      font-size: 16px;
      color: #333;
      margin-bottom: 24px;
      text-align: center;
      line-height: 1.7;
    }
    
    .highlight-box {
      background: #f0f8ff;
      border-left: 4px solid #027be3;
      border-radius: 8px;
      padding: 20px;
      margin: 24px 0;
    }
    
    .highlight-box p {
      margin: 0;
      font-size: 15px;
      color: #1a1a1a;
      line-height: 1.6;
    }
    
    .cta-section {
      text-align: center;
      margin: 32px 0;
      padding: 24px 0;
      border-top: 1px solid #e0e0e0;
      border-bottom: 1px solid #e0e0e0;
    }
    
    .cta-title {
      font-size: 18px;
      font-weight: 600;
      color: #1a1a1a;
      margin-bottom: 20px;
    }
    
    .cta-button {
      display: inline-block;
      padding: 16px 48px;
      font-size: 18px;
      font-weight: 600;
      color: white;
      background: linear-gradient(135deg, #027be3 0%, #0056b3 100%);
      border-radius: 50px;
      text-decoration: none;
      box-shadow: 0 4px 12px rgba(2, 123, 227, 0.3);
      transition: transform 0.2s, box-shadow 0.2s;
    }
    
    .cta-button:hover {
      transform: translateY(-2px);
      box-shadow: 0 6px 16px rgba(2, 123, 227, 0.4);
    }
    
    .alternative-link {
      margin-top: 20px;
      font-size: 13px;
      color: #777;
    }
    
    .alternative-link a {
      color: #027be3;
      text-decoration: none;
      word-break: break-all;
    }
    
    .info-box {
      background: #e8f5e9;
      border-radius: 8px;
      padding: 16px;
      margin-top: 24px;
      text-align: center;
    }
    
    .info-box p {
      margin: 0;
      color: #2e7d32;
      font-size: 14px;
      line-height: 1.6;
    }
    
    .benefits-list {
      background: #f8f9fa;
      border-radius: 8px;
      padding: 20px;
      margin: 24px 0;
    }
    
    .benefits-list h3 {
      font-size: 16px;
      color: #1a1a1a;
      margin-bottom: 16px;
      text-align: center;
    }
    
    .benefit-item {
      display: flex;
      align-items: flex-start;
      margin-bottom: 12px;
      padding: 8px 0;
    }
    
    .benefit-icon {
      font-size: 20px;
      margin-right: 12px;
      min-width: 24px;
    }
    
    .benefit-text {
      font-size: 14px;
      color: #555;
      line-height: 1.5;
    }
    
    .email-footer {
      padding: 24px 20px;
      text-align: center;
      background: #f8f9fa;
      color: #777;
      font-size: 13px;
    }
    
    .email-footer p {
      margin: 4px 0;
    }
    
    .divider {
      height: 1px;
      background: linear-gradient(to right, transparent, #e0e0e0, transparent);
      margin: 24px 0;
    }
    
    @media only screen and (max-width: 600px) {
      body {
        padding: 10px;
      }
      
      .email-header {
        padding: 24px 16px;
      }
      
      .email-header h1 {
        font-size: 24px;
      }
      
      .email-body {
        padding: 24px 16px;
      }
      
      .cta-button {
        padding: 14px 32px;
        font-size: 16px;
        width: 100%;
        max-width: 300px;
      }
    }
  </style>
</head>
<body>
  <div class="email-container">
    <!-- Header -->
    <div class="email-header">
      <img class="header-logo" src="${baseUrl}/images/logo.png" alt="${nomeApp} Logo">
      <div class="welcome-icon">🎉</div>
      <h1>Sei stato invitato!</h1>
      <p>${usernameInvitante ? `${usernameInvitante} ti invita a provare` : 'Unisciti a'} ${nomeApp}</p>
    </div>

    <!-- Body -->
    <div class="email-body">
      <div class="intro-text">
        ${
          usernameInvitante
            ? `<strong>${usernameInvitante}</strong> pensa che ${nomeApp} possa esserti utile e ti ha invitato a unirti alla piattaforma!`
            : `Hai ricevuto un invito speciale per unirti a ${nomeApp}!`
        }
      </div>

      ${
        usernameInvitante
          ? `
      <div class="highlight-box">
        <p>
          💌 <strong>Messaggio da ${usernameInvitante}:</strong><br>
          "Ti consiglio di provare questa app, sono sicuro che ti sarà utile!"
        </p>
      </div>
      `
          : ''
      }

      <!-- Benefici -->
      <div class="benefits-list">
        <h3>✨ Cosa puoi fare con ${nomeApp}</h3>
        <div class="benefit-item">
          <span class="benefit-icon">🚀</span>
          <span class="benefit-text">Accedi a funzionalità esclusive per migliorare la tua esperienza</span>
        </div>
        <div class="benefit-item">
          <span class="benefit-icon">🤝</span>
          <span class="benefit-text">Connettiti con una community di utenti appassionati</span>
        </div>
        <div class="benefit-item">
          <span class="benefit-icon">🎯</span>
          <span class="benefit-text">Raggiungi i tuoi obiettivi con strumenti professionali</span>
        </div>
        <div class="benefit-item">
          <span class="benefit-icon">📱</span>
          <span class="benefit-text">Utilizza l'app ovunque tu sia, anche offline</span>
        </div>
      </div>

      <!-- CTA -->
      <div class="cta-section">
        <div class="cta-title">🎁 Inizia subito gratuitamente</div>
        <a class="cta-button" href="${linkRegistrazione}" target="_blank">
          Registrati Ora
        </a>
        <div class="alternative-link">
          Oppure copia e incolla questo link nel tuo browser:<br>
          <a href="${linkRegistrazione}" target="_blank">${linkRegistrazione}</a>
        </div>
      </div>

      <!-- Info Box -->
      <div class="info-box">
        <p>
          ✓ <strong>Registrazione gratuita</strong> · Nessuna carta di credito richiesta<br>
          ✓ <strong>Facile e veloce</strong> · Bastano 2 minuti per iniziare
        </p>
      </div>
    </div>

    <!-- Footer -->
    <div class="email-footer">
      <div class="divider"></div>
      <p>Hai ricevuto questa email perché ${usernameInvitante || 'qualcuno'} ti ha invitato su ${nomeApp}</p>
      <p style="margin-top: 12px; font-size: 12px;">
        © ${new Date().getFullYear()} ${nomeApp}.
      </p>
      <p style="margin-top: 8px; font-size: 11px; color: #999;">
        Se non sei interessato, puoi semplicemente ignorare questa email.
      </p>
    </div>
  </div>
</body>
</html>
  `;
};

function checkifSendEmail() {
  return process.env.SEND_EMAIL === '1';
  //return false;
}

module.exports = {
  sendEmail_base_e_manager: async function (idapp, template, to, mylocalsconf, replyTo, transport, previewonly) {
    await this.sendEmail_base(idapp, template, to, mylocalsconf, replyTo, transport, previewonly);

    await this.sendEmail_base(idapp, template, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '', transport, previewonly);

    if (tools.isManagAndAdminDifferent(idapp)) {
      const email = tools.getManagerEmailByIdApp(idapp);
      await this.sendEmail_base(idapp, template, email, mylocalsconf, '', transport, previewonly);
    }
  },

  sendEmail_base: async function (idapp, template, to, mylocalsconf, replyTo, transport, previewonly) {
    if (to === '') return false;

    // console.log('mylocalsconf', mylocalsconf);

    // console.log("check EMAIL :" + checkifSendEmail());

    if (replyTo === '') replyTo = mylocalsconf.dataemail.email_reply;

    if (!replyTo) replyTo = '';

    const emailSender = mylocalsconf.dataemail.from;
    let senderName = '';
    if (idapp) {
      senderName = tools.getNomeAppByIdApp(mylocalsconf.idapp);
    }

    const emailcompleta = senderName ? `"${senderName}" <${emailSender}>` : emailSender;

    const paramemail = {
      message: {
        from: emailcompleta,
        headers: {
          'Reply-To': replyTo,
        },
      },
    };

    if (previewonly === undefined) {
      paramemail.preview = !checkifSendEmail();
      paramemail.send = checkifSendEmail();
    } else {
      paramemail.preview = previewonly;
      paramemail.send = !previewonly;
    }

    if (transport) {
      paramemail.transport = transport;
    } else {
      paramemail.transport = this.getTransport(mylocalsconf);
    }

    // se non è presente la password, non inviare l'email e manda messaggio di errore !

    if (!paramemail.transport.options.auth.pass) {
      let email = paramemail.transport.options.auth.user;

      console.error('❌ Password mancante ! Impossibile inviare le email. user=', email);
      return false;
    }

    // console.table(paramemail.transport);

    // console.log('2 . paramemail.transport', paramemail.transport);
    // console.log('user', tools.getEmailByIdApp(mylocalsconf.idapp));
    // console.log('pass', tools.getPwdByIdApp(mylocalsconf.idapp));

    // console.log('paramemail', paramemail);

    const email = new Email(paramemail);

    console.log(' *** Invia Email a ' + to, 'template', template);

    return email
      .send({
        template: template,
        message: {
          to: to,
        },
        locals: mylocalsconf,
      })
      .then((ris) => {
        if (ris?.response && ris.response.includes('Ok')) {
          console.log('✅ Email INVIATA');
        }
        // console.log('ris EMAIL', ris);
        return !!ris;
      })
      .catch((err) => {
        console.log('❌ Email NON INVIATA!');
        console.error('sendEmail_base Error: ', err);
        return false;
      });
  },

  sendEmail_Normale: async function (mylocalsconf, to, subject, html, replyTo) {
    try {
      const emailSender = tools.getEmailByIdApp(mylocalsconf.idapp);
      const senderName = tools.getNomeAppByIdApp(mylocalsconf.idapp);

      // setup e-mail data with unicode symbols
      var mailOptions = {
        from: `"${senderName}" <${emailSender}>`,
        dataemail: await this.getdataemail(mylocalsconf.idapp),
        to: to,
        generateTextFromHTML: true,
        subject: subject,
        html: html,
      };

      if (replyTo) mailOptions['reply-to'] = replyTo;

      const smtpTransport = this.getTransport(mylocalsconf);

      if (process.env.SEND_EMAIL === '1') {
        // console.log("SEND EMAIL...");
        // send mail with defined transport object
        smtpTransport.sendMail(mailOptions, function (error, response) {
          if (error) {
            console.log('Email Inviata ERRORE RISPOSTA: ' + error);
          } else {
            // console.log("Email Inviata RISPOSTA: " + response);
          }
        });
      } else {
        if (process.env.PROVA_EMAIL_TEMPLATE !== '1') previewEmail(mailOptions).then(console.log).catch(console.error);
        else transport_preview.sendMail(mailOptions).then(console.log).catch(console.error);
      }
    } catch (e) {
      console.error('Errore Sendmail', e);
    }
  },

  getlinkReg: function (idapp, idreg) {
    const strlinkreg = tools.getHostByIdApp(idapp) + process.env.LINKVERIF_REG + `/?idapp=${idapp}&idlink=${idreg}`;
    return strlinkreg;
  },
  getlinkVerifyEmail: async function (idapp, email, username) {
    try {
      const reg = require('./reg/registration');

      const idverif = reg.getlinkregByEmail(idapp, email, username);

      await User.setLinkToVerifiedEmail(idapp, username, idverif);

      const strlinkreg =
        tools.getHostByIdApp(idapp) + process.env.CHECKREVERIF_EMAIL + `/?idapp=${idapp}&idlink=${idverif}`;
      return strlinkreg;
    } catch (e) {
      console.error('ERROR getlinkVerifyEmail');
    }
  },
  getlinkInvitoReg: function (idapp, dati) {
    const strlinkreg = tools.getHostByIdApp(idapp) + `/invitetoreg/${dati.token}`;
    return strlinkreg;
  },
  getLinkAmmissione: function (idapp, user) {
    if (user.token_da_ammettere) {
      const strlink = tools.getHostByIdApp(idapp) + `/ammetti/${user.token_da_ammettere}/${user.username}`;
      return strlink;
    }
    return '';
  },
  getLinkAbilitaCircuito: function (idapp, user, data) {
    if (data.token_circuito_da_ammettere) {
      const strlink =
        tools.getHostByIdApp(idapp) +
        `/abcirc/${data.cmd}/${data.token_circuito_da_ammettere}/${user.username}/${data.myusername}`;
      return strlink;
    }
    return '';
  },

  getPathEmail(idapp, email_template) {
    const RISO_TEMPLATES = [
      'reg_notifica_all_invitante',
      'reg_email_benvenuto_ammesso',
      'reg_chiedi_ammettere_all_invitante',
      'circuit_chiedi_facilitatori_di_entrare',
      'circuit_abilitato_al_fido_membro',
    ];

    if (idapp === '13') {
      if (RISO_TEMPLATES.includes(email_template)) {
        return tools.RISO_STR_PATH + '/' + email_template;
      }
    }
    return 'defaultSite/' + email_template;
  },
  sendEmail_Registration: async function (lang, emailto, user, idapp, idreg) {
    try {
      const nomecognomeInvitante = await User.getNameSurnameByUsername(idapp, user.aportador_solidario, true);

      if (!user.verified_by_aportador) {
        // Genera Token per Ammettere l'Utente
        const r1 = await User.setAmmissioneByTokenAndUsername(idapp, user.username);
        if (r1 && r1.token_da_ammettere) {
          user.token_da_ammettere = r1.token_da_ammettere;
        }
      }

      let mylocalsconf = {
        idapp,
        dataemail: await this.getdataemail(idapp),
        baseurl: tools.getHostByIdApp(idapp),
        locale: lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        strlinkreg: this.getlinkReg(idapp, idreg),
        forgetpwd: tools.getHostByIdApp(idapp) + '/requestresetpwd',
        linkAmmissione: this.getLinkAmmissione(idapp, user),
        emailto: emailto,
        verified_email: user.verified_email,
        usernameInvitante: user.aportador_solidario,
        nomeInvitante: nomecognomeInvitante.trim(),
        nomeInvitato: await User.getNameSurnameEUsernameByUsername(idapp, user.username),
        userprofile: await User.getProfileByUsername(idapp, user.username),
        usernameInvitato: user.username,
        emailInvitato: user.email,
        user,
      };

      mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);

      let quale_email_inviare = '';

      if (user.verified_email) {
        // se l'utente è già stato verificata la sua email, allora gli mando direttamente la email di invito.
        quale_email_inviare = this.getPathEmail(idapp, 'reg_email_benvenuto_ammesso') + '/' + lang;
      } else {
        // altrimenti gli mando l'email con la richiesta di Verifica email
        quale_email_inviare = tools.getpathregByIdApp(idapp, lang);
      }

      //Invia una email al nuovo utente
      await this.sendEmail_base(idapp, quale_email_inviare, emailto, mylocalsconf, tools.getreplyToEmailByIdApp(idapp));

      if (user.verified_email && user.aportador_solidario && user.verified_by_aportador) {
        const pathemail = this.getPathEmail(idapp, 'reg_notifica_all_invitante');

        // Manda anche una email al suo Invitante
        const recaportador = await User.getUserShortDataByUsername(idapp, user.aportador_solidario);
        const ris = await this.sendEmail_base(idapp, pathemail + '/' + tools.LANGADMIN, recaportador.email, mylocalsconf, '');
      } else if (user.aportador_solidario && !user.verified_by_aportador) {
        const pathemail = this.getPathEmail(idapp, 'reg_chiedi_ammettere_all_invitante');

        // Manda una email al suo Invitante per chiedere di essere ammesso
        const recaportador = await User.getUserShortDataByUsername(idapp, user.aportador_solidario);
        const ris = await this.sendEmail_base(idapp, pathemail + '/' + tools.LANGADMIN, recaportador.email, mylocalsconf, '');
      }

      // Send to the Admin an Email
      const ris = await this.sendEmail_base(idapp, 
        'admin/registration/' + tools.LANGADMIN,
        tools.getAdminEmailByIdApp(idapp),
        mylocalsconf,
        ''
      );

      await telegrambot.notifyToTelegram(telegrambot.phase.REGISTRATION, mylocalsconf);

      if (tools.getConfSiteOptionEnabledByIdApp(mylocalsconf.idapp, shared_consts.ConfSite.Notif_Reg_Push_Admin)) {
        const nometot = tools.getNomeCognomeEUserNameByUser(mylocalsconf);

        let aportador = mylocalsconf.aportador_solidario ? ' (da ' + mylocalsconf.aportador_solidario + ')' : '';

        const numutenti = await User.getNumUsers(mylocalsconf.idapp);
        tools.sendNotifToAdmin(mylocalsconf.idapp, true, '++Registrazione [' + numutenti + '] ' + nometot + aportador);
      }

      return ris;
    } catch (e) {
      console.error('Err sendEmail_Registration', e);
    }
  },
  sendEmail_InvitaAmico: async function (lang, emailto, user, idapp, dati) {
    try {
      const nomecognomeInvitante = await User.getNameSurnameByUsername(idapp, dati.usernameInvitante, true);

      let mylocalsconf = {
        idapp,
        dataemail: await this.getdataemail(idapp),
        baseurl: tools.getHostByIdApp(idapp),
        locale: lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        //strlinkreg: this.getlinkReg(idapp, idreg),
        linkRegistrazione: this.getlinkInvitoReg(idapp, dati),
        emailto: emailto,
        usernameInvitante: dati.usernameInvitante,
        nomeInvitante: nomecognomeInvitante.trim(),
        messaggioPersonalizzato: dati.messaggioPersonalizzato,
      };

      const ris = await this.sendEmail_base(idapp, 'invitaamico/' + lang, emailto, mylocalsconf, '');

      await telegrambot.notifyToTelegram(telegrambot.phase.INVITA_AMICO, mylocalsconf);

      return ris;
    } catch (e) {
      console.error('Err sendEmail_InvitaAmico', e);
    }
  },
  sendEmail_Utente_Ammesso: async function (lang, emailto, user, idapp, dati) {
    try {
      let mylocalsconf = {
        idapp,
        dataemail: await this.getdataemail(idapp),
        baseurl: tools.getHostByIdApp(idapp),
        locale: lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        //strlinkreg: this.getlinkReg(idapp, idreg),
        emailto: emailto,
        usernameInvitante: dati.usernameInvitante,
        ammessoUtente: true,
        user,
      };

      const quale_email_inviare = this.getPathEmail(idapp, 'reg_email_benvenuto_ammesso') + '/' + lang;

      const ris = await this.sendEmail_base(idapp, quale_email_inviare, emailto, mylocalsconf, '');

      await telegrambot.notifyToTelegram(telegrambot.phase.AMMETTI_UTENTE, mylocalsconf);

      return ris;
    } catch (e) {
      console.error('Err sendEmail_Utente_Ammesso', e);
    }
  },
  sendEmail_ReVerifyingEmail: async function (dati, idapp) {
    try {
      const user = await User.getUserById(idapp, dati._id);
      const lang = user.lang;
      const username = user.username;
      const email = user.email;

      let mylocalsconf = {
        idapp,
        dataemail: await this.getdataemail(idapp),
        baseurl: tools.getHostByIdApp(idapp),
        locale: lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        //strlinkreg: this.getlinkReg(idapp, idreg),
        emailto: email,
        name: user.name,
        username: user.username,
        verifyLink: await this.getlinkVerifyEmail(idapp, email, username),
        user,
        supportEmail: tools.getContactEmailSupportBydApp(idapp),
      };

      const quale_email_inviare = this.getPathEmail(idapp, 'reg_resend_email_to_verifiyng') + '/' + lang;

      const ris = await this.sendEmail_base(idapp, quale_email_inviare, email, mylocalsconf, '');

      return ris;
    } catch (e) {
      console.error('Err sendEmail_ReVerifyingEmail', e);
    }
  },
  sendEmail_Utente_Abilitato_Circuito_FidoConcesso: async function (lang, emailto, user, idapp, dati) {
    try {
      const { Circuit } = require('../models/circuit');
      
      let mylocalsconf = {
        idapp,
        dataemail: await this.getdataemail(idapp),
        baseurl: tools.getHostByIdApp(idapp),
        locale: lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        emailto: emailto,
        usernameInvitante: dati.usernameInvitante,
        linkProfiloAdmin: tools.getLinkUserProfile(idapp, dati.usernameInvitante),
        user,
        symbol: await Circuit.getSymbolByCircuitId(dati.circuitId),
        usernameMembro: user.username,
        nomeTerritorio: dati.nomeTerritorio,
        linkTelegramTerritorio: dati.link_group,
      };

      const quale_email_inviare = this.getPathEmail(idapp, 'circuit_abilitato_al_fido_membro') + '/' + lang;

      const ris = await this.sendEmail_base(idapp, quale_email_inviare, emailto, mylocalsconf, '');

      await telegrambot.notifyToTelegram(telegrambot.phase.AMMETTI_UTENTE, mylocalsconf);

      return ris;
    } catch (e) {
      console.error('Err sendEmail_Utente_Ammesso', e);
    }
  },
  sendEmail_Richiesta_Al_Facilitatore_Di_FarEntrare_AlCircuito: async function (
    lang,
    emailto,
    user,
    userInvitante,
    idapp,
    dati
  ) {
    try {
      // dati.circuitId
      // dati.groupname
      dati.cmd = shared_consts.CIRCUITCMD.SETFIDO;

      const linkAbilitazione = this.getLinkAbilitaCircuito(idapp, user, dati);

      const { Circuit } = require('../models/circuit');

      let mylocalsconf = {
        idapp,
        dataemail: await this.getdataemail(idapp),
        baseurl: tools.getHostByIdApp(idapp),
        locale: lang,
        usernameInvitante: user.aportador_solidario,
        nomeInvitante: userInvitante.name,
        cognomeInvitante: userInvitante.surname,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        //strlinkreg: this.getlinkReg(idapp, idreg),
        emailto: emailto,
        usernameMembro: user.username,
        nomeMembro: user.name,
        cognomeMembro: user.surname,
        emailMembro: user.email,
        nomeFacilitatore: dati.nomeFacilitatore,
        nomeTerritorio: dati.nomeTerritorio,
        comuneResidenza: user.profile.resid_str_comune,
        provinciaResidenza: user.profile.resid_province,
        user,
        symbol: await Circuit.getSymbolByCircuitId(dati.circuitId),
        linkAbilitazione: linkAbilitazione,
        linkProfiloMembro: tools.getLinkUserProfile(idapp, user.username),
        linkProfiloInvitante: tools.getLinkUserProfile(idapp, user.aportador_solidario),
        telegramMembro: user.profile?.username_telegram,
        telegramInvitante: userInvitante.profile?.username_telegram,
      };

      const quale_email_inviare = this.getPathEmail(idapp, 'circuit_chiedi_facilitatori_di_entrare') + '/' + lang;

      const ris = await this.sendEmail_base(idapp, quale_email_inviare, emailto, mylocalsconf, '');

      // await telegrambot.notifyToTelegram(telegrambot.phase.AMMETTI_UTENTE, mylocalsconf);

      return ris;
    } catch (e) {
      console.error('Err sendEmail_Richiesta_Al_Facilitatore_Di_FarEntrare_AlCircuito', e);
    }
  },

  sendEmail_IscrizioneConacreis: async function (lang, emailto, iscritto, idapp) {
    // console.log('idapp', idapp, tools.getNomeAppByIdApp(idapp));

    let mylocalsconf = {
      idapp,
      dataemail: await this.getdataemail(idapp),
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksito: tools.getHostByIdApp(idapp),
      emailto: emailto,
      iscritto,
      metodo_pagamento: tools.getPaymentTypesById(iscritto.metodo_pagamento),
      data_nascita: tools.getstrDate_DD_MM_YYYY(iscritto.dateofbirth),
    };

    mylocalsconf = this.setParamsForTemplate(iscritto, mylocalsconf);

    await this.sendEmail_base(
      idapp, 
      'iscrizione_conacreis/' + lang,
      emailto,
      mylocalsconf,
      tools.getreplyToEmailByIdApp(idapp)
    );

    // Send to the Admin an Email
    await this.sendEmail_base(
      idapp, 
      'admin/iscrizione_conacreis/' + tools.LANGADMIN,
      tools.getAdminEmailByIdApp(idapp),
      mylocalsconf,
      ''
    );

    await telegrambot.notifyIscrizioneToTelegram(
      telegrambot.phase.ISCRIZIONE_CONACREIS,
      mylocalsconf,
      'MSG_ISCRITTO_CONACREIS'
    );

    tools.sendNotifToAdmin(
      idapp,
      true,
      'Iscrizione Conacreis : ' + mylocalsconf.name + ' ' + mylocalsconf.surname + ' (' + mylocalsconf.username + ')'
    );

    if (tools.isManagAndAdminDifferent(idapp)) {
      await this.sendEmail_base(
        idapp, 
        'admin/iscrizione_conacreis/' + tools.LANGADMIN,
        tools.getManagerEmailByIdApp(idapp),
        mylocalsconf,
        ''
      );
    }
  },

  sendEmail_RequestNewPassword: async function (lang, user, emailto, idapp, tokenforgot, tokenforgot_code) {
    console.log('sendEmail_RequestNewPassword');

    let mylocalsconf = {
      idapp,
      dataemail: await this.getdataemail(idapp),
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksetpassword: tools.getlinkRequestNewPassword(idapp, emailto, tokenforgot),
      tokenforgot_code,
      emailto: emailto,
    };

    mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);

    await this.sendEmail_base(idapp, 'resetpwd/' + lang, emailto, mylocalsconf, '');
  },

  sendEmail_RisRicevuti: async function (lang, userDest, emailto, idapp, myrec, extrarec) {
    console.log('sendEmail_RisRicevuti');

    let mylocalsconf = {
      idapp,
      baseurl: tools.getHostByIdApp(idapp),
      dataemail: await this.getdataemail(idapp),
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksito: tools.getHostByIdApp(idapp),
      emailto: emailto,
      qty: myrec.qty,
      saldoAttuale: extrarec.saldoDest,
      mittente: decode(myrec.mittente),
      nomecircuito: decode(myrec.nomecircuito),
      transactionDate: tools.getstrDate_DD_MM_YYYY(myrec.transactionDate),
      symbol: myrec.symbol,
      causale: myrec.causale,
      causalDest: myrec.causalDest,
      groupDestoContoCom: myrec.groupDestoContoCom,
    };

    mylocalsconf = this.setParamsForTemplate(userDest, mylocalsconf);

    await this.sendEmail_base(idapp, 'risricevuti/' + lang, emailto, mylocalsconf, '');
  },

  sendEmail_Booking: async function (res, lang, emailto, user, idapp, recbooking) {
    tools.mylog('sendEmail_Booking');
    tools.mylog('tools.getNomeAppByIdApp(idapp)', tools.getNomeAppByIdApp(idapp), idapp);

    let mylocalsconf = {
      idapp,
      dataemail: await this.getdataemail(idapp),
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksito: tools.getHostByIdApp(idapp),
      emailto: emailto,
      msgbooking: '',
      participants: '',
      participantsLunch: '',
      participantsDinner: '',
      participantsDinnerShared: '',
      msgbooking: tools.convertTexttoHtml(recbooking.msgbooking),
      eventtextplain: tools.removeSpecialCharForEmail(recbooking.infoevent),
      event: recbooking.infoevent,
    };

    mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);

    return await Settings.getValDbSettings(idapp, 'MSG_REPLY_AFTER_BOOKING').then(async (ris) => {
      mylocalsconf.msgreply_after_booking = ris;

      mylocalsconf = await this.preparaConfPerBooking(res, idapp, mylocalsconf, recbooking, 'Prenotazione');

      if (recbooking.modified) {
        texthtml = 'modifybooking';
      } else {
        texthtml = 'makebooking';
      }

      await this.sendEmail_base(
        idapp, 
        'booking/' + texthtml + '/' + lang,
        emailto,
        mylocalsconf,
        tools.getreplyToEmailByIdApp(idapp)
      );

      // Send Email also to the Admin
      await this.sendEmail_base(
        idapp, 
        'admin/' + texthtml + '/' + tools.LANGADMIN,
        tools.getAdminEmailByIdApp(idapp),
        mylocalsconf,
        ''
      );

      if (tools.isManagAndAdminDifferent(idapp)) {
        await this.sendEmail_base(
          idapp, 
          'admin/' + texthtml + '/' + tools.LANGADMIN,
          tools.getManagerEmailByIdApp(idapp),
          mylocalsconf,
          ''
        );
      }
    });
  },

  preparaConfPerBooking: async function (res, idapp, mylocalsconf, recbooking, title) {
    let texthtml = '';
    let msgtelegram =
      title +
      ' Evento [' +
      mylocalsconf.username +
      ' (' +
      mylocalsconf.name +
      ' ' +
      mylocalsconf.surname +
      ')] ' +
      mylocalsconf.eventtextplain;
    if (recbooking.modified) {
      msgtelegram += ' (modificato) ';
    } else {
      msgtelegram += ' (Nuovo)';
    }

    msgtelegram += '\n';

    if (recbooking.msgbooking) {
      mylocalsconf.msgbooking = 'Messaggio: ' + recbooking.msgbooking.toString();
      msgtelegram += mylocalsconf.msgbooking + '\n';
    }
    if (recbooking.numpeople > 0) {
      mylocalsconf.participants = recbooking.numpeople.toString() + ' ' + tools.getres__('partecipanti', res);
      msgtelegram += mylocalsconf.participants + '\n';
    }

    if (recbooking.numpeopleLunch > 0) {
      mylocalsconf.participantsLunch =
        recbooking.numpeopleLunch.toString() + ' ' + tools.getres__('partecipanti a Pranzo', res);
      msgtelegram += mylocalsconf.participantsLunch + '\n';
    }

    if (recbooking.numpeopleDinner > 0) {
      mylocalsconf.participantsDinner =
        recbooking.numpeopleDinner.toString() + ' ' + tools.getres__('partecipanti a Cena', res);
      msgtelegram += mylocalsconf.participantsDinner + '\n';
    }

    if (recbooking.numpeopleDinnerShared > 0) {
      mylocalsconf.participantsDinnerShared =
        recbooking.numpeopleDinnerShared.toString() + ' ' + tools.getres__('partecipanti a Cena Condivisa', res);
      msgtelegram += mylocalsconf.participantsDinnerShared + '\n';
    }

    telegrambot.sendMsgTelegramToTheManagers(idapp, msgtelegram);

    return mylocalsconf;
  },

  getName: function (mylocalsconf) {
    return mylocalsconf.name
      ? mylocalsconf.surname
        ? mylocalsconf.name + ' ' + mylocalsconf.surname
        : mylocalsconf.name
      : mylocalsconf.username;
  },

  sendEmail_CancelBooking: async function (res, lang, emailto, user, idapp, recbooking) {
    tools.mylog('sendEmail_CancelBooking');

    let mylocalsconf = {
      idapp,
      dataemail: await this.getdataemail(idapp),
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksito: tools.getHostByIdApp(idapp),
      event: recbooking.infoevent,
      participants: '',
      participantsLunch: '',
      participantsDinner: '',
      participantsDinnerShared: '',
      eventtextplain: tools.removeSpecialCharForEmail(recbooking.infoevent),
    };

    mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);

    mylocalsconf.emailto = emailto;

    mylocalsconf = await this.preparaConfPerBooking(res, idapp, mylocalsconf, recbooking, 'Cancellazione');

    let msgtelegram = 'Cancellazione Evento [' + this.getName(mylocalsconf) + '] ' + mylocalsconf.eventtextplain;

    telegrambot.sendMsgTelegramToTheManagers(idapp, msgtelegram);

    await this.sendEmail_base(
      idapp, 
      'booking/cancelbooking/' + lang,
      emailto,
      mylocalsconf,
      tools.getreplyToEmailByIdApp(idapp)
    );

    // Send Email also to the Admin
    await this.sendEmail_base(
      idapp, 
      'admin/cancelbooking/' + tools.LANGADMIN,
      tools.getAdminEmailByIdApp(idapp),
      mylocalsconf,
      ''
    );

    if (tools.isManagAndAdminDifferent(idapp)) {
      await this.sendEmail_base(
        idapp, 
        'admin/cancelbooking/' + tools.LANGADMIN,
        tools.getManagerEmailByIdApp(idapp),
        mylocalsconf,
        ''
      );
    }
  },

  sendEmail_Msg: async function (res, lang, emailto, user, idapp, recmsg) {
    tools.mylog('sendEmail_Msg');
    tools.mylog('tools.getNomeAppByIdApp(idapp)', tools.getNomeAppByIdApp(idapp), idapp);

    mylocalsconf = {
      idapp,
      dataemail: await this.getdataemail(idapp),
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksito: tools.getHostByIdApp(idapp),
      usernameorig: user.name + ' ' + user.surname,
      message: tools.convertTexttoHtml(recmsg.message),
      infoevent: recmsg.source.infoevent,
      strlinkreply: tools.getHostByIdApp(idapp) + '/messages/' + recmsg._id,
    };

    mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);
    mylocalsconf.emailto = emailto;

    let replyto = '';
    if (mylocalsconf.infoevent !== '') replyto = user.email;
    else replyto = tools.getreplyToEmailByIdApp(idapp);

    return await this.sendEmail_base(idapp, 'msg/sendmsg/' + lang, emailto, mylocalsconf, replyto);

    // Send Email also to the Admin
    // this.sendEmail_base('admin/sendmsg/' + lang, tools.getAdminEmailByIdApp(idapp), mylocalsconf);
  },

  sendEmail_ByText: async function (lang, emailto, user, idapp, rec) {
    try {
      tools.mylog('sendEmail_ByText');

      let mylocalsconf = {
        idapp,
        dataemail: await this.getdataemail(idapp),
        locale: lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        usernameorig: user.name + ' ' + user.surname,
      };

      mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);
      mylocalsconf.emailto = emailto;

      mylocalsconf.dataemail.emailbody = rec.emailbody;
      mylocalsconf.dataemail.emailtitle = rec.emailtitle;

      if (!!mylocalsconf.dataemail.emailtitle && !!mylocalsconf.dataemail.emailbody) {
        const replyto = tools.getreplyToEmailByIdApp(idapp);

        //return this.sendEmail_base('standard', emailto, mylocalsconf, replyto);
        return await this.sendEmail_Normale(
          mylocalsconf,
          emailto,
          mylocalsconf.dataemail.emailtitle,
          mylocalsconf.dataemail.emailbody,
          replyto
        );
      }
    } catch (e) {
      console.error('Errore sendEmail_ByText', e);
    }

    // Send Email also to the Admin
    // this.sendEmail_base('admin/sendmsg/' + lang, tools.getAdminEmailByIdApp(idapp), mylocalsconf);
  },

  sendEmail_ByNotif: async function (lang, emailto, user, idapp, recnotif) {
    tools.mylog('sendEmail_ByNotif');

    let mylocalsconf = {
      idapp,
      dataemail: await this.getdataemail(idapp),
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksito: tools.getHostByIdApp(idapp),
      usernameorig: user.name + ' ' + user.surname,
    };

    mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);
    mylocalsconf.emailto = emailto;

    mylocalsconf.dataemail.emailtitle = recnotif.title;
    mylocalsconf.dataemail.emailbody = tools.getTextNotifByRecNotif(recnotif);

    if (!!mylocalsconf.dataemail.emailtitle && !!mylocalsconf.dataemail.emailbody) {
      const replyto = tools.getreplyToEmailByIdApp(idapp);

      //return this.sendEmail_base('standard', emailto, mylocalsconf, replyto);
      return await this.sendEmail_Normale(
        mylocalsconf,
        emailto,
        mylocalsconf.dataemail.emailtitle,
        mylocalsconf.dataemail.emailbody,
        replyto
      );
    }

    // Send Email also to the Admin
    // this.sendEmail_base('admin/sendmsg/' + lang, tools.getAdminEmailByIdApp(idapp), mylocalsconf);
  },

  Add_to_MailingList_AndSendEmailNotify: async function (lang, user, idapp, sendnews) {
    // console.log('idapp', idapp, tools.getNomeAppByIdApp(idapp));

    let mylocalsconf = {
      idapp,
      dataemail: await this.getdataemail(idapp),
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksito: tools.getHostByIdApp(idapp),
    };

    mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);

    const hash = tools.getHash(mylocalsconf.emailto);

    // Check if exist to the Mailing List
    let myperson = await MailingList.findByHash(idapp, hash);
    if (!myperson || !myperson.news_on || !myperson.email_errata) {
      if (!myperson) {
        myperson = new MailingList({
          name: mylocalsconf.name,
          surname: mylocalsconf.surname,
          email: mylocalsconf.emailto,
          hash,
        });
        myperson._id = new ObjectId();
      } else {
        myperson.name = mylocalsconf.name;
        myperson.surname = mylocalsconf.surname;
        //myperson.email = mylocalsconf.emailto;
        //myperson.hash = hash;
      }

      myperson.idapp = idapp;
      myperson.news_on = true; // subscription
      myperson.email_errata = false;

      // Add/save new record to the DB MailingList
      const res = await myperson.save();

      if (sendnews) {
        // Send to the Admin an Email
        await this.sendEmail_base(
          idapp, 
          'admin/added_to_newsletter/' + tools.LANGADMIN,
          tools.getAdminEmailByIdApp(idapp),
          mylocalsconf,
          ''
        );

        if (tools.isManagAndAdminDifferent(idapp)) {
          await this.sendEmail_base(
            idapp, 
            'admin/added_to_newsletter/' + tools.LANGADMIN,
            tools.getManagerEmailByIdApp(idapp),
            mylocalsconf,
            ''
          );
        }
      }

      return { code: server_constants.RIS_SUBSCRIBED_OK, msg: server_constants.RIS_SUBSCRIBED_MSG[lang] };
    } else {
      // Already Esist
      return {
        code: server_constants.RIS_SUBSCRIBED_ALREADYEXIST,
        msg: server_constants.RIS_SUBSCRIBED_MSG_ALREADYEXIST[lang],
      };
    }
  },

  Remove_from_MailingList: async function (lang, hashemail, idapp) {
    // console.log('idapp', idapp, tools.getNomeAppByIdApp(idapp));

    // Check if exist to the Mailing List
    if (await MailingList.isUnsubscribed(idapp, hashemail)) {
      return {
        myperson: null,
        code: server_constants.RIS_UNSUBSCRIBED_ALREADY_DONE,
        msg: server_constants.RIS_UNSUBSCRIBED_MSG_ALREADY_DONE[lang],
      };
    }

    const fields_to_update = {
      news_on: false,
    };
    let myperson = await User.findOneAndUpdate(
      {
        idapp,
        hash: hashemail,
      },
      { $set: fields_to_update },
      { new: false }
    );
    if (myperson) {
      return { myperson, code: server_constants.RIS_UNSUBSCRIBED_OK, msg: '' };
    } else {
      // Not found !
      return {
        myperson: null,
        code: server_constants.RIS_UNSUBSCRIBED_NOT_EXIST,
        msg: server_constants.RIS_UNSUBSTR_NOT_EXIST[lang],
      };
    }
  },

  fieldsloop: function (mylocalsconf, myvar) {
    let out = '';
    try {
      out = myvar.replace('{urlunsubscribe}', tools.getUnsubsribeUrl(mylocalsconf));
      out = out.replace(
        '{urlunsubscribe_user}',
        tools.getUnsubsribeUrl_User({
          idapp: mylocalsconf.idapp,
          email: mylocalsconf.emailto,
          username: mylocalsconf.username,
          name: mylocalsconf.name,
          surname: mylocalsconf.surname,
        })
      );

      out = out.replace('{email}', mylocalsconf.emailto);
      out = out.replace('{username}', mylocalsconf.username);
      out = out.replace('{name}', mylocalsconf.name ? mylocalsconf.name : mylocalsconf.username);
      out = out.replace('{surname}', mylocalsconf.surname ? mylocalsconf.surname : '');
      out = out.replace(
        '{aportador_solidario}',
        mylocalsconf.aportador_solidario ? mylocalsconf.aportador_solidario : ''
      );
    } catch (e) {
      console.error('err fieldsloop', e);
      return out;
    }

    return out;
  },

  replacefields: function (mylocalsconf) {
    try {
      mylocalsconf.dataemail.disclaimer_out = !!mylocalsconf.dataemail.disclaimer
        ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.disclaimer)
        : '';
      mylocalsconf.dataemail.disc_bottom_out = !!mylocalsconf.dataemail.disc_bottom
        ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.disc_bottom)
        : '';
      mylocalsconf.dataemail.firma = !!mylocalsconf.dataemail.firma
        ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.firma)
        : '';

      if (mylocalsconf.dataemail.templ) {
        if (mylocalsconf.dataemail.templ.disclaimer)
          mylocalsconf.dataemail.disclaimer_out = this.fieldsloop(
            mylocalsconf,
            mylocalsconf.dataemail.templ.disclaimer
          );

        if (mylocalsconf.dataemail.templ.piedipagina)
          mylocalsconf.dataemail.disc_bottom_out = this.fieldsloop(
            mylocalsconf,
            mylocalsconf.dataemail.templ.piedipagina
          );

        if (mylocalsconf.dataemail.templ.firma)
          mylocalsconf.dataemail.firma = this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.templ.firma);

        mylocalsconf.dataemail.templ.testoheadermail_out = !!mylocalsconf.dataemail.templ.testoheadermail
          ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.templ.testoheadermail)
          : '';

        mylocalsconf.dataemail.templ.content = !!mylocalsconf.dataemail.templ.content
          ? this.fieldsloop(mylocalsconf, mylocalsconf.dataemail.templ.content)
          : '';
      }
    } catch (e) {
      console.error('Error replacefields: ' + e);
    }

    return mylocalsconf;
  },

  getdataemail: async (idapp, templemail_id) => {
    try {
      const pwd_from = await Settings.getValDbSettings(idapp, 'PWD_FROM');

      let mydata = {
        templemail_id: templemail_id ? templemail_id : await Settings.getValDbSettings(idapp, 'TEMPLEMAIL_ID'),
        destnewsletter_id: await Settings.getValDbSettings(idapp, 'TEMPLEMAIL_DEST'),
      };

      mydata.templ = await TemplEmail.findOne({ _id: mydata.templemail_id }).lean();
      mydata.destnewsl = await DestNewsletter.findOne({ _id: mydata.destnewsletter_id }).lean();

      // console.log('getdataemail');
      mydata = {
        ...mydata,
        content_after_events: await Settings.getValDbSettings(idapp, 'TEXT_AFTER_EV'),
        mailchimpactive: tools.BoolToInt(await Settings.getValDbSettings(idapp, 'MAILCHIMP_ON')),
        urltwitter: await Settings.getValDbSettings(idapp, 'URL_TWITTER'),
        urlfb: await Settings.getValDbSettings(idapp, 'URL_FACEBOOK'),
        urlyoutube: await Settings.getValDbSettings(idapp, 'URL_YOUTUBE'),
        urlinstagram: await Settings.getValDbSettings(idapp, 'URL_INSTAGRAM'),
        textpromo: await Settings.getValDbSettings(idapp, 'TEXT_PROMO'),
        disc_bottom: await Settings.getValDbSettings(idapp, 'TEXT_DISC_BOTTOM'),

        arrdiscipline: await Discipline.getDisciplineforNewsletter(idapp),
        disc_title: await Settings.getValDbSettings(idapp, 'DISC_TITLE'),
        height_logo: await Settings.getValDbSettings(idapp, 'HEIGHT_LOGO'),
        from: await Settings.getValDbSettings(idapp, 'EMAIL_FROM'),
        email_reply: await Settings.getValDbSettings(idapp, 'EMAIL_REPLY', ''),
        pwd_from: pwd_from,
        email_service: await Settings.getValDbSettings(idapp, 'EMAIL_SERVICE_SEND'),
        email_port: await Settings.getValDbSettings(idapp, 'EMAIL_PORT'),
      };

      return mydata;
    } catch (e) {
      console.error('Error getdataemail: ' + e);
      return null;
    }
  },

  getTransport: (mylocalsconf) => {
    // console.log('getTransport');

    // Create Transport
    let smtpTransport = null;

    // console.log('mylocalsconf.dataemail', mylocalsconf.dataemail);

    if (
      mylocalsconf.dataemail.email_service !== 'gmail' &&
      mylocalsconf.dataemail.email_service !== undefined &&
      mylocalsconf.dataemail.email_service !== ''
    ) {
      smtpTransport = nodemailer.createTransport({
        host: mylocalsconf.dataemail.email_service,
        port: mylocalsconf.dataemail.email_port,
        secureConnection: true,
        tls: { cipher: 'SSLv3' },
        auth: {
          user: mylocalsconf.dataemail.from,
          pass: tools.decryptdata(mylocalsconf.dataemail.pwd_from),
        },
      });
    } else if (mylocalsconf.dataemail.email_service === 'gmail' && !!mylocalsconf.dataemail.pwd_from) {
      //smtpTransport = {
      smtpTransport = nodemailer.createTransport({
        service: 'gmail', //'Gmail',
        auth: {
          user: mylocalsconf.dataemail.from,
          pass: tools.decryptdata(mylocalsconf.dataemail.pwd_from),
        },
      });
    } else {
      // smtpTransport = {
      smtpTransport = nodemailer.createTransport({
        service: 'gmail',
        auth: {
          user: tools.getEmailByIdApp(mylocalsconf.idapp),
          pass: tools.getPwdByIdApp(mylocalsconf.idapp),
        },
      });
    }

    // console.log('smtpTransport', smtpTransport);

    return smtpTransport;
  },

  setParamsForTemplate: function (user, mylocalsconf) {
    try {
      mylocalsconf.username = user.username;
      mylocalsconf.name = user.name;
      mylocalsconf.surname = user.surname;
      mylocalsconf.aportador_solidario = user.aportador_solidario ? user.aportador_solidario : '';
      mylocalsconf.idMyGroup = user.idMyGroup;
      mylocalsconf.emailto = user.email;
      mylocalsconf.hashemail = tools.getHash(user.email);
      mylocalsconf.user = user;

      mylocalsconf = this.replacefields(mylocalsconf);
    } catch (e) {
      console.error('setParamsForTemplate', e);
    }

    return mylocalsconf;
  },

  sendEmail_OrderProduct: async function (lang, idapp, orders, user) {
    try {
      const msg = await OrdersCart.getmsgorderTelegram(orders);
      const msginizio = msg;
      console.log(msginizio);

      await telegrambot.sendMsgTelegramToTheManagers(idapp, msginizio);

      if (process.env.SEND_EMAIL_ORDERS === '1') {
        let mylocalsconf = {
          idapp,
          locale: lang,
          nomeapp: tools.getNomeAppByIdApp(idapp),
          strlinksito: tools.getHostByIdApp(idapp),
          orders,
          baseurl: tools.getHostByIdApp(idapp),
          dataemail: await this.getdataemail(idapp),
          ordernumber: orders.numorder,
          dirimg: 'upload/products/',
          user,
        };

        mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);

        await this.sendEmail_base_e_manager(
          idapp,
          'ecommerce/makeorder/' + lang,
          mylocalsconf.emailto,
          mylocalsconf,
          mylocalsconf.dataemail.email_reply
        );
      } else {
        console.log('Invio Email non eseguito perchè sei in TEST !');
      }
    } catch (e) {
      console.error('Err:', e);
    }
  },
  sendEmail_Order: async function (lang, idapp, orders, user, ordertype, status) {
    try {
      const msg = await OrdersCart.getmsgorderTelegram(orders);
      const msginizio = msg;
      console.log(msginizio);

      // await telegrambot.sendMsgTelegramToTheManagers(idapp, msginizio);

      if (process.env.SEND_EMAIL_ORDERS === '1') {
        let mylocalsconf = {
          idapp,
          locale: lang,
          nomeapp: tools.getNomeAppByIdApp(idapp),
          strlinksito: tools.getHostByIdApp(idapp),
          orders,
          baseurl: tools.getHostByIdApp(idapp),
          dataemail: await this.getdataemail(idapp),
          ordernumber: orders.numorder,
          user,
        };

        mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);

        if (status !== shared_consts.OrderStatus.CANCELED && status !== shared_consts.OrderStatus.COMPLETED) {
          const esito = await this.sendEmail_base(
            idapp, 
            'ecommerce/' + ordertype + '/' + lang,
            mylocalsconf.emailto,
            mylocalsconf,
            mylocalsconf.dataemail.email_reply
          );

          // this.sendEmail_base('ecommerce/' + ordertype + '/' + lang, tools.getAdminEmailByIdApp(idapp), mylocalsconf, '');

          // if (tools.isManagAndAdminDifferent(idapp)) {
          //   this.sendEmail_base('ecommerce/' + ordertype + '/' + lang, tools.getManagerEmailByIdApp(idapp), mylocalsconf, '');
          // }
        }
      } else {
        console.log('Invio Email non eseguito perchè sei in TEST !');
      }
    } catch (e) {
      console.error('Err:', e);
    }
  },

  sendEmail_Newsletter_Events: async function (lang, idapp, id_newstosent) {
    const msginizio = 'INIZIO - sendEmail_Newsletter_Events: ' + tools.getNomeAppByIdApp(idapp);
    console.log(msginizio);

    await telegrambot.sendMsgTelegramToTheManagers(idapp, msginizio);

    const myarrevents = await MyEvent.getLastEvents(idapp);

    let mylocalsconf = {
      idapp,
      locale: lang,
      nomeapp: tools.getNomeAppByIdApp(idapp),
      strlinksito: tools.getHostByIdApp(idapp),
      arrevents: myarrevents,
      baseurl: tools.getHostByIdApp(idapp),
      dataemail: await this.getdataemail(idapp),
    };

    await Newstosent.processingJob(id_newstosent, true);

    const mynewsrec = await Newstosent.findOne({ _id: id_newstosent });

    try {
      mynewsrec.templemail_str = mylocalsconf.dataemail.templ.subject;
      mynewsrec.destnewsletter_str = mylocalsconf.dataemail.destnewsl?.descr;

      let userstosend = [];

      if (mylocalsconf.dataemail.destnewsl?.tipodest_id === shared_consts.DESTNEWSLETTER.UTENTI) {
        userstosend = await MailingList.findAllIdAppSubscribed(idapp);
      } else if (mylocalsconf.dataemail.destnewsl?.tipodest_id === shared_consts.DESTNEWSLETTER.DIARIO) {
        userstosend = await MailingList.findAllIdAppDiarioSubscr(idapp);
      } else if (mylocalsconf.dataemail.destnewsl?.tipodest_id === shared_consts.DESTNEWSLETTER.TEST) {
        userstosend = await MailingList.findAllIdAppTestSubscr(idapp);
      } else {
        userstosend = await MailingList.findAllIdAppSubscribed(idapp);
      }

      mynewsrec.numemail_tot = userstosend.length;

      mynewsrec.numemail_sent = await MailingList.getnumSent(idapp, id_newstosent);

      const smtpTransport = this.getTransport(mylocalsconf);

      // LOOP USERS EMAIL
      for (const user of userstosend) {
        try {
          const isok = await MailingList.isOk(idapp, user._id, id_newstosent);
          if (isok) {
            let secpause = await Settings.getValDbSettings(idapp, 'MSEC_PAUSE_SEND', process.env.DELAY_SENDEMAIL);
            if (secpause < process.env.DELAY_SENDEMAIL) secpause = process.env.DELAY_SENDEMAIL;

            const activate = await Newstosent.isActivated(id_newstosent);

            if (!activate) {
              // Invio Newsletter Abortito!
              mynewsrec.error_job =
                'Invio Newsletter abortito alle ore ' + new Date().toDateString() + new Date().toTimeString();
              await telegrambot.sendMsgTelegramToTheManagers(idapp, mynewsrec.error_job);
              await mynewsrec.save();
              await Newstosent.processingJob(id_newstosent, false);
              console.log("*** L'Invio della Newsletter è stato fermato ! ");
              return false;
            }

            mylocalsconf = this.setParamsForTemplate(user, mylocalsconf);

            // If has already sent, don't send it again!
            if (user.lastid_newstosent !== id_newstosent.toString()) {
              // console.log('@@@@@ COMPARE DIVERSI: lastid', user.lastid_newstosent, 'idsent', id_newstosent.toString());

              if (process.env.VITE_DEBUG) await tools.snooze(5000);

              // Send Email to the User
              // console.log('-> Invio Email (', mynewsrec.numemail_sent, '/', mynewsrec.numemail_tot, ')');
              const esito = await this.sendEmail_base(
                idapp, 
                'newsletter/' + lang,
                mylocalsconf.emailto,
                mylocalsconf,
                mylocalsconf.dataemail.email_reply,
                smtpTransport
              );

              if (mynewsrec.numemail_sent % 100 === 0) {
                const msgproc =
                  'In Corso ' + mynewsrec.numemail_sent + ' / ' + mynewsrec.numemail_tot + ' Email inviate...';
                await telegrambot.sendMsgTelegramToTheManagers(idapp, msgproc);
              }

              //Put the result in the database, to check if is sent or not.
              const updateml = await User.findOneAndUpdate(
                {
                  idapp,
                  email: user.email,
                },
                { $set: { lastid_newstosent: new ObjectId(id_newstosent) } },
                { new: false }
              );

              //Delay for send email...
              await tools.snooze(secpause);

              mynewsrec.lastemailsent_Job = new Date();
              mynewsrec.numemail_sent = await MailingList.getnumSent(idapp, id_newstosent);

              const recsaved = await mynewsrec.save();
            } else {
              console.log(
                '*** COMPARE: UGUALI !!!!! lastid',
                user.lastid_newstosent,
                'idsent',
                id_newstosent.toString()
              );
            }
          }
        } catch (e) {
          const msgerr = 'Error LOOP sendEmail_Newsletter_Events: ' + e;
          console.error(msgerr);
          await telegrambot.sendMsgTelegramToTheManagers(idapp, msgerr);
        }
      }

      await Newstosent.endJob(id_newstosent);
      await Newstosent.processingJob(id_newstosent, false);
      let msgfine = 'FINE - sendEmail_Newsletter_Events [' + tools.getNomeAppByIdApp(idapp) + ']: ';
      msgfine += mynewsrec.numemail_sent + ' Email inviate';
      console.log(msgfine);

      await telegrambot.sendMsgTelegramToTheManagers(idapp, msgfine);
    } catch (e) {
      console.error('*** Errore su sendEmail_Newsletter: ! ', e.message);

      const activate = await Newstosent.isActivated(id_newstosent);

      if (!activate) {
        // Invio Newsletter Abortito!
        mynewsrec.error_job =
          'Invio Newsletter abortito alle ore ' + new Date().toDateString() + new Date().toTimeString();
        await telegrambot.sendMsgTelegramToTheManagers(idapp, mynewsrec.error_job);
        await mynewsrec.save();
        await Newstosent.processingJob(id_newstosent, false);
        console.log("*** L'Invio della Newsletter è stato fermato ! ");
        return false;
      }
    }
  },

  checkifSentNewsletter: async function (idapp) {
    // Check if is the time to send the Newsletter

    return await Newstosent.findNewsletter_To_Send(idapp).then((rec) => {
      if (rec) this.sendNewsletter(rec, idapp);
    });
  },
  checkifPendingNewsletter: async function (idapp) {
    // Check if is the time to send the Newsletter
    // Only newsletter pending en 8 hour last email sent.

    return await Newstosent.findNewsletterPending_To_Send(idapp).then((rec) => {
      //
      this.sendNewsletter(rec, idapp);
    });
  },

  sendNewsletter: async function (rec, idapp) {
    if (rec) {
      // Start the job
      let myjobnews = await Newstosent.findOne({ _id: rec._id });
      if (!!myjobnews) {
        myjobnews.starting_job = true;
        myjobnews.datestartJob = new Date();

        myjobnews
          .save()
          .then(async (ris) => {
            await this.sendEmail_Newsletter_Events('it', idapp, rec._id);
          })
          .catch((e) => {
            console.error(e.message);
          });
      }
    }
  },

  testemail: async function (idapp, lang, previewonly) {
    const myarrevents = await MyEvent.getLastEvents(idapp);
    const myemail = await Settings.getValDbSettings(idapp, 'EMAIL_TEST');
    if (myemail) {
      let mylocalsconf = {
        idapp,
        locale: lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        arrevents: myarrevents,
        name: 'TestNome',
        surname: 'TestCognome',
        username: await User.getUsernameByEmail(idapp, myemail),
        emailto: myemail,
        baseurl: tools.getHostByIdApp(idapp),
        hashemail: tools.getHash(myemail),
      };

      console.log('myarrevents');
      console.table(mylocalsconf.arrevents);

      mylocalsconf.dataemail = await this.getdataemail(idapp);

      (mylocalsconf.dataemail.subject =
        mylocalsconf.dataemail && mylocalsconf.dataemail.templ ? mylocalsconf.dataemail.templ.subject : ''),
        this.replacefields(mylocalsconf);

      const smtpTransport = this.getTransport(mylocalsconf);

      console.log('-> Invio Email TEST a', mylocalsconf.emailto, 'previewonly', previewonly);
      return await this.sendEmail_base(
        idapp, 
        'newsletter/' + lang,
        mylocalsconf.emailto,
        mylocalsconf,
        '',
        smtpTransport,
        previewonly
      );
    }
  },

  sendEmail_byTemplate: async function (idapp, userto, previewonly, emailto, templemail_id, test) {
    // const myarrevents = await MyEvent.getLastEvents(idapp);
    const myemail = emailto;
    if (myemail) {
      let mylocalsconf = {
        idapp,
        locale: userto.lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        name: userto.name,
        surname: userto.surname,
        emailto: myemail,
        baseurl: tools.getHostByIdApp(idapp),
        hashemail: tools.getHash(myemail),
      };

      if (test) {
        mylocalsconf.emailto = await Settings.getValDbSettings(idapp, 'EMAIL_TEST');
      }

      mylocalsconf.dataemail = await this.getdataemail(idapp, templemail_id);

      this.replacefields(mylocalsconf);

      mylocalsconf.subject = mylocalsconf.dataemail.templ.subject;

      const smtpTransport = this.getTransport(mylocalsconf);

      console.log('-> Invio Email ' + mylocalsconf.subject + ' a', mylocalsconf.emailto, 'in corso...');
      const risult = await this.sendEmail_base(
        idapp, 
        'newsletter/' + userto.lang,
        mylocalsconf.emailto,
        mylocalsconf,
        '',
        smtpTransport,
        previewonly
      );
      // console.log('   ...email inviata?', risult);

      return risult;
    }

    return false;
  },

  testemailHtml: async function (idapp, lang, email, myuser) {
    let mytitle = 'Prova msg';
    let messaggio =
      '<br><b>Ciao!</b><div>Come stai?</div><br>Tutto Bene?<br><a href="https://ayni.gifteconomy.app/">Prova Link</a><br><i>Corsivo</i></i>&nbsp;';

    /*const htmlToText = require('html-to-text');

    messaggio = htmlToText.fromString(messaggio, {
      wordwrap: 80,
      preserveNewlines: true,
      singleNewLineParagraphs: true
    });
    */

    return await this.sendEmail_ByText(lang, email, myuser, idapp, {
      emailbody: messaggio,
      emailtitle: mytitle,
    });
  },
};
