#include "rive/animation/linear_animation_instance.hpp"
#include "rive/animation/interpolating_keyframe.hpp"
#include "rive/animation/linear_animation.hpp"
#include "rive/animation/loop.hpp"
#include "rive/animation/keyed_callback_reporter.hpp"
#include "rive/animation/keyframe.hpp"
#include "rive/animation/keyframe_double.hpp"
#include "rive/animation/keyframe_color.hpp"
#include "rive/animation/keyframe_bool.hpp"
#include "rive/animation/keyframe_string.hpp"
#include "rive/artboard.hpp"
#include "rive/assets/script_asset.hpp"
#include "rive/data_bind/data_bind.hpp"
#include "rive/data_bind/bindable_property.hpp"
#include "rive/data_bind/bindable_property_number.hpp"
#include "rive/data_bind/bindable_property_color.hpp"
#include "rive/data_bind/bindable_property_boolean.hpp"
#include "rive/data_bind/bindable_property_string.hpp"
#include "rive/data_bind/converters/data_converter.hpp"
#include "rive/profiler/profiler_macros.h"
#include "rive/scripted/scripted_interpolator.hpp"
#include "rive/animation/linear_animation_instance_extras.hpp"

#include <cmath>
#include <cassert>

using namespace rive;

LinearAnimationInstance::LinearAnimationInstance(
    const LinearAnimation* animation,
    ArtboardInstance* instance,
    float speedMultiplier)
    : Scene(instance)
    , m_animation((assert(animation != nullptr), animation))
    , m_time(
          (speedMultiplier >= 0) ? animation->startTime()
                                 : animation->endTime())
    , m_speedDirection((speedMultiplier >= 0) ? 1 : -1)
    , m_totalTime(0.0f)
    , m_lastTotalTime(0.0f)
    , m_spilledTime(0.0f)
    , m_direction(1)
{}

LinearAnimationInstance::LinearAnimationInstance(
    LinearAnimationInstance const& lhs)
    : Scene(lhs)
    , m_animation(lhs.m_animation)
    , m_time(lhs.m_time)
    , m_speedDirection(lhs.m_speedDirection)
    , m_totalTime(lhs.m_totalTime)
    , m_lastTotalTime(lhs.m_lastTotalTime)
    , m_spilledTime(lhs.m_spilledTime)
    , m_direction(lhs.m_direction)
    , m_didLoop(lhs.m_didLoop)
    , m_noKeyFrameBinds(lhs.m_noKeyFrameBinds)
    , m_loopValue(lhs.m_loopValue)
{}

LinearAnimationInstance::~LinearAnimationInstance()
{
  if (m_bindingExtras == nullptr)
  {
    return;
  }
  auto& extras = *m_bindingExtras;
  // Critical teardown order, mirroring the SMI pattern at
  // state_machine_instance.cpp:2011-2044: every cloned data bind must leave
  // the artboard and be deleted BEFORE the object owning its target dies.
  // Without this, the next Artboard::updateDataBinds() (which runs every
  // frame from updatePass) reads through DataBind::target() into freed
  // memory.
  //
  // The containers share one struct, so declaration order alone would
  // decide this. Do it explicitly instead — the ordering is load bearing and
  // must not be silently broken by reordering a field.
  //
  // ~Artboard deletes m_Objects — which own the LAIs (nested animations,
  // joysticks) — before deleteDataBinds(), so the artboard's bind list is
  // still valid here.
  //
  // Each StatefulScriptedInterpolator removes + deletes the binds it parked
  // on the artboard before it destroys its clone.
  extras.scriptedInterpolators.clear();
  if (m_artboardInstance != nullptr)
  {
    // Keyframe value bind clones target the holders below, so remove +
    // delete them from the artboard BEFORE freeing the holders.
    for (auto& pair : extras.keyFrameValueBinds)
    {
      m_artboardInstance->removeDataBind(pair.second);
      delete pair.second;
    }
  }
  extras.keyFrameValueBinds.clear();

  // Keyframe value holders are owned here; safe to delete now that the clones
  // targeting them were removed above.
  for (auto& pair : extras.keyFrameValueHolders)
  {
    delete pair.second;
  }
  extras.keyFrameValueHolders.clear();

  m_bindingExtras.reset();
}

