const express = require('express')
const next = require('next')
require('dotenv').config()
const mailer = require("./src/mailer.js")

const axios = require('axios')

const { join } = require('path');
const { parse } = require('url');

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

const passport = require('passport')
const FacebookStrategy = require('passport-facebook').Strategy
const LinkedInStrategy = require('passport-linkedin-oauth2').Strategy
const bodyParser = require('body-parser');

const clePubliqueMailJet = "355697fac93fca865660734b4fdffaeb"
const clePriveMailJet = "ddecf75321ca89c09e561857b13534c8"

passport.use(new FacebookStrategy({
  clientID: process.env.NODE_ENV === 'production' ? process.env.TT_FACEBOOK_ID : process.env.FACEBOOK_ID,
  clientSecret: process.env.NODE_ENV === 'production' ? process.env.TT_FACEBOOK_SECRET : process.env.FACEBOOK_SECRET,
  callbackURL: process.env.FRONT_SERVER + "/auth/facebook/callback",
  enableProof: true,
  passReqToCallback: true
},
  function (req, token, tokenSecret, profile, done) {
    process.nextTick(function () {
      //console.log("fb verifyfunction")
      // To keep the example simple, the user's Linkedin profile is returned to
      // represent the logged-in user.  In a typical application, you would want
      // to associate the Linkedin account with a user record in your database,
      // and return that user instead.
      // console.log(token)
      // console.log(profile)

      // ! as we are in pure JWT strategie we pass token to authentify on our web services
      return done(null, token);
    });
  }
));

passport.use(new LinkedInStrategy({
  clientID: process.env.NODE_ENV === 'production' ? process.env.TT_LINKEDIN_ID : process.env.LINKEDIN_ID,
  clientSecret: process.env.NODE_ENV === 'production' ? process.env.TT_LINKEDIN_SECRET : process.env.LINKEDIN_SECRET,
  callbackURL: process.env.FRONT_SERVER + "/auth/linkedin/callback",
  //scope: ['r_emailaddress', 'r_liteprofile', 'r_basicprofile'],
  // profileFields: ['id', 'first-name', 'last-name', 'location', 'email-address', 'picture-urls::(original)'],
  passReqToCallback: true
},
  function (req, token, tokenSecret, profile, done) {
    //console.log("===linkedin verifyfunction===")
    process.nextTick(function () {
      // To keep the example simple, the user's Linkedin profile is returned to
      // represent the logged-in user.  In a typical application, you would want
      // to associate the Linkedin account with a user record in your database,
      // and return that user instead.
      //console.log(token)
      // ! as we are in pure JWT strategy we pass token to authentify on our web services
     console.log(token)
      console.log(profile)

      return done(null, token);



    });

  }
));

