#include "CharacterClassEditor.hpp"
#include "../components/CharacterClassDatabase.hpp"
#include "../systems/CharacterClassSystem.hpp"
#include <imgui.h>

bool CharacterClassEditor::renderComponent(flecs::entity entity,
						   CharacterClassComponent &comp)
{
	(void)entity;

	auto &db = CharacterClassDatabase::getSingleton();

	// Class selector
	const auto &classNames = db.getClassNames();
	if (!classNames.empty()) {
		int selected = -1;
		for (int i = 0; i < (int)classNames.size(); i++) {
			if (classNames[i] == comp.className) {
				selected = i;
				break;
			}
		}
		if (ImGui::Combo("Class", &selected,
				 [](void *data, int idx) -> const char * {
					 const auto *names =
						 static_cast<const std::vector<Ogre::String> *>(
							 data);
					 if (idx < 0 ||
					     idx >= (int)names->size())
						 return nullptr;
					 return (*names)[idx].c_str();
				 },
				 (void *)&classNames,
				 (int)classNames.size())) {
			if (selected >= 0 &&
			    selected < (int)classNames.size())
				comp.className = classNames[selected];
		}
	} else {
		ImGui::Text("No classes defined in database.");
	}

	ImGui::Separator();

	if (ImGui::Button("Reinitialize from Class")) {
		CharacterClassSystem::initializeFromClass(entity);
	}
	if (ImGui::IsItemHovered()) {
		ImGui::BeginTooltip();
		ImGui::Text("Reset stats/skills/needs to class base values,");
		ImGui::Text("then simulate all level-ups with AI point distribution.");
		ImGui::EndTooltip();
	}

	// Level & XP
	ImGui::InputInt("Level", &comp.level, 1, 5);
	if (comp.level < 1)
		comp.level = 1;

	int64_t xp = comp.currentXP;
	ImGui::InputScalar("Current XP", ImGuiDataType_S64, &xp);
	comp.currentXP = xp;

	ImGui::InputInt("Available Points", &comp.availablePoints, 1, 5);

	if (comp.levelUpPending)
		ImGui::TextColored(ImVec4(0, 1, 0, 1), "LEVEL UP PENDING!");

	ImGui::Separator();

	// Stats: show ALL database stat definitions, not just stored ones
	if (!db.getStatNames().empty()) {
		ImGui::Text("Stats");
		for (const auto &name : db.getStatNames()) {
			const auto *def = db.findStat(name);
			if (!def)
				continue;

			ImGui::PushID(name.c_str());
			if (def->kind ==
			    CharacterClassDatabase::StatKind::ResourcePool) {
				// Resource pool: current / max
				int current = comp.getPoolCurrent(name);
				int maxVal = comp.stats.count(name) ?
						     comp.stats.at(name) :
						     0;
				ImGui::Text("%s", name.c_str());
				ImGui::SameLine(100);
				ImGui::Text("Cur:");
				ImGui::SameLine();
				if (ImGui::InputInt("##cur", &current, 1, 5))
					comp.setPoolCurrent(name, current);
				ImGui::SameLine();
				ImGui::Text("Max:");
				ImGui::SameLine();
				if (ImGui::InputInt("##max", &maxVal, 1, 5)) {
					comp.stats[name] = maxVal;
					comp.setPoolCurrent(name,
							   comp.getPoolCurrent(
								   name));
				}
			} else {
				// Attribute
				int val = comp.stats.count(name) ?
						  comp.stats.at(name) :
						  0;
				if (ImGui::InputInt(name.c_str(), &val, 1, 5))
					comp.stats[name] = val;
			}
			ImGui::PopID();
		}
	}

	// Skills: show ALL database skill definitions
	if (!db.getSkillNames().empty()) {
		ImGui::Separator();
		ImGui::Text("Skills");
		for (const auto &name : db.getSkillNames()) {
			int val = comp.skills.count(name) ?
					  comp.skills.at(name) :
					  0;
			if (ImGui::InputInt(name.c_str(), &val, 1, 5)) {
				if (val < 0)
					val = 0;
				if (val > 100)
					val = 100;
				comp.skills[name] = val;
			}
		}
	}

	// Needs: show ALL database need definitions
	if (!db.getNeedNames().empty()) {
		ImGui::Separator();
		ImGui::Text("Needs");
		for (const auto &name : db.getNeedNames()) {
			int val = comp.needs.count(name) ?
					  comp.needs.at(name) :
					  0;
			if (ImGui::InputInt(name.c_str(), &val, 1, 5)) {
				if (val < 0)
					val = 0;
				if (val > 1000)
					val = 1000;
				comp.needs[name] = val;
			}
		}
	}

	return false;
}