// The BindableProperty value property key matching a keyframe's value type, or
// 0 for unsupported keyframe types (e.g. id/uint), which are left unbound.
static uint32_t keyFrameHolderPropertyKey(uint16_t keyFrameType)
{
  switch (keyFrameType)
  {
    case KeyFrameDoubleBase::typeKey:
      return BindablePropertyNumberBase::propertyValuePropertyKey;
    case KeyFrameColorBase::typeKey:
      return BindablePropertyColorBase::propertyValuePropertyKey;
    case KeyFrameBoolBase::typeKey:
      return BindablePropertyBooleanBase::propertyValuePropertyKey;
    case KeyFrameStringBase::typeKey:
      return BindablePropertyStringBase::propertyValuePropertyKey;
    default:
      return 0;
  }
}

// Creates the BindableProperty holder matching a keyframe's value type.
static BindableProperty* makeKeyFrameValueHolder(uint16_t keyFrameType)
{
  switch (keyFrameType)
  {
    case KeyFrameDoubleBase::typeKey:
      return new BindablePropertyNumber();
    case KeyFrameColorBase::typeKey:
      return new BindablePropertyColor();
    case KeyFrameBoolBase::typeKey:
      return new BindablePropertyBoolean();
    case KeyFrameStringBase::typeKey:
      return new BindablePropertyString();
    default:
      return nullptr;
  }
}

LAIBindingExtras& LinearAnimationInstance::ensureBindingExtras() const
{
  if (m_bindingExtras == nullptr)
  {
    m_bindingExtras = std::make_unique<LAIBindingExtras>();
  }
  return *m_bindingExtras;
}

#ifdef TESTING
uint64_t LinearAnimationInstance::sm_keyFrameHolderResolves = 0;
#endif

BindableProperty* LinearAnimationInstance::resolveKeyFrameValueHolder(
    const KeyFrame* keyframe) const
{
#ifdef TESTING
  sm_keyFrameHolderResolves++;
#endif
  // Already resolved for this LAI (holder cached).
  if (m_bindingExtras != nullptr)
  {
    auto& holders = m_bindingExtras->keyFrameValueHolders;
    auto it = holders.find(keyframe);
    if (it != holders.end())
    {
      // Refresh the holder from its source now (if the source changed
      // this frame) so the value is current at read time, regardless of
      // where the batched artboard updateDataBinds() falls relative to
      // the animation apply that's calling us. No-op when the bind isn't
      // dirty.
      auto& binds = m_bindingExtras->keyFrameValueBinds;
      auto bindIt = binds.find(keyframe);
      if (bindIt != binds.end() && m_artboardInstance != nullptr)
      {
        m_artboardInstance->flushDataBind(bindIt->second);
      }
      return it->second;
    }
  }
  // Lazily resolve from the source artboard's keyframe data binds. The gate
  // keeps playback in files without any keyframe binds free of per-keyframe
  // work (hasKeyFrameSourceBinds() is a cached O(1) check).
  if (m_artboardInstance == nullptr)
  {
    return nullptr;
  }
  const Artboard* source = m_artboardInstance->artboardSource();
  if (source == nullptr || !source->hasKeyFrameSourceBinds())
  {
#ifndef WITH_RIVE_EDITOR
    m_noKeyFrameBinds = true;
#endif
    return nullptr;
  }
  DataBind* sourceBind = source->keyFrameSourceBind(keyframe);
  if (sourceBind == nullptr)
  {
    return nullptr;
  }
  return buildKeyFrameValueHolder(keyframe, sourceBind);
}

BindableProperty* LinearAnimationInstance::buildKeyFrameValueHolder(
    const KeyFrame* keyframe,
    DataBind* sourceBind) const
{
  uint32_t propertyKey = keyFrameHolderPropertyKey(keyframe->coreType());
  if (propertyKey == 0)
  {
    return nullptr;
  }
  BindableProperty* holder = makeKeyFrameValueHolder(keyframe->coreType());
  ensureBindingExtras().keyFrameValueHolders[keyframe] = holder;

  // Clone the source bind, retarget it at the per-instance holder, and park
  // it on the artboard's data-bind container so it's advanced each frame.
  // addDataBind primes the holder synchronously when the data context is set.
  auto* clone = static_cast<DataBind*>(sourceBind->clone());
  clone->file(sourceBind->file());
  clone->target(holder);
  clone->propertyKey(propertyKey);
  clone->initialize();
  if (sourceBind->converter() != nullptr)
  {
    clone->converter(sourceBind->converter()->clone()->as<DataConverter>());
  }
  m_artboardInstance->addDataBind(clone);
  m_bindingExtras->keyFrameValueBinds[keyframe] = clone;
  return holder;
}

