#include "rive/animation/state_transition.hpp"
#include "rive/importers/import_stack.hpp"
#include "rive/importers/layer_state_importer.hpp"
#include "rive/animation/layer_state.hpp"
#include "rive/animation/transition_condition.hpp"
#include "rive/animation/animation_state.hpp"
#include "rive/animation/linear_animation.hpp"
#include "rive/animation/state_machine_input_instance.hpp"
#include "rive/animation/state_machine_trigger.hpp"
#include "rive/animation/animation_state_instance.hpp"
#include "rive/animation/transition_trigger_condition.hpp"

using namespace rive;

StateTransition::~StateTransition()
{
	for (auto condition : m_Conditions)
	{
		delete condition;
	}
}

StatusCode StateTransition::onAddedDirty(CoreContext* context)
{
	StatusCode code;
	for (auto condition : m_Conditions)
	{
		if ((code = condition->onAddedDirty(context)) != StatusCode::Ok)
		{
			return code;
		}
	}
	return StatusCode::Ok;
}

StatusCode StateTransition::onAddedClean(CoreContext* context)
{
	StatusCode code;
	for (auto condition : m_Conditions)
	{
		if ((code = condition->onAddedClean(context)) != StatusCode::Ok)
		{
			return code;
		}
	}
	return StatusCode::Ok;
}

StatusCode StateTransition::import(ImportStack& importStack)
{
	auto stateImporter =
	    importStack.latest<LayerStateImporter>(LayerState::typeKey);
	if (stateImporter == nullptr)
	{
		return StatusCode::MissingObject;
	}
	stateImporter->addTransition(this);
	return Super::import(importStack);
}

void StateTransition::addCondition(TransitionCondition* condition)
{
	m_Conditions.push_back(condition);
}

float StateTransition::mixTime(const LayerState* stateFrom) const
{
	if (duration() == 0)
	{
		return 0;
	}
	if ((transitionFlags() & StateTransitionFlags::DurationIsPercentage) ==
	    StateTransitionFlags::DurationIsPercentage)
	{
		float animationDuration = 0.0f;
		if (stateFrom->is<AnimationState>())
		{
			auto animation = stateFrom->as<AnimationState>()->animation();
			if (animation != nullptr)
			{
				animationDuration = animation->durationSeconds();
			}
		}
		return duration() / 100.0f * animationDuration;
	}
	else
	{
		return duration() / 1000.0f;
	}
}

float StateTransition::exitTimeSeconds(const LayerState* stateFrom,
                                       bool absolute) const
{
	if ((transitionFlags() & StateTransitionFlags::ExitTimeIsPercentage) ==
	    StateTransitionFlags::ExitTimeIsPercentage)
	{
		float animationDuration = 0.0f;
		float start = 0.0f;

		auto exitAnimation = exitTimeAnimation(stateFrom);
		if (exitAnimation != nullptr)
		{
			start = absolute ? exitAnimation->startSeconds() : 0.0f;
			animationDuration = exitAnimation->durationSeconds();
		}

		return start + exitTime() / 100.0f * animationDuration;
	}
	return exitTime() / 1000.0f;
}

const LinearAnimationInstance*
StateTransition::exitTimeAnimationInstance(const StateInstance* from) const
{
	return from != nullptr && from->state()->is<AnimationState>()
	           ? static_cast<const AnimationStateInstance*>(from)
	                 ->animationInstance()
	           : nullptr;
}

const LinearAnimation*
StateTransition::exitTimeAnimation(const LayerState* from) const
{
	return from != nullptr && from->is<AnimationState>()
	           ? from->as<AnimationState>()->animation()
	           : nullptr;
}

AllowTransition StateTransition::allowed(StateInstance* stateFrom,
                                         SMIInput** inputs,
                                         bool ignoreTriggers) const
{
	if (isDisabled())
	{
		return AllowTransition::no;
	}

	for (auto condition : m_Conditions)
	{
		// N.B. state machine instance sanitizes these for us...
		auto input = inputs[condition->inputId()];

		if ((ignoreTriggers && condition->is<TransitionTriggerCondition>()) ||
		    !condition->evaluate(input))
		{
			return AllowTransition::no;
		}
	}

	if (enableExitTime())
	{
		auto exitAnimation = exitTimeAnimationInstance(stateFrom);
		if (exitAnimation != nullptr)
		{
			// Exit time is specified in a value less than a single loop, so we
			// want to allow exiting regardless of which loop we're on. To do
			// that we bring the exit time up to the loop our lastTime is at.
			auto lastTime = exitAnimation->lastTotalTime();
			auto time = exitAnimation->totalTime();
			auto exitTime = exitTimeSeconds(stateFrom->state());
			auto animationFrom = exitAnimation->animation();
			auto duration = animationFrom->durationSeconds();

			// TODO: there are some considerations to have when exit time is combined with another condition (like trigger)
			//   - not sure how to get this to make sense with pingPing animations
			//   - also if exit time is, say 50% on a loop, this will be happy to fire
			//       - when time is anywhere in 50%-100%, 150%-200%. as opposed to just at 50%
			//       .... makes you wonder if we need some kind of exit after/exit before time 
			//       .... but i suspect that will introduce some more issues?

			// There's only one iteration in oneShot, 
			if (exitTime <= duration && animationFrom->loop() !=Loop::oneShot)
			{
				// Get exit time relative to the loop lastTime was in.
				exitTime += std::floor(lastTime / duration) * duration;
			}

			if (time < exitTime)
			{
				return AllowTransition::waitingForExit;
			}
		}
	}
	return AllowTransition::yes;
}

bool StateTransition::applyExitCondition(StateInstance* from) const
{
	// Hold exit time when the user has set to pauseOnExit on this condition
	// (only valid when exiting from an Animation).
	bool useExitTime = enableExitTime() &&
	                   (from != nullptr && from->state()->is<AnimationState>());
	if (pauseOnExit() && useExitTime)
	{
		static_cast<AnimationStateInstance*>(from)->animationInstance()->time(
		    exitTimeSeconds(from->state(), true));
		return true;
	}
	return useExitTime;
}