import dotenv from 'dotenv';
import https from 'https';
import passport from 'passport';
import FacebookStrategy from 'passport-facebook';
import { UserRole } from '../types/serverTypes.js';
import { convertUrlParamsToAppPath } from '../utils/urlParamPassthrough.js';
import runRegistrationAuthProvider, { runLoginAuthProvider } from './runAuthProvider.js';
import { newAccountsDisabled } from './newAccountsDisabled.js';
https.globalAgent.options.rejectUnauthorized = false;
dotenv.config();

const landingUri = process.env.LANDING_URI || 'http://localhost:3000';

// Refer to the auth/README.md for more details on how this works
export default (app, failureRedirect, successRedirect) => {
  const FACEBOOK_APP_ID = process.env.FACEBOOK_APP_ID;
  const FACEBOOK_APP_SECRET = process.env.FACEBOOK_APP_SECRET;
  const FACEBOOK_CALLBACK_URL = process.env.SERVER_URI + '/oauth2/redirect/facebook';

  passport.use(
    'facebook-signup',
    new FacebookStrategy(
      {
        clientID: FACEBOOK_APP_ID,
        clientSecret: FACEBOOK_APP_SECRET,
        callbackURL: FACEBOOK_CALLBACK_URL,
        profileFields: ['id', 'displayName', 'email'],
      },
      async (accessToken, refreshToken, profile, done) => {
        return await runRegistrationAuthProvider('facebook', profile, done);
      }
    )
  );

  passport.use(
    'facebook-login',
    new FacebookStrategy(
      {
        clientID: FACEBOOK_APP_ID,
        clientSecret: FACEBOOK_APP_SECRET,
        callbackURL: FACEBOOK_CALLBACK_URL,
        profileFields: ['id', 'displayName', 'email'],
      },
      async (accessToken, refreshToken, profile, done) => {
        return await runLoginAuthProvider('facebook', profile, done);
      }
    )
  );

  app.get(
    '/auth/facebook',
    (req, res, next) => {
      const projectId = req.query.project_id;
      req.session.failure_redirect = null;
      if (projectId) {
        req.session.login_redirect = convertUrlParamsToAppPath(successRedirect, { projectId });
      }
      const backToLanding = req.query.back_to_landing;
      if (!!backToLanding) {
        req.session.login_redirect = `${landingUri}/logged-in`;
        req.session.failure_redirect = `${landingUri}/logged-in`;
      }
      req.session.auth_type = 'login';
      next();
    },
    passport.authenticate('facebook-login', { scope: ['email'] })
  );

  app.get(
    '/auth/facebook/signup',
    (req, res, next) => {
      if (newAccountsDisabled) {
        return res.status(403).send('Error: New accounts are disabled.');
      }
      const projectId = req.query.project_id;
      req.session.failure_redirect = null;
      if (projectId) {
        req.session.login_redirect = convertUrlParamsToAppPath(successRedirect, { projectId });
      }
      const backToLanding = req.query.back_to_landing;
      if (!!backToLanding) {
        req.session.login_redirect = `${landingUri}/logged-in`;
      }
      req.session.auth_type = 'signup';
      next();
    },
    passport.authenticate('facebook-signup', { scope: ['email'] })
  );

  app.get(
    '/oauth2/redirect/facebook',
    (req, res, next) => {
      res.locals.login_redirect = req.session.login_redirect;
      res.locals.failure_redirect = req.session.failure_redirect;
      next();
    },
    (req, res, next) => {
      if (req.session.auth_type === 'signup') {
        passport.authenticate('facebook-signup', {
          scope: ['email'],
          failureRedirect: res.locals.failure_redirect || failureRedirect,
          failureMessage: true,
        })(req, res, next);
      } else {
        passport.authenticate('facebook-login', {
          scope: ['email'],
          failureRedirect: `${res.locals.failure_redirect || failureRedirect}?notregistered=true`,
          failureMessage: true,
        })(req, res, next);
      }
    },
    (req, res) => {
      if (req.isAuthenticated() && req.user.role !== UserRole.Waitlist) {
        const redirectUri = res.locals.login_redirect;
        if (redirectUri) {
          res.redirect(redirectUri);
        } else {
          res.redirect(successRedirect);
        }
      } else {
        res.redirect(res.locals.failure_redirect || failureRedirect);
      }
    }
  );
};