// Returns a per-(this LAI, keyframe) stateful clone of the given shared
// ScriptedInterpolator. Mirrors StateMachineInstance::scriptedObjects but
// keyed by the keyframe pointer so distinct keyframes that share a script
// each get their own Lua `self` table. Lazily allocates the map and the
// clone on first hit; subsequent calls return the cached clone. Cleanup
// runs in ~LinearAnimationInstance.
ScriptedInterpolator* LinearAnimationInstance::statefulInterpolator(
    const InterpolatingKeyFrame* keyframe,
    const ScriptedInterpolator* shared) const
{
  if (shared == nullptr || keyframe == nullptr)
  {
    return nullptr;
  }
  auto& map = ensureBindingExtras().scriptedInterpolators;
  auto it = map.find(keyframe);
  if (it != map.end())
  {
    return it->second->get();
  }
  auto stateful = std::unique_ptr<StatefulScriptedInterpolator>(
      new StatefulScriptedInterpolator(
          shared,
          m_artboardInstance,
          m_artboardInstance->dataContext()));
  auto* clone = stateful->get();
  if (clone == nullptr)
  {
    return nullptr;
  }
  map.emplace(keyframe, std::move(stateful));
  return clone;
}

bool LinearAnimationInstance::advanceAndApply(float seconds)
{
  RIVE_PROF_SCOPE_L(1)
  // Scripted interpolators run in apply(), before Artboard::advance polls.
  m_artboardInstance->pollAsyncWork();
  bool more = this->advance(seconds, this);
  this->apply();
  if (m_artboardInstance->advance(seconds))
  {
    more = true;
  }
  // A host that stops ticking a finished animation would never poll its
  // scripts' async work in.
  return more || keepGoing() || m_artboardInstance->hasPendingAsyncWork();
}

bool LinearAnimationInstance::advance(
    float elapsedSeconds,
    KeyedCallbackReporter* reporter)
{
  const LinearAnimation& animation = *m_animation;
  float deltaSeconds = elapsedSeconds * animation.speed() * m_direction;

  m_spilledTime = 0.0f;
  if (deltaSeconds == 0)
  {
    m_didLoop = false;
    return false;
  }

  m_lastTotalTime = m_totalTime;
  m_totalTime += std::abs(deltaSeconds);

  // NOTE:
  // do not track spilled time, if our one shot loop is already completed.
  // stop gap before we move spilled tracking into state machine logic.
  bool killSpilledTime = !this->keepGoing(elapsedSeconds);

  float lastTime = m_time;
  m_time += deltaSeconds;
  if (reporter != nullptr)
  {
    animation.reportKeyedCallbacks(
        reporter,
        lastTime,
        m_time,
        m_speedDirection,
        false);
  }

  float fps = (float)animation.fps();
  float frames = m_time * fps;
  float start = animation.enableWorkArea() ? (float)animation.workStart()
                                           : 0.0f;
  float end = animation.enableWorkArea() ? (float)animation.workEnd()
                                         : (float)animation.duration();
  float range = end - start;

  bool didLoop = false;

  // this has some issues when deltaSeconds is 0,
  // right now we basically assume we default to going forwards in that case
  //
  int direction = deltaSeconds < 0 ? -1 : 1;
  switch (loop())
  {
    case Loop::oneShot:
      if (direction == 1 && frames > end)
      {
        // Account for the time dilation or contraction applied in the
        // animation local time by its speed to calculate spilled time.
        // Calculate the ratio of the time excess by the total elapsed
        // time in local time (deltaFrames) and multiply the elapsed
        // time by it.
        auto deltaFrames = deltaSeconds * fps;
        auto spilledFramesRatio = (frames - end) / deltaFrames;
        m_spilledTime = spilledFramesRatio * elapsedSeconds;
        frames = (float)end;
        m_time = frames / fps;
        didLoop = true;
      }
      else if (direction == -1 && frames < start)
      {
        auto deltaFrames = std::abs(deltaSeconds * fps);
        auto spilledFramesRatio = (start - frames) / deltaFrames;
        m_spilledTime = spilledFramesRatio * elapsedSeconds;
        frames = (float)start;
        m_time = frames / fps;
        didLoop = true;
      }
      break;
    case Loop::loop:
      if (direction == 1 && frames >= end)
      {
        // How spilled time has to be calculated, given that local time
        // can be scaled to a factor of the regular time:
        // - for convenience, calculate the local elapsed time in frames
        // (deltaFrames)
        // - get the remainder of current frame position (frames) by
        // duration (range)
        // - use that remainder as the ratio of the original time that
        // was not consumed by the loop (spilledFramesRatio)
        // - multiply the original elapsedTime by the ratio to set the
        // spilled time
        auto deltaFrames = deltaSeconds * fps;
        auto remainder = std::fmod(frames - start, (float)range);
        auto spilledFramesRatio = remainder / deltaFrames;
        m_spilledTime = spilledFramesRatio * elapsedSeconds;
        frames = start + remainder;
        m_time = frames / fps;
        didLoop = true;
        if (reporter != nullptr)
        {
          animation.reportKeyedCallbacks(
              reporter,
              0.0f,
              m_time,
              m_speedDirection,
              false);
        }
      }
      else if (direction == -1 && frames <= start)
      {
        auto deltaFrames = deltaSeconds * fps;
        auto remainder = std::abs(std::fmod(start - frames, (float)range));
        auto spilledFramesRatio = std::abs(remainder / deltaFrames);
        m_spilledTime = spilledFramesRatio * elapsedSeconds;
        frames = end - remainder;
        m_time = frames / fps;
        didLoop = true;
        if (reporter != nullptr)
        {
          animation.reportKeyedCallbacks(
              reporter,
              end / (float)fps,
              m_time,
              m_speedDirection,
              false);
        }
      }
      break;
    case Loop::pingPong:
      bool fromPong = true;
      while (true)
      {
        if (direction == 1 && frames >= end)
        {
          m_spilledTime = (frames - end) / fps;
          frames = end + (end - frames);
          lastTime = end / (float)fps;
        }
        else if (direction == -1 && frames < start)
        {
          m_spilledTime = (start - frames) / fps;
          frames = start + (start - frames);
          lastTime = start / (float)fps;
        }
        else
        {
          // we're within the range, we can stop fixing. We do this in
          // a loop to fix conditions when time has advanced so far
          // that we've ping-ponged back and forth a few times in a
          // single frame. We want to accomodate for this in cases
          // where animations are not advanced on regular intervals.
          break;
        }
        m_time = frames / fps;
        m_direction *= -1;
        direction *= -1;
        didLoop = true;
        if (reporter != nullptr)
        {
          animation.reportKeyedCallbacks(
              reporter,
              lastTime,
              m_time,
              m_speedDirection,
              fromPong);
        }
        fromPong = !fromPong;
      }
      break;
  }

  if (killSpilledTime)
  {
    m_spilledTime = 0;
  }

  m_didLoop = didLoop;
  return this->keepGoing(elapsedSeconds);
}

