
#include "cpp-httplib/httplib.h"

#include "files.hpp"
#include "contact.hpp"

#include <fstream>
#include <iostream>
#include <string>
#include <format>
#include <regex>

const std::string DATA_INDEX = Files::load("../static/index.html");
const std::string DATA_ERROR = Files::load("../static/error.html");
const std::string PATH_LIGHT = "/static/css/light.css";
const std::string PATH_DARK = "/static/css/dark.css";

httplib::Server svr;

std::string get_theme(const httplib::Request& req)
{
	std::string cookies = req.get_header_value("Cookie");
	return regex_search(cookies, std::regex("(^|;) *theme=light")) ? PATH_LIGHT : PATH_DARK;
}

struct page_handler
{
	std::string path;

	page_handler(std::string path) : path(path) {}

	void operator()(const httplib::Request& req, httplib::Response& res)
	{
		std::string data_content = Files::load(path);
		std::string page = std::vformat(DATA_INDEX, std::make_format_args(get_theme(req), data_content));
		res.set_content(page, "text/html");
	}
};

struct theme_handler
{
	std::string theme;
	std::string content;

	theme_handler(std::string theme, std::string content) : theme(theme), content(content) {}

	void operator()(const httplib::Request& req, httplib::Response& res)
	{
		res.set_header("Set-Cookie", std::format("theme={}; Path=/; SameSite=Strict; HttpOnly; Max-Age=31536000", theme));
		res.set_content(content, "text/html");
	}
};

void put_contact(const httplib::Request& req, httplib::Response& res)
{
	if(!req.has_param("name") || !req.has_param("email") || !req.has_param("message"))
	{
		res.status = 400;
		res.set_content("<p>Bad request</p>", "text/html");
		return;
	}

	if(!Contact::send(req.get_param_value("name"), req.get_param_value("email"), req.get_param_value("message")))
	{
		res.status = 500;
		res.set_content("<p>Internal server error</p>", "text/html");
		return;
	}

	res.set_content("<p>Message sent. Thanks!</p>", "text/html");
}

void error_handler(const httplib::Request& req, httplib::Response& res)
{
	std::string page = std::vformat(DATA_INDEX, std::make_format_args(get_theme(req), DATA_ERROR));
	res.set_content(page, "text/html");
}

int main()
{
	if(!Contact::init())
	{
		return 1;
	}

	svr.set_mount_point("/static", "../static/public/");

	svr.Get("/", page_handler("../static/public/html/projects.html"));
	svr.Get("/projects", page_handler("../static/public/html/projects.html"));
	svr.Get("/contact", page_handler("../static/public/html/contact.html"));
	svr.Get("/about", page_handler("../static/public/html/about.html"));

	svr.Put("/contact", put_contact);

	svr.set_error_handler(error_handler);
	
	std::cout << "Listening on port 8080\n";
	svr.listen("0.0.0.0", 8080);
}

