const EventEmitter = require("events"),
	express = require("express"),
	app = express(),
	session = require("express-session"),
	bodyParser = require("body-parser"),
	partials = require("express-partials"),
	router = require("./router"),
	initServer = require("./InitFunctions/initServer");

const version = require("./package.json").version;
const DBDEvents = new EventEmitter();

class Dashboard {
	constructor(config) {
		const notSetYetAndRequired = [];

		if (!config.port) notSetYetAndRequired.push("port");
		if (!config.theme) notSetYetAndRequired.push("theme");
		if (!config.client) notSetYetAndRequired.push("client");
		if (!config.redirectUri) notSetYetAndRequired.push("redirectUri");
		if (!config.bot) notSetYetAndRequired.push("bot");
		if (!config.settings) notSetYetAndRequired.push("settings");
		if (!config.domain) notSetYetAndRequired.push("domain");
		if (notSetYetAndRequired[0]) throw new Error(`You need to define some more things: ${notSetYetAndRequired.join(", ")}.`);

		this.config = config;
		this.modules = [];
	}

	async init() {
		const config = this.config,
			modules = this.modules;

		app.use(bodyParser.urlencoded({ extended: true }));
		app.use(bodyParser.json());
		app.use(partials());

		app.use(express.static(config.theme.staticPath));
		app.use("/", express.static(config.theme.staticPath));
		app.use("/:a/", express.static(config.theme.staticPath));
		app.use("/:a/:b/", express.static(config.theme.staticPath));
		app.use("/:a/:b/:c/", express.static(config.theme.staticPath));
		app.use("/:a/:b/:c/:d/", express.static(config.theme.staticPath));

		app.set("views", config.theme.viewsPath);
		app.set("view engine", "ejs");

		const sessionData = {
			secret: config.cookiesSecret || "total_secret_cookie_secret",
			resave: true,
			saveUninitialized: true,
			cookie: {
				maxAge: 3600000,
			},
		};

		config.sessionSaveSession ? sessionData.store = config.sessionSaveSession : null;
		app.use(session(sessionData));

		const themeConfig = config.theme.themeConfig;

		app.get("*", (req, res, next) => {
			DBDEvents.emit("websiteView", req.session.user ? req.session.user : { loggedIn: false });

			next();
		});

		app.use((req, res, next) => {
			req.DBDEvents = DBDEvents;

			if (req.session.loggedInLastTime == true) {
				req.displayLoggedInInfo = true;
				req.session.loggedInLastTime = false;
			}
			if (!req.body) req.body = {};

			req.client = config.client;
			req.redirectUri = config.redirectUri;

			req.themeConfig = themeConfig;

			req.botToken = config.bot.token;
			req.guildAfterAuthorization = config.guildAfterAuthorization || {};

			req.websiteTitle = config.websiteTitle || "Discord Bot Dashboard";
			req.iconUrl = config.iconUrl || "https://www.nomadfoods.com/wp-content/uploads/2018/08/placeholder-1-e1533569576673.png";

			req.app = app;
			req.config = config;
			next();
		});

		router(app, config, themeConfig, modules);

		this.app = app;

		const sio = initServer(app, config, themeConfig, modules);

		this.server = sio.server;
		this.io = sio.io;
	}

	getApp() {
		return this.app;
	}

	useThirdPartyModule(module) {
		this.modules.push(module);
	}
}

module.exports = {
	Dashboard,
	formTypes: require("./ModuleExportsFunctions/formTypes"),
	customPagesTypes: require("./ModuleExportsFunctions/customPagesTypes"),
	DBDEvents,
	version,
};