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');

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, videoId:req.query.videoId, type:req.query.type }
      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/:url', (req, res) => {
      const actualPage = '/ConfirmAccount'
      const queryParams = { token: req.params.token, email: req.params.email, url: req.params.url }
      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('/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)
  })