#include "client/config/BlitzConfig.h"

#include "blitz/misc/Log.h"
#include "imgui.h"
#include <fstream>
#include <nlohmann/json.hpp>

using json = nlohmann::json;

namespace blitz {

BlitzConfig::BlitzConfig() {
	LoadConfig();
}

BlitzConfig::~BlitzConfig() {
	SaveConfig();
}

void BlitzConfig::LoadConfig() {
	std::ifstream file{"settings.json"};

	LoadDefaultConfig();

	if (!file) {
		utils::LOG("[BlitzConfig] Could not load config !");
		return;
	}

	try {
		json jsonInput;
		file >> jsonInput;

		std::string pseudo;
		jsonInput.find("pseudo");
		jsonInput.at("pseudo").get_to<std::string>(pseudo);
		std::memcpy(m_Pseudo.data(), pseudo.data(), pseudo.size() + 1);
		jsonInput.at("vsync").get_to<bool>(m_VSync);
		jsonInput.at("fps").get_to<bool>(m_DisplayFps);
		jsonInput.at("sensitivity").get_to<float>(m_MouseSpeed);
		jsonInput.at("gravity").get_to<float>(m_ServerConfig.Gravity);
		jsonInput.at("firingrate").get_to<int>(m_ServerConfig.FiringRate);
		jsonInput.at("keys").get_to<Keybinds>(m_Keybinds);

		utils::LOG("[BlitzConfig] Restored config !");
	} catch (std::exception&) {
		utils::LOGE("[BlitzConfig] Failed to load config !");
	}
}

void BlitzConfig::LoadDefaultConfig() {
	m_DisplayFps = false;
	m_VSync = true;
	const char defaultPseudo[] = "Pseudo";
	std::memcpy(m_Pseudo.data(), defaultPseudo, sizeof(defaultPseudo));
	m_MouseSpeed = 0.0025f;
	m_ServerConfig.Gravity = 20.0f;
	m_ServerConfig.FiringRate = 60;
	m_Keybinds = {ImGuiKey_Z, ImGuiKey_S, ImGuiKey_D, ImGuiKey_Q, ImGuiKey_P};
}

void BlitzConfig::SaveConfig() {
	std::ofstream file{"settings.json"};

	if (!file) {
		utils::LOGE("[BlitzConfig] Could not save config !");
	}

	json jsonOutput = {
		{"pseudo", GetPseudo().data()},
		{"vsync", IsVSyncEnabled()},
		{"fps", IsFPSDisplayEnabled()},
		{"sensitivity", GetMouseSpeed()},
		{"gravity", GetServerConfig().Gravity},
		{"firingrate", GetServerConfig().FiringRate},
		{"keys", GetKeys()},
	};

	file << jsonOutput;
}

}  // namespace blitz
