require('./config/config');
require('./config/config');

// console.log(" lodash");

console.log(process.versions);

const _ = require('lodash');
// console.log(" cors");
const cors = require('cors');

// console.log(" 2) fs");
const fs = require('fs');

const NUOVO_METODO_TEST = true;

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

//const throttle = require('express-throttle-bandwidth');
// app.use(throttle(1024 * 128)) // throttling bandwidth

const port = process.env.PORT;

// var cookieParser = require('cookie-parser')
// var csrf = require('csurf')
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');

const cron = require('node-cron');
console.log('Starting mongoose...');

require('./db/mongoose');

// console.log('Starting pem...');

// const pem = require('pem')

const { Settings } = require('./models/settings');

// test

const i18n = require('i18n');

let credentials = null;

// OBTAIN
// https://www.psclistens.com/insight/blog/enabling-a-nodejs-ssl-webserver-using-let-s-encrypt-pem-certificates/


if ((process.env.NODE_ENV === 'production')) {
  console.log('*** AMBIENTE DI PRODUZIONE !!!!')
} else if (process.env.NODE_ENV === 'test') {
  console.log('*** ### AMBIENTE DI TEST ')
}


console.log('DB: ' + process.env.DATABASE);
// console.log("PORT: " + port);
// console.log("MONGODB_URI: " + process.env.MONGODB_URI);

var app = express();

let telegrambot = null;

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

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

var mongoose = require('mongoose').set('debug', false);

mongoose.set('debug', false);

const { CfgServer } = require('./models/cfgserver');
const { ObjectID } = require('mongodb');

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

const printf = require('util').format;