app.prepare()
  .then(() => {
    var jsonParser = bodyParser.json()
    // Get Express and instance of Express from NextAuth
    const server = express()

    server.use(function (req, res, next) {
      res.header("Access-Control-Allow-Origin", "*");
      res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
      next();
    });

    server.use(passport.initialize());

    server.use('/', express.static(__dirname + '/.next/'))

    server.get('/auth/facebook',
      passport.authorize('facebook', { scope: ['email', 'public_profile'], session: false, failureRedirect: 'Login' }));

    server.get('/auth/facebook/callback',
      passport.authorize('facebook', { failureRedirect: '/Login', session: false }),
      (req, res) => {


       // console.log('facebookcallback')
        //console.log(req.account)//don't understand why !
        //  console.log(req.accessToken)
        // console.log(req)

        axios.post(process.env.SERVER_URL + "/api/login_check_oauth", { 'oauth-token': req.account, 'oauth-type': 'facebook' })
          .then((resApi) => {
            console.log('$$$$$$$$$$$retreive user from token validation$$$$$$$$$$$$$$')
            console.log(resApi)
            return res.redirect('/AuthRouter?JWT=' + resApi.data.token)
          }
          ).catch(err => { console.log(err) })
      })

    server.get('/auth/linkedin',
      passport.authenticate('linkedin', { scope: ['r_basicprofile', 'r_emailaddress', 'r_liteprofile'], session: false, failureRedirect: '/Login' }));

    server.get('/auth/linkedin/callback',
      passport.authenticate('linkedin', { failureRedirect: '/Login', session: false }),
      function (req, res) {
        console.log(req)
        // if (error) {
        //  console.log(error)
        //   return res.redirect('/Login?error=' + error.message)
        // }
        // console.log('-linkedincallback')
        // console.log(req.accessToken)
        // console.log('--linkedincallback')
        // console.log(req.account)
        // console.log('---linkedincallback')
        // console.log(req)
        // console.log(token)

        axios.post(process.env.SERVER_URL + "/api/login_check_oauth", { 'oauth-token': req.user, 'oauth-type': 'linkedin' })
          .then((resApi) => {
              console.log('$$$$$$$$$$$retreive user from token validation$$$$$$$$$$$$$$')
              console.log(resApi)
            // return res.redirect('/AuthRouter?JWT=' + resApi.data.token)
            return res.redirect('/AuthRouter?JWT=' + resApi.data.token)
          }
          ).catch(err => {
            console.log(err)
          })
      });

    server.get('/Candidature/:id', (req, res) => {
      const actualPage = '/Candidature'
      const queryParams = { id: req.params.id }
      app.render(req, res, actualPage, queryParams)
    })

    server.get('/Offre/:id-:rest', (req, res) => {
      const actualPage = '/Offre'
      const queryParams = { id: req.params.id }
      app.render(req, res, actualPage, queryParams)
    })


    server.get('/Entreprise/:id-:rest', (req, res) => {
      const actualPage = '/Entreprise'
      const queryParams = { id: req.params.id }
      app.render(req, res, actualPage, queryParams)
    })

    server.get('/Reponse', (req, res) => {
      const actualPage = '/Reponse'
      const queryParams = { adId: req.query.adId, companyId:req.query.companyId }
      app.render(req, res, actualPage, queryParams)
    })

    server.get('/Player', (req, res) => {
      const actualPage = '/Player'
      const queryParams = { id: req.query.id, url: req.query.url, videoId:req.query.videoId, typeEntite:req.query.typeEntite, nameCompany:req.query.nameCompany, nameOffre:req.query.nameOffre }
      app.render(req, res, actualPage, queryParams)
    })

    server.get('/VerifyEmail/:email', (req, res) => {
      const actualPage = '/VerifyEmail'
      const queryParams = { email: req.params.email }
      app.render(req, res, actualPage, queryParams)
    })

    server.get('/ConfirmAccount/:token/:email', (req, res) => {
      const actualPage = '/ConfirmAccount'
      const queryParams = { token: req.params.token, email: req.params.email }
      app.render(req, res, actualPage, queryParams)
    })

    // server.post('/NewsletterSubscription', jsonParser, (req, res) => {
     
    //   let email = req.body.email;

    //   if (!!!email) {
    //     res.status(404).json({ success: false, message: 'Mauvais paramètre.' });
    //   }

    //   var mailjet = require('node-mailjet')
    //     .connect(process.env.MJ_APIKEY_PUBLIC, process.env.MJ_APIKEY_PRIVATE)
    //   let error = null;
    //   let mailjetResponse = mailjet.post('contact')
    //     .request({ Email: email })
    //     .then(rep => res.json({ success: true }), rep => res.json({ success: false, message: rep.message }))
    //     .catch((err) => { 
    //      });

    // })

    server.post('/NewsletterSubscription', jsonParser, (req, res) => {
     
      let email = req.body.email;

      if (!!!email) {
        res.status(404).json({ success: false, message: 'Mauvais paramètre.' });
      }
      // var mailjet = require ('node-mailjet')
      //     .connect(process.env.MJ_APIKEY_PUBLIC, process.env.MJ_APIKEY_PRIVATE)

      //     mailjet.post('contact')
      //     .request({Email: email})
      //     .catch((err)=>console.log(err));

      // res.json({success:true});
      // })
      var mailjet = require('node-mailjet')
      .connect(clePubliqueMailJet, clePriveMailJet)
      let error = null;
      console.log("envoi du contact a mailjet")
      let mailjetResponse = mailjet
        .post('contact')
        .action("managemanycontacts")
        .request({
          "Contacts":[
            {
              "Email":email,
              "IsExcludedFromCampaigns":"false",
              "Properties":"object"
            }
          ],
          "ContactsLists":[
            {
              "Action":"addforce",
              "ListID":"2400791"
            },
            
          ] 
          })
        .then(rep => res.json({ success: true }), rep => {
          console.log("success")
          res.json({ success: false, message: rep.message })
          
        })
        .catch((err) => console.log("erreur"));
      console.log("Fin envoi du contact a mailjet")
      // US technique 444
      // var mailjet2 = require('node-mailjet')
      //   .connect('805b8adce80bc6aa9422ddff20bb4171', 'f3bce955f21bc9456d65245c50e8c512')
      
      // console.log("envoi du mail avec mailjet laniau2")
      // let request = mailjet2.post("send", {'version': 'v3.1'})
      // .request({
      //   "Messages":[
      //     {
      //       "From": {
      //         "Email": "l.laniau@talentstube.com",
      //         "Name": "Laurent"
      //       },
      //       "To": [
      //         {
      //           "Email": "l.laniau@talentstube.com",
      //           "Name": "Laurent"
      //         }
      //       ],
      //       "TemplateID": 2087555,
      //       "TemplateLanguage": true,
      //       "Variables": {
      //         "prénom": "\"]]</title><!--[if !mso]><!-- --><meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\"><!--<![endif]--><meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"><meta name=\"viewport\" content=\"width=device-width,initial-scale=1\"><style type=\"text/css",
      //         "lien": '<p style="display:inline-block;background:#36eda4;color:#ffffff;font-family:Arial,sans-serif;font-size:13px;font-weight:normal;line-height:120%;margin:0;text-decoration:none;text-transform:none;padding:10px 25px;border-radius:3px"><span style="font-size:11px;text-align:center;background-color:#36eda4;color:#ffffff;font-family:Arial"><b>&nbsp; &nbsp; &nbsp; &nbsp;<a href="www.talentstube.com">Activer mon compte</a> &nbsp; &nbsp; &nbsp;</b></span></p>'
      //         },
      //       "Subject": "Test [[data:prénom:'Corentin']]",
      //       "TextPart": "My first Mailjet email",
      //       "HTMLPart": "<h3>Dear passenger 1, welcome to <a href='https://www.mailjet.com/'>Mailjet</a>!</h3><br />May the delivery force be with you!",
      //       "CustomID": "AppGettingStartedTest"
      //     }
      //   ]
      // })
      // request
      // .then((result) => {
      //   console.log(result.body)
      // })
      // .catch((err) => {
      //   console.log(err.statusCode)
      // })
      // mailer.sendTransactionnelEmail();  
      // console.log("Fin envoi du mail a mailjet")
    })

    server.post('/sendConfirmationEmail', jsonParser, (req, res) => {

      const token = req.body.confirmationToken
      const email = req.body.email
      const nom = req.body.lastname
      const prenom = req.body.firstname
      //const url = req.body.adId
      //console.log("Envoi d'email "+url)
      //TODO Ajouter le contexte de l'annonce 
      //Envoyer URL
      const tokenUrl = `${process.env.FRONT_SERVER}/ConfirmAccount/${token}/${email}`
      console.log("tokenUrl "+tokenUrl)
      mailer.sendConfirmationEmail(nom, prenom, tokenUrl, email);

      res.json({ status: 'success' });

    })

    server.get('/static/js/*.js', (req, res) => {

      const parsedUrl = parse(req.url, true);
      const { pathname } = parsedUrl;
      const filePath = join(__dirname, '.next', pathname);
      app.serveStatic(req, res, filePath);
    })

    server.get('/manifest.json', (req, res) => {

      const parsedUrl = parse(req.url, true);
      const { pathname } = parsedUrl;
      const filePath = join(__dirname, '/static/', pathname);
      app.serveStatic(req, res, filePath);
    })

    server.get('*', (req, res) => {
      return handle(req, res)
    })

    server.listen(process.env.PORT, (err) => {
      if (err) throw err
      console.log('> Ready on ' + process.env.FRONT_SERVER + ' PORT :'+ process.env.PORT)
    })

  })
  .catch((ex) => {
    console.error(ex.stack)
    process.exit(1)
  })