#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,
                                         Span<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;
}