myLoad().then(ris => {

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

  require('./models/todo');
  require('./models/project');
  require('./models/subscribers');
  require('./models/booking');
  require('./models/sendmsg');
  require('./models/sendnotif');
  require('./models/mailinglist');
  require('./models/newstosent');
  require('./models/mypage');
  require('./models/myelem');
  require('./models/bot');
  require('./models/calzoom');
  const mysql_func = require('./mysql/mysql_func');

  const index_router = require('./router/index_router');
  const push_router = require('./router/push_router');
  const newsletter_router = require('./router/newsletter_router');
  const booking_router = require('./router/booking_router');
  const dashboard_router = require('./router/dashboard_router');
  const myevent_router = require('./router/myevent_router');
  const subscribe_router = require('./router/subscribe_router');
  const sendmsg_router = require('./router/sendmsg_router');
  const sendnotif_router = require('./router/sendnotif_router');
  const email_router = require('./router/email_router');
  const todos_router = require('./router/todos_router');
  const test_router = require('./router/test_router');
  const projects_router = require('./router/projects_router');
  const report_router = require('./router/report_router');
  const users_router = require('./router/users_router');
  const reactions_router = require('./router/reactions_router');
  const mygroups_router = require('./router/mygroups_router');
  const circuits_router = require('./router/circuits_router');
  const accounts_router = require('./router/accounts_router');
  const iscrittiConacreis_router = require('./router/iscrittiConacreis_router');
  const iscrittiArcadei_router = require('./router/iscrittiArcadei_router');
  const site_router = require('./router/site_router');
  const admin_router = require('./router/admin_router');
  const products_router = require('./router/products_router');
  const cart_router = require('./router/cart_router');
  const orders_router = require('./router/orders_router');
  const myskills_router = require('./router/myskills_router');
  const mygoods_router = require('./router/mygoods_router');
  const mygen_router = require('./router/mygen_router');

  const { MyEvent } = require('./models/myevent');

  app.use(express.static('views'));

  // app.use(express.static(path.join(__dirname, 'client')));

  app.use(bodyParser.json());

  // app.set('view engine', 'pug');

  // Set static folder
  // app.use(express.static(path.join(__dirname, 'public')));

  i18n.configure({
    locales: ['it', 'enUs', 'es', 'fr', 'pt', 'si'],
    defaultLocale: 'it',
    // cookie: 'cook',
    directory: __dirname + '/locales',
    api: {
      '__': 'translate',
      '__n': 'translateN'
    },
  });

  app.use(cors({
    exposedHeaders: ['x-auth'],
  }));

  app.use(bodyParser.json());

  // app.use(express.cookieParser());
  app.use(i18n.init);

  console.log('Use Routes \...');


  // Use Routes
  app.use('/', index_router);
  app.use('/subscribe', subscribe_router);
  app.use('/sendmsg', sendmsg_router);
  app.use('/sendnotif', sendnotif_router);
  app.use('/push', push_router);
  app.use('/news', newsletter_router);
  app.use('/booking', booking_router);
  app.use('/dashboard', dashboard_router);
  app.use('/event', myevent_router);
  app.use('/email', email_router);
  app.use('/todos', todos_router);
  app.use('/test', test_router);
  app.use('/projects', projects_router);
  app.use('/users', users_router);
  app.use('/reactions', reactions_router);
  app.use('/mygroup', mygroups_router);
  app.use('/circuit', circuits_router);
  app.use('/account', accounts_router);
  app.use('/iscritti_conacreis', iscrittiConacreis_router);
  app.use('/iscritti_arcadei', iscrittiArcadei_router);
  app.use('/report', report_router);
  app.use('/site', site_router);
  app.use('/admin', admin_router);
  app.use('/products', products_router);
  app.use('/cart', cart_router);
  app.use('/orders', orders_router);
  app.use('/myskills', myskills_router);
  app.use('/mygoods', mygoods_router);
  app.use('/mygen', mygen_router);

  // catch 404 and forward to error handler
  // app.use(function (req, res, next) {
  //   var err = new Error('Not Found');
  //   err.status = 404;
  //   next(err);
  // });

  // app.set('views', path.join(__dirname, 'views'));
  // app.set('view engine', 'pug');

  // development error handler
  // will print stacktrace
  if (app.get('env') === 'development') {

    app.use(function (err, req, res, next) {
      console.log('Server Error: ', err.message);
      // console.trace();
      res.status(err.status || 500).send({ error: err.message });
      // res.render('error', {
      //   message: err.message,
      //   error: err
      // });
    });

  }

  // require('./telegram/telegrambot');

  // *** DB CONNECTIONS ***
  // mysql_func.mySqlConn_Shen.connect((err) => {
  //   if (!err)
  //     console.log('DB connection to Shen Database succeded.');
  //   else
  //     console.log('DB connection to Shen Database FAILED \n Error: ' + JSON.stringify(err, undefined, 2));
  // });

  if (process.env.NODE_ENV === 'production') {
    console.log('*** PRODUCTION! ');
  }

  if ((process.env.NODE_ENV === 'production') ||
    (process.env.NODE_ENV === 'test')) {

    const keyStream = path.resolve(`./${process.env.PATH_CERT_KEY}`);
    const certificateStream = path.resolve(`./${process.env.PATH_SERVER_CRT}`);

    const privateKey = fs.readFileSync(keyStream, "utf8");
    const certificate = fs.readFileSync(certificateStream, "utf8");


    if (NUOVO_METODO_TEST) {
      credentials = {
        key: privateKey,
        cert: certificate,
      };
    } else {
      credentials = {
        key: privateKey,
        cert: certificate,
        ca: [
          fs.readFileSync(process.env.PATH_SSL_ROOT_PEM, 'utf8'),
          fs.readFileSync(process.env.PATH_SSL_CHAIN_PEM, 'utf8'),
        ],
      };
    }

    var https = require('https');
  } else {
    if (process.env.HTTPS_LOCALHOST === "true") {
      var privateKey = fs.readFileSync(process.env.PATH_CERT_KEY, 'utf8');
      var certificate = fs.readFileSync(process.env.PATH_SERVER_CRT, 'utf8');
      credentials = {
        key: privateKey,
        cert: certificate,
        ciphers: 'ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES256-SHA384',
        honorCipherOrder: true,
        secureProtocol: 'TLSv1_2_method',
      };
      var https = require('https');

    } else {
      var http = require('http');
    }
  }

  if ((process.env.NODE_ENV === 'production') ||
    (process.env.NODE_ENV === 'test') || process.env.HTTPS_LOCALHOST === "true") {

    if (false) {
      /*pem.createCertificate({ days: 1, selfSigned: true }, (err, keys) => {
        if (err) {
          throw err
        }
        const httpsServer = https.createServer({ key: keys.clientKey, cert: keys.certificate }, (req, res) => {
          res.end('o hai!')
        }).listen(port)
      }) */
    } else {
      const httpsServer = https.createServer(credentials, app);

      console.log('httpsServer: port ', port);
      httpsServer.listen(port);
    }
  } else {
    console.log('httpServer: port ', port);
    const httpServer = http.createServer(app);
    httpServer.listen(port);
  }

  mystart();

});

// app.use(throttle(1024 * 128)); // throttling bandwidth

// app.use((req, res, next) => {
//   res.header('Access-Control-Allow-Origin', '*')
//   res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept')
//   next()
// });

async function myLoad() {

  return tools.loadApps();
}

async function mystart() {

  // await estraiTutteLeImmagini();

  await tools.getApps();

  if (process.env.PROD !== 1) {

    testmsgwebpush();

    // tools.sendNotifToAdmin('Riparti', 'Riparti');

    let miapass = '';

    if (miapass !== '') {
      let crypt = tools.cryptdata(miapass);
      let decrypt = tools.decryptdata(crypt);

      console.log('crypted:', crypt);
      console.log('decrypted:', decrypt);
    }

    if (!process.env.DEBUG) {
      mycron();
    }
  }


  telegrambot = require('./telegram/telegrambot');

  await inizia();

  await resetProcessingJob();

  populate.popolaTabelleNuove();

  faitest();

  // ----------------- MAILCHIMP -----
  const querystring = require('querystring');
  const mailchimpClientId = 'xxxxxxxxxxxxxxxx';

  app.get('/mailchimp/auth/authorize', function (req, res) {
    res.redirect('https://login.mailchimp.com/oauth2/authorize?' +
      querystring.stringify({
        'response_type': 'code',
        'client_id': mailchimpClientId,
        'redirect_uri': 'http://127.0.0.1:3000/mailchimp/auth/callback',
      }));
  });

}

// -----------------

function populateDBadmin() {
  const cfgserv = [
    {
      _id: new ObjectID(),
      idapp: '9',
      chiave: 'vers',
      userId: 'ALL',
      valore: '0.1.2',
    }];

  let cfg = new CfgServer(cfgserv[0]).save();
}

function mycron() {

  const sendemail = require('./sendemail');

  for (const app of tools.getApps()) {
    sendemail.checkifPendingNewsletter(app.idapp);
    sendemail.checkifSentNewsletter(app.idapp);

  }
}

async function mycron_30min() {
  for (const app of tools.getApps()) {
    let enablecrontab = false;

    enablecrontab = await Settings.getValDbSettings(app.idapp,
      tools.ENABLE_CRONTAB, false);

    if (enablecrontab) {
      // ...
    }
  }
}

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

  // console.log('nomeapp 1: ' , tools.getNomeAppByIdApp(1));
  // console.log('nomeapp 2: ' , tools.getNomeAppByIdApp(2));

  User.find({ username: 'paoloar77', idapp: '1' }).then(async (arrusers) => {
    if (arrusers !== null) {
      for (const user of arrusers) {
        await tools.sendNotificationToUser(user._id, 'Server',
          'Il Server è Ripartito', '/', '', 'server', []).then(ris => {
            if (ris) {

            } else {
              // already sent the error on calling sendNotificationToUser
            }
          });
      }
    }
  });

}

// Cron every X minutes
cron.schedule('*/2 * * * *', () => {
  // console.log('Running Cron Job');
  if (!process.env.DEBUG) {
    mycron();
  }
});

// Cron every X minutes
cron.schedule('*/60 * * * *', async () => {
  if (!process.env.DEBUG) {
    mycron_30min();
  }
});

// mycron_30min();

// tools.writelogfile('test', 'prova.txt');

async function resetProcessingJob() {

  const { Newstosent } = require('./models/newstosent');

  arrrec = await Newstosent.find({});

  for (const rec of arrrec) {
    rec.processing_job = false;
    await Newstosent.findOneAndUpdate({ _id: rec.id }, { $set: rec }, { new: false }).
      then((item) => {

      });
  }
}

//app.listen(port, () => {
//  console.log(`Server started at port ${port}`);
//});

async function inizia() {

  try {

    if (process.env.NODE_ENV === 'development') {
      await telegrambot.sendMsgTelegram(tools.FREEPLANET,
        telegrambot.ADMIN_USER_SERVER,
        `Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}!`);

      await telegrambot.sendMsgTelegramByIdTelegram(tools.FREEPLANET,
        telegrambot.ADMIN_IDTELEGRAM_SERVER,
        `Ciao ${telegrambot.ADMIN_USER_NAME_SERVER}\n` +
        `🔅 Il Server ${process.env.DATABASE} è appena ripartito!`);

    } else {

      await telegrambot.sendMsgTelegramToTheAdminAllSites(`Ciao Admin\n` + `🔅🔅🔅 Il Server col BOT di {appname} è appena ripartito!`, false);

    }

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

    await Circuit.setDeperimentoOff();

     */



  } catch (e) {

  }

}

//

// telegrambot.sendMsgTelegramToTheManagers('7', 'PROVAAA!');

// if (process.env.PROD !== 1) {
//   const reg = require('./reg/registration');
//   const link = reg.getlinkregByEmail('7', 'tomasihelen@dasdasgmail.comAAAA' , 'HelenTomasidasdasd');
//   const link2 = reg.getlinkregByEmail('7', 'tomasihelen@gmail.com' , 'HelenTomasi');
//   //const link2 = reg.getlinkregByEmail('7', 'elenaliubicich@gmail.com' , 'Elenaliu');
//
//   console.log(link);
//   console.log(link2);
// }

async function estraiImmagini(table) {
  const { User } = require('./models/user');

  let idapp = '13';

  let arrlist;

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


  const mytable = globalTables.getTableByTableName(table);
  if (!mytable)
    return;

  console.log('INIZIO - estraiImmagini', table);

  arrlist = await mytable.find({ idapp }).lean();

  let file = '';
  let filetocheck = '';
  let dirmain = '';
  let filefrom = '';
  let filefrom2 = '';
  let dir = tools.getdirByIdApp(idapp) + dirmain + '/upload/';

  try {
    if (!tools.sulServer()) {
      dirmain = '/public';
    }

    for (const rec of arrlist) {
      const myuser = await User.findOne({ idapp, _id: rec.userId }).lean();
      if (myuser) {
        const myphotos = rec.photos;

        if (myphotos.length > 0) {
          let folderprof = dir + 'profile/' + myuser.username;

          try {
            // console.log('checkdir', folderprof);
            if (!fs.existsSync(folderprof)) {
              console.log('*** Creadir', folderprof);
              fs.mkdirSync(folderprof);
            }

            folderprof = dir + 'profile/' + myuser.username + '/' + table;
            // console.log('checkdir', folderprof);
            if (!fs.existsSync(folderprof)) {
              console.log('creadir', folderprof);
              fs.mkdirSync(folderprof);
            }
          } catch (e) {

          }
        }

        for (const photo of myphotos) {

          if (photo.imagefile) {
            file = dir + 'profile/' + myuser.username + '/' + table + '/' +
              photo.imagefile;
            filefrom = dir + 'profile/undefined/' + table + '/' + photo.imagefile;
            filefrom2 = dir + 'profile/' + myuser.username + '/' + photo.imagefile;

            // console.log('file', file);
            // console.log('filefrom', filefrom);

            if (!tools.isFileExists(file)) {
              // non esiste
              console.log('non esiste', file);
              console.log('   filefrom', filefrom);
              console.log('   filefrom2', filefrom2);
            }

            if (!tools.isFileExists(file) && tools.isFileExists(filefrom)) {
              console.log('@@@@@@  copia file:', filefrom, 'a', file);
              tools.copy(filefrom, file);
            }
            if (!tools.isFileExists(file) && tools.isFileExists(filefrom2)) {
              console.log('@@@@@@  copia file 2:', filefrom2, 'a', file);
              tools.copy(filefrom2, file);
            }
          }
        }
      }
    }
    console.log('FINE - estraiImmagini', table);
  } catch (e) {
    console.error('e', e);
  }
}

async function estraiTutteLeImmagini() {

  await estraiImmagini('myskills');
  await estraiImmagini('mygoods');
  await estraiImmagini('mybachecas');
}

async function faitest() {
  // console.log('Fai Test:')

  const testfind = false;

  // const $vers = tools.getVersionint('1.92.45');

  if (true) {
    // tools.execScript("ls -la");
  }

  if (false) {
    prova = tools.removeAtChar('@prova');
  }

  if (false) {
    const prova = tools.getConfSiteOptionEnabledByIdApp('13', shared_consts.ConfSite.Notif_Reg_Push_Admin);
    console.log('prova', prova);
  }

  if (testfind) {
    const { City } = require('./models/city');

    let miacity = 'roma';
    const ris = await City.findByCity(miacity);

    console.log('ris', ris);
  }

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

  if (false) {
    let myuser = await User.findOne({
      idapp: '1',
      username: 'paoloar77',
    });

    const langdest = 'it';

    telegrambot.askConfirmationUser(myuser.idapp, shared_consts.CallFunz.REGISTRATION, myuser);

  }

  if (false) {

    const user = await User.findOne({
      idapp: 12,
      username: 'paolotest1',
    });

    await sendemail.sendEmail_Registration('it', 'paolo@arcodiluce.it', user,
      '12', '');

  }

  if (false) {

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

    const idapp = tools.FREEPLANET;
    const idreg = 0;

    try {

      const user = await User.findOne({
        idapp,
        username: 'paoloar773',
      });

      user.aportador_solidario = 'paoloar77';

      let mylocalsconf = {
        idapp,
        dataemail: null,
        locale: user.lang,
        nomeapp: tools.getNomeAppByIdApp(idapp),
        strlinksito: tools.getHostByIdApp(idapp),
        strlinkreg: '',
        username: user.username,
        name: user.name,
        surname: user.surname,
        forgetpwd: tools.getHostByIdApp(idapp) + '/requestresetpwd',
        emailto: '',
        user,
      };

      await telegrambot.notifyToTelegram(telegrambot.phase.REGISTRATION,
        mylocalsconf);
    } catch (e) {
      console.log('error ' + e);
    }
  }
}

module.exports = { app };