void LinearAnimationInstance::time(float value)
{
  if (m_time == value)
  {
    return;
  }
  m_time = value;
  // Make sure to keep last and total in relative lockstep so state machines
  // can track change even when setting time.
  auto diff = m_totalTime - m_lastTotalTime;

  float start = (m_animation->enableWorkArea() ? (float)m_animation->workStart()
                                               : 0.0f) *
                (float)m_animation->fps();
  m_totalTime = value - start;
  m_lastTotalTime = m_totalTime - diff;

  // leaving this RIGHT now. but is this required? it kinda messes up
  // playing things backwards and seeking. what purpose does it solve?
  m_direction = 1;
}

void LinearAnimationInstance::reset(float speedMultiplier = 1.0)
{
  m_time = (speedMultiplier >= 0) ? m_animation->startTime()
                                  : m_animation->endTime();
}

uint32_t LinearAnimationInstance::fps() const { return m_animation->fps(); }

uint32_t LinearAnimationInstance::duration() const
{
  return m_animation->duration();
}

float LinearAnimationInstance::speed() const { return m_animation->speed(); }

float LinearAnimationInstance::startTime() const
{
  return m_animation->startTime();
}

std::string LinearAnimationInstance::name() const
{
  return m_animation->name();
}

bool LinearAnimationInstance::isTranslucent() const
{
  return m_artboardInstance->isTranslucent(this);
}

// Returns either the animation's default or overridden loop values
int LinearAnimationInstance::loopValue() const
{
  if (m_loopValue != -1)
  {
    return m_loopValue;
  }
  return m_animation->loopValue();
}

// Override the animation's loop value
void LinearAnimationInstance::loopValue(int value)
{
  if (m_loopValue == value)
  {
    return;
  }
  if (m_loopValue == -1 && m_animation->loopValue() == value)
  {
    return;
  }
  m_loopValue = value;
}

float LinearAnimationInstance::durationSeconds() const
{
  return m_animation->durationSeconds();
}

void LinearAnimationInstance::reportEvent(Event* event, float secondsDelay)
{
  const std::vector<Event*> events{event};
  notifyListeners(events);
}