#include "TargetInfo.h"

#include "Utils/PlayerUtils.h"
#include "Utils/TimeUtils.h"
#include "Utils/MathUtils.h"
#include "Utils/ImGuiRenderUtils.h"
#include "Utils/ColorUtils.h"

#include "Mod/Interface.h"

auto TargetInfo::onAttack(Actor& actor) -> void {
	Player* target = (Player*)&actor;
	if (!target) return;

	for (Player* player : list) {
		if (player == target) {
			lastplayer.name = Utils::String::removeSymbols(Utils::String::removeToEscape(player->getLocalNameTag()));
			lastplayer.health = Utils::Players::getHealth(player);
			lastplayer.absorption = Utils::Players::getAbsorption(player);

			lasthit = Utils::Time::getMs();
		}
	}
}

auto TargetInfo::onImGuiRender() -> void {
	auto clientinstance = Client::clientinstance;
	if (!clientinstance) return;

	auto localplayer = clientinstance->getLocalPlayer();
	if (!localplayer) return;

	auto interfaceMod = Client::findMod<Interface>(_("Interface"));

	long long now = Utils::Time::getMs();

	bool closeor = now - lasthit >= 3000.f;
	if (Client::screenName == _("chat_screen")) {
		closeor = false;
		lastplayer.name = localplayer->getLocalNameTag();
		lastplayer.health = Utils::Players::getHealth(localplayer);
		lastplayer.absorption = Utils::Players::getAbsorption(localplayer);
	}

	static float animation = 0.f;
	animation = Utils::Math::animate(closeor ? 0.f : 1.f, animation, Client::deltaTime * (closeor ? 4.f : 6.f));

	switch (style) {
	case 0: {

		Utils::ImGuiRender::setSize(1.4f * animation);
		Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[(bold ? 1 : 0) + (4 * interfaceMod->font)]);

		ImVec4 rect = ImVec4(
			pos.x - (((Utils::ImGuiRender::getTextSize(_("Name: ") + lastplayer.name).x * animation) / 2) + 50.f),
			pos.y - (40.f * animation),
			pos.x + ((Utils::ImGuiRender::getTextSize(_("Name: ") + lastplayer.name).x * animation) / 2) + 50.f,
			pos.y + (40.f * animation)
		);

		Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 0.4f * animation));
		Utils::ImGuiRender::setRound(15.f);

		Utils::ImGuiRender::setBlurStreangth(blurs);
		Utils::ImGuiRender::fillBlurRectangle(rect);

		Utils::ImGuiRender::fillRectangle(rect);

		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 1.f * animation));
		Utils::ImGuiRender::setSize(50.f);
		Utils::ImGuiRender::setThickness(400.f);
		Utils::ImGuiRender::fillShadowRectangle(rect);

		ImVec4 headrect = ImVec4(
			rect.x + (7.5f * animation),
			rect.y + (7.5f * animation),
			rect.x + ((rect.w - rect.y) - (7.5f * animation)),
			rect.w - (7.5f * animation)
		);
		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 1.f * animation));
		Utils::ImGuiRender::fillRectangle(headrect);

		ImVec2 namepos = ImVec2(headrect.z + 5.f, headrect.y + 5.f);
		Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f * animation));
		Utils::ImGuiRender::setSize(1.4f * animation);
		Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[(bold ? 1 : 0) + (4 * interfaceMod->font)]);
		Utils::ImGuiRender::drawText(_("Name: "), namepos);

		Utils::ImGuiRender::setColor(Utils::Color::getColor(3.f, 0, 1.f * animation));

		namepos.x += Utils::ImGuiRender::getTextSize(_("Name: ")).x;
		Utils::ImGuiRender::drawText(lastplayer.name, namepos);

		std::stringstream ss;
		ss.precision(0);
		ss << std::fixed << ((lastplayer.health / 2) + (lastplayer.absorption / 2));

		Utils::ImGuiRender::setSize(1.1f * animation);
		ImVec2 hpsize = Utils::ImGuiRender::getTextSize(ss.str());
		Utils::ImGuiRender::setSize(1.4f * animation);
		ImVec2 namesize = Utils::ImGuiRender::getTextSize(_(""));
		ImVec4 hprect = ImVec4(
			headrect.z + (5.f * animation),
			namepos.y + Utils::ImGuiRender::getTextSize(_("")).y + (5.f * animation) + (4.f * animation),
			headrect.z + (((rect.z - rect.x) - (headrect.z - headrect.x)) - ((10.f * animation) + hpsize.x)) - (20.f * animation),
			namepos.y + Utils::ImGuiRender::getTextSize(_("")).y + (5.f * animation) + (hpsize.y * animation) - (4.f * animation)
		);
		ImVec2 hppos = ImVec2(
			hprect.z + (5.f * animation),
			namepos.y + Utils::ImGuiRender::getTextSize(_("")).y + (5.f * animation)
		);
		Utils::ImGuiRender::fillRectangle(hprect);
		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 1.f * animation));
		Utils::ImGuiRender::setSize(50.f);
		Utils::ImGuiRender::setThickness(100.f);
		Utils::ImGuiRender::fillShadowRectangle(hprect);

		Utils::ImGuiRender::setColor(Utils::Color::getColor(3.f, 0, 1.f * animation));


		Utils::ImGuiRender::setSize(1.1f * animation);

		Utils::ImGuiRender::drawText(ss.str(), hppos);
		break;
	}
	case 1: {

		Utils::ImGuiRender::setSize(1.4f * animation);
		Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[(bold ? 1 : 0) + (4 * interfaceMod->font)]);

		ImVec4 rect = ImVec4(
			pos.x - (((Utils::ImGuiRender::getTextSize(lastplayer.name).x * animation) / 2) + (50.f * animation)),
			pos.y - (40.f * animation),
			pos.x + ((Utils::ImGuiRender::getTextSize(lastplayer.name).x * animation) / 2) + (50.f * animation),
			pos.y + (40.f * animation)
		);

		Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 0.4f * animation));
		Utils::ImGuiRender::setRound(15.f);

		Utils::ImGuiRender::setBlurStreangth(blurs);
		Utils::ImGuiRender::fillBlurRectangle(rect);

		Utils::ImGuiRender::fillRectangle(rect);

		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 1.f * animation));
		Utils::ImGuiRender::setSize(50.f);
		Utils::ImGuiRender::setThickness(400.f);
		Utils::ImGuiRender::fillShadowRectangle(rect);

		ImVec4 headrect = ImVec4(
			rect.x + (7.5f * animation),
			rect.y + (7.5f * animation),
			rect.x + ((rect.w - rect.y) - (7.5f * animation)),
			rect.w - (7.5f * animation)
		);
		
		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 1.f * animation));
		Utils::ImGuiRender::fillRectangle(headrect);

		ImVec2 namepos = ImVec2(headrect.z + 5.f, headrect.y + 5.f);
		Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f * animation));
		Utils::ImGuiRender::setSize(1.3f * animation);
		Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[(bold ? 1 : 0) + (4 * interfaceMod->font)]);

		Utils::ImGuiRender::drawText(lastplayer.name, namepos);

		std::stringstream ss;
		ss.precision(0);
		ss << std::fixed << ((lastplayer.health / 2) + (lastplayer.absorption / 2)) << _(" HP");

		Utils::ImGuiRender::setSize(1.1f * animation);
		ImVec2 hpsize = Utils::ImGuiRender::getTextSize(ss.str());
		Utils::ImGuiRender::setSize(1.3f * animation);
		ImVec2 namesize = Utils::ImGuiRender::getTextSize(_(""));
		ImVec4 hprect = ImVec4(
			headrect.z + (5.f * animation),
			namepos.y + Utils::ImGuiRender::getTextSize(_("")).y + (5.f * animation) + (10.f * animation),
			headrect.z + (((rect.z - rect.x) - (headrect.z - headrect.x)) - (10.f * animation)) - (20.f * animation),
			namepos.y + Utils::ImGuiRender::getTextSize(_("")).y + (5.f * animation) + (hpsize.y * animation) - (2.f * animation)
		);
		ImVec2 hppos = ImVec2(
			hprect.x + (1.f * animation),
			hprect.y - hpsize.y + (3.f * animation)
		);
		Utils::ImGuiRender::fillRectangle(hprect);
		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 1.f * animation));
		Utils::ImGuiRender::setSize(50.f);
		Utils::ImGuiRender::setThickness(100.f);
		Utils::ImGuiRender::setRound(5.f);
		Utils::ImGuiRender::fillShadowRectangle(hprect);

		Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[0 + (4 * interfaceMod->font)]);
		Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f * animation));
		Utils::ImGuiRender::setSize(1.f * animation);
		Utils::ImGuiRender::drawText(ss.str(), hppos);
		break;
	}
	case 2: {

		Utils::ImGuiRender::setSize(1.4f * animation);
		Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[(bold ? 1 : 0) + (4 * interfaceMod->font)]);

		ImVec4 rect = ImVec4(
			pos.x - (((Utils::ImGuiRender::getTextSize(lastplayer.name).x * animation) / 2) + (50.f * animation)),
			pos.y - (40.f * animation),
			pos.x + ((Utils::ImGuiRender::getTextSize(lastplayer.name).x * animation) / 2) + (50.f * animation),
			pos.y + (40.f * animation)
		);

		Utils::ImGuiRender::setDrawList(ImGui::GetBackgroundDrawList());
		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, opacity * animation));
		Utils::ImGuiRender::setRound(15.f);

		Utils::ImGuiRender::setBlurStreangth(blurs);
		Utils::ImGuiRender::fillBlurRectangle(rect);

		Utils::ImGuiRender::fillRectangle(rect);

		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 1.f * animation));
		Utils::ImGuiRender::setSize(50.f);
		Utils::ImGuiRender::setThickness(400.f);
		Utils::ImGuiRender::fillShadowRectangle(rect);

		ImVec4 headrect = ImVec4(
			rect.x + (7.5f * animation),
			rect.y + (7.5f * animation),
			rect.x + ((rect.w - rect.y) - (7.5f * animation)),
			rect.w - (7.5f * animation)
		);
		Utils::ImGuiRender::setColor(ImColor(0.f, 0.f, 0.f, 1.f * animation));
		Utils::ImGuiRender::fillRectangle(headrect);

		ImVec2 namepos = ImVec2(headrect.z + 5.f, headrect.y + 5.f);
		Utils::ImGuiRender::setColor(ImColor(1.f, 1.f, 1.f, 1.f * animation));
		Utils::ImGuiRender::setSize(1.3f * animation);
		Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[(bold ? 1 : 0) + (4 * interfaceMod->font)]);

		Utils::ImGuiRender::drawText(lastplayer.name, namepos);

		std::stringstream ss;
		ss.precision(0);
		ss << std::fixed << ((lastplayer.health / 2) + (lastplayer.absorption / 2)) << _(" HP");

		Utils::ImGuiRender::setSize(1.1f * animation);
		ImVec2 hpsize = Utils::ImGuiRender::getTextSize(ss.str());
		Utils::ImGuiRender::setSize(1.3f * animation);
		ImVec2 namesize = Utils::ImGuiRender::getTextSize(_(""));
		ImVec4 hprect = ImVec4(
			headrect.z + (5.f * animation),
			namepos.y + Utils::ImGuiRender::getTextSize(_("")).y + (5.f * animation) + (10.f * animation),
			headrect.z + (((rect.z - rect.x) - (headrect.z - headrect.x)) - (10.f * animation)) - (20.f * animation),
			namepos.y + Utils::ImGuiRender::getTextSize(_("")).y + (5.f * animation) + (hpsize.y * animation) - (2.f * animation)
		);
		ImVec2 hppos = ImVec2(
			hprect.x + (1.f * animation),
			hprect.y - hpsize.y + (3.f * animation)
		);

		Utils::ImGuiRender::setFont(ImGui::GetIO().Fonts->Fonts[0 + (4 * interfaceMod->font)]);
		Utils::ImGuiRender::setColor(ImColor(0.8f, 0.8f, 0.8f, 1.f * animation));
		Utils::ImGuiRender::setSize(1.1f * animation);
		Utils::ImGuiRender::drawText(ss.str(), hppos);
		break;
	}
	}
}

auto TargetInfo::onClient() -> void {
	if (!enabled) return;

	auto clientinstance = Client::clientinstance;
	if (!clientinstance) return;

	auto localplayer = clientinstance->getLocalPlayer();
	if (!localplayer) return;

	auto level = localplayer->getLevel();
	if (!level) return;

	std::vector<Player*> list_;
	level->forEachPlayer([&](Player& player) {
		if (&player != localplayer && Utils::Players::isRealPlayer(&player)) {
			list_.push_back(&player);
		}

		return true;
		});

	list = list_;
}
