const express = require('express');
const app = express();
const bodyparser = require('body-parser');
const session = require('express-session');
const ejs = require('ejs');
const passport = require('passport');
const { Strategy } = require('passport-discord');

module.exports.load = async (client) => {
	app.use(bodyparser.json());
	app.use(bodyparser.urlencoded({ extended: true }));
	app.engine('html', ejs.renderFile);
	app.set('view engine', 'ejs');
	app.set('views', "./views");
	app.use(express.static("./public"));
	app.use(session({
		secret: 'BotDashboardExample101',
		resave: false,
		saveUninitialized: false,
	}));

	app.use(async function(req, res, next) {
		req.client = client;
		next();
	});

	app.use(passport.initialize());
	app.use(passport.session());

	passport.serializeUser((user, done) => {
		done(null, user);
	});
	passport.deserializeUser((obj, done) => {
		done(null, obj);
	});

	passport.use(new Strategy({
		clientID: process.env.CLIENT_ID,
		clientSecret: process.env.CLIENT_SECRET,
		callbackURL: process.env.CALLBACK_URL,
		scope: [ 'identify', 'guilds' ],
	}, function(accessToken, refreshToken, profile, done) {
		process.nextTick(function() {
			return done(null, profile);
		});
	}));

	app.use('/', require('./routes/index'));
	// app.use('/dashboard', require('./routes/dashboard'));
	// app.use('/appeal', require('./routes/appeal'));

	app.get('*', (req, res) => {
		res.render('../views/404', {
			bot: req.client,
			user: req.user,
		});
	});

	app.listen(process.env.PORT, () => {
		console.log(`Web Server now online on port ${process.env.PORT} | Dashboard: http://localhost:${process.env.PORT}/`);
	});
};