#include "client/gui/GameChatGui.h"

#include "blitz/misc/Easing.h"
#include "blitz/misc/Format.h"
#include "blitz/misc/Log.h"
#include "client/display/InputManager.h"
#include "client/gui/ColorFulText.h"
#include "client/gui/GuiWidget.h"
#include <client/Client.h>
#include <imgui.h>
#include <string>

namespace blitz {
namespace gui {

static const float ChatFadeTime = 2.0f;

GameChatGui::GameChatGui(GuiWidget* parent, Client* client) : GuiWidget(parent, client) {
	m_Client->BindListener(this);
	InputBuf[0] = '\0';
}

void GameChatGui::Draw(const char* title, bool* p_open) {
	HistoryPos = -1;
	static float chat_width = 620.0f;
	static float chat_height = 450.0f;
	static float chatInput_width = 590.0f;
	ImGui::SetNextWindowPos(ImVec2(0, ImGui::GetIO().DisplaySize.y - 2 * chat_height));
	ImGui::SetNextWindowSize(ImVec2(chat_width, chat_height));
	// const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
	ImGui::Begin(title, p_open, GetWindowFullScreenFlags());
	{
		ImGuiInputTextFlags input_text_flags = ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_EscapeClearsAll;

		if (m_FocusRequested) {
			ImGui::SetKeyboardFocusHere(0);
			m_FocusRequested = false;
		}

		for (const auto& line : m_Lines) {
			RenderColorfulText(line, 1);
		}

		const static ImVec4 chatColorInputText = {1.0f, 0.0f, 0.0f, 0.27f};
		ImGui::SetNextItemWidth(chatInput_width);
		ImGui::PushStyleColor(ImGuiCol_FrameBg, chatColorInputText);
		if (ImGui::InputText(" ", InputBuf, IM_ARRAYSIZE(InputBuf), input_text_flags) && InputBuf[0] != '\0') {
			m_Client->SendChatText(InputBuf);
			InputBuf[0] = '\0';
		}

		if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
			ImGui::SetScrollHereY(1.0f);
		ScrollToBottom = false;

		ImGui::PopStyleColor();
	}

	ImGui::End();
}

void GameChatGui::DrawMini(const char* title, bool* p_open) {
	static float chat_width = 620.0f;
	static float chat_height = 225.0f;
	ImGui::SetNextWindowPos(ImVec2(0.0f, ImGui::GetIO().DisplaySize.y - 3.5f * chat_height));
	ImGui::SetNextWindowSize(ImVec2(chat_width, chat_height));
	ImGui::Begin(title, p_open, GetWindowFullScreenFlags() | ImGuiWindowFlags_NoNav);
	{
		for (const auto& line : m_TempLines) {
			RenderColorfulText(line, utils::EaseOutCubic(m_ChatDisplay / ChatFadeTime));
		}

		if (ScrollToBottom || (AutoScroll && ImGui::GetScrollY() >= ImGui::GetScrollMaxY()))
			ImGui::SetScrollHereY(1.0f);
		ScrollToBottom = false;
	}
	ImGui::End();
}

void GameChatGui::Render() {
	if (!m_Client->IsConnected())
		return;

	static bool showCHAT = false;

	m_ChatDisplay = std::max(0.0f, m_ChatDisplay - ImGui::GetIO().DeltaTime);
	if (m_ChatDisplay == 0) {
		m_TempLines.clear();
	}

	if (ImGui::IsKeyPressed(ImGuiKey_Enter)) {
		showCHAT = true;
		m_FocusRequested = true;
		InputManager::GrabMouse(false);
	} else if (ImGui::IsKeyPressed(ImGuiKey_Escape) && showCHAT) {
		showCHAT = false;
		ImGui::GetIO().ClearInputKeys();
		InputManager::GrabMouse(true);
	}

	if (showCHAT) {
		Draw("Chat BLITZ", nullptr);
	} else if (m_ChatDisplay > 0) {
		DrawMini("Mini Chat BLITZ", nullptr);
	}
}

void GameChatGui::OnTextChatReceived(const protocol::ColoredText& text) {
	// rajouter des lignes dans le chat
	m_Lines.push_back(text);
	m_ChatDisplay = ChatFadeTime;
	m_TempLines.push_back(text);
}

}  // namespace gui
}  // namespace blitz
