#include "rive/bones/skin.hpp"
#include "rive/bones/bone.hpp"
#include "rive/bones/skinnable.hpp"
#include "rive/bones/tendon.hpp"
#include "rive/shapes/vertex.hpp"
#include "rive/shapes/path_vertex.hpp"
#include "rive/constraints/constraint.hpp"
#include <algorithm>

#include <cmath>

using namespace rive;

Skin::~Skin() { delete[] m_BoneTransforms; }

StatusCode Skin::onAddedDirty(CoreContext* context)
{
  StatusCode code = Super::onAddedDirty(context);
  if (code != StatusCode::Ok)
  {
    return code;
  }
  m_WorldTransform[0] = xx();
  m_WorldTransform[1] = xy();
  m_WorldTransform[2] = yx();
  m_WorldTransform[3] = yy();
  m_WorldTransform[4] = tx();
  m_WorldTransform[5] = ty();
  m_Skinnable = Skinnable::from(parent());
  if (m_Skinnable == nullptr)
  {
    return StatusCode::MissingObject;
  }

#ifndef WITH_RIVE_EDITOR
  // Runtime-only; editor build registers via editorParentChanged.
  m_Skinnable->skin(this);
#endif

  return StatusCode::Ok;
}

void Skin::update(ComponentDirt value)
{
  int bidx = 6;
  for (auto tendon : m_Tendons)
  {
#ifdef WITH_RIVE_EDITOR
    // Edit-time: a partially-hydrated coop batch can leave a
    // Tendon with a null `m_Bone` (its Bone hasn't been delivered
    // yet, or was deleted). Without this guard `update` reads the
    // null bone's world transform and crashes mid-frame. Emit the
    // identity transform so the skin can still render in its
    // bind pose until the bone reappears.
    if (tendon->bone() == nullptr)
    {
      const auto& inv = tendon->inverseBind();
      m_BoneTransforms[bidx++] = inv[0];
      m_BoneTransforms[bidx++] = inv[1];
      m_BoneTransforms[bidx++] = inv[2];
      m_BoneTransforms[bidx++] = inv[3];
      m_BoneTransforms[bidx++] = inv[4];
      m_BoneTransforms[bidx++] = inv[5];
      continue;
    }
#endif
    auto world = tendon->bone()->worldTransform() * tendon->inverseBind();
    m_BoneTransforms[bidx++] = world[0];
    m_BoneTransforms[bidx++] = world[1];
    m_BoneTransforms[bidx++] = world[2];
    m_BoneTransforms[bidx++] = world[3];
    m_BoneTransforms[bidx++] = world[4];
    m_BoneTransforms[bidx++] = world[5];
  }
}

int Skin::windingSign() const
{
  if (m_BoneTransforms == nullptr)
  {
    return 0;
  }
  bool anyMirrored = false;
  bool anyUpright = false;
  const float* transform = m_BoneTransforms;
  for (auto tendon : m_Tendons)
  {
    transform += 6;
#ifdef WITH_RIVE_EDITOR
    if (tendon->bone() == nullptr)
    {
      continue;
    }
#else
    (void)tendon;
#endif
    int sign = orientation(
        transform[0],
        transform[1],
        transform[2],
        transform[3]);
    anyMirrored |= sign < 0;
    anyUpright |= sign > 0;
  }
  return anyMirrored == anyUpright ? 0 : (anyMirrored ? -1 : 1);
}

int Skin::orientation(float xx, float xy, float yx, float yy)
{
  float xxyy = xx * yy;
  float xyyx = xy * yx;
  float determinant = xxyy - xyyx;
  // The determinant is only zero up to the rounding of the two products.
  if (std::abs(determinant) <= 1e-6f * (std::abs(xxyy) + std::abs(xyyx)))
  {
    return 0;
  }
  return determinant < 0 ? -1 : 1;
}

void Skin::buildDependencies()
{
  // depend on bones from tendons
  for (auto tendon : m_Tendons)
  {
    auto bone = tendon->bone();
#ifdef WITH_RIVE_EDITOR
    // See `Skin::update` — coop can leave an unresolved Tendon
    // with a null bone. `editor_native/finalizeBatch` calls
    // `Tendon::resolveBone` on every tendon before us, so this
    // is only hit for tendons whose bone genuinely isn't in the
    // file yet. Skip; the dependency edge rewires when the bone
    // arrives in a later batch and we re-run finalizeBatch.
    if (bone == nullptr)
    {
      continue;
    }
#endif
    bone->addDependent(this);
    for (auto constraint : bone->peerConstraints())
    {
      constraint->parent()->addDependent(this);
    }
  }

#ifdef WITH_RIVE_EDITOR
  // Editor re-runs buildDependencies after every batch (Pass-B-prep
  // wipes the dependents list, then the typed per-class method
  // rewires it). For Skin that means a second allocation of the
  // bone-transform buffer — `assert` below would catch the runtime-
  // only invariant. Free the prior buffer so the editor case stays
  // leak-free while keeping the runtime guard intact.
  if (m_BoneTransforms != nullptr)
  {
    delete[] m_BoneTransforms;
    m_BoneTransforms = nullptr;
  }
#else
  // Make sure no-one is calling this twice.
  assert(m_BoneTransforms == nullptr);
#endif
  // We can now init the bone buffer.
  auto size = (m_Tendons.size() + 1) * 6;
  m_BoneTransforms = new float[size];
  m_BoneTransforms[0] = 1;
  m_BoneTransforms[1] = 0;
  m_BoneTransforms[2] = 0;
  m_BoneTransforms[3] = 1;
  m_BoneTransforms[4] = 0;
  m_BoneTransforms[5] = 0;
}

void Skin::deform(Span<Vertex*> vertices)
{
  for (auto vertex : vertices)
  {
    vertex->deform(m_WorldTransform, m_BoneTransforms);
  }
}
void Skin::addTendon(Tendon* tendon)
{
  m_Tendons.push_back(tendon);
#ifdef WITH_RIVE_EDITOR
  bindingChangedForEditor();
#endif
}

#ifdef WITH_RIVE_EDITOR
void Skin::bindingChangedForEditor()
{
  if (m_Skinnable != nullptr)
  {
    m_Skinnable->bindingChangedForEditor();
  }
}

void Skin::sortTendonsForEditor()
{
  auto byChildOrder = [](const Tendon* a, const Tendon* b) {
    return a->childOrder().compareTo(b->childOrder()) < 0;
  };
  if (std::is_sorted(m_Tendons.begin(), m_Tendons.end(), byChildOrder))
  {
    return;
  }
  std::sort(m_Tendons.begin(), m_Tendons.end(), byChildOrder);
  bindingChangedForEditor();
  // Weights index m_BoneTransforms by tendon position, so a reorder has to
  // rebuild the buffer and re-deform the skinnable.
  addDirt(ComponentDirt::WorldTransform);
}
#endif

void Skin::onDirty(ComponentDirt dirt)
{
  // Render opacity alone, a fade reaching us through our bones, can't move a
  // bone, so the skinned vertices stay where they are. Collapsed is a state
  // this dirt keeps while we are hidden, not work.
  if ((dirt & ~ComponentDirt::Collapsed) == ComponentDirt::RenderOpacity)
  {
    return;
  }
  if (m_Skinnable != nullptr)
  {
    m_Skinnable->markSkinDirty();
  }
}
