#include "PregnancySystem.hpp"
#include "CharacterRegistry.hpp"
#include "EventBus.hpp"
#include "../components/EventParams.hpp"
#include <OgreLogManager.h>

PregnancySystem::PregnancySystem(flecs::world &world)
	: m_world(world)
{
}

PregnancySystem::~PregnancySystem() = default;

void PregnancySystem::update(float deltaTime)
{
	advancePregnancies(deltaTime);
	checkBirths();
}

void PregnancySystem::advancePregnancies(float dt)
{
	CharacterRegistry &reg = CharacterRegistry::getSingleton();
	float timeScale = reg.getPregnancyTimeScale();
	if (timeScale <= 0.0f)
		return;

	for (const auto &pair : reg.getCharacters()) {
		uint64_t id = pair.first;
		if (pair.second.pregnantByFatherId == 0)
			continue;
		CharacterRegistry::CharacterRecord *c =
			reg.findCharacter(id);
		if (c)
			c->pregnancyProgress += dt * timeScale;
	}
}

void PregnancySystem::checkBirths()
{
	CharacterRegistry &reg = CharacterRegistry::getSingleton();
	std::vector<uint64_t> toBirth;

	for (const auto &pair : reg.getCharacters()) {
		const CharacterRegistry::CharacterRecord &c = pair.second;
		if (c.pregnantByFatherId == 0)
			continue;
		if (c.pregnancyMaxProgress > 0.0f &&
		    c.pregnancyProgress >= c.pregnancyMaxProgress)
			toBirth.push_back(c.id);
	}

	for (uint64_t motherId : toBirth) {
		CharacterRegistry::CharacterRecord *mother =
			reg.findCharacter(motherId);
		if (!mother)
			continue;
		uint64_t fatherId = mother->pregnantByFatherId;

		uint64_t childId = reg.createChild(fatherId, motherId);

		/* Fire birth event */
		editScene::EventParams params;
		params.setEntityId("mother", motherId);
		params.setEntityId("father", fatherId);
		params.setEntityId("child", childId);
		EventBus::getInstance().send("birth", params);

		/* Reset pregnancy */
		mother->pregnantByFatherId = 0;
		mother->pregnancyProgress = 0.0f;
		mother->pregnancyMaxProgress = 0.0f;

		Ogre::LogManager::getSingleton().logMessage(
			"PregnancySystem: birth — mother=" +
			Ogre::StringConverter::toString(motherId) +
			" father=" + Ogre::StringConverter::toString(fatherId) +
			" child=" + Ogre::StringConverter::toString(childId));
	}
}
