#include "rive/nested_artboard_layout.hpp"
#include "rive/artboard.hpp"
#include "rive/animation/keyframe_interpolator.hpp"
#include "rive/layout/layout_data.hpp"
#include "rive/math/aabb.hpp"
#include "rive/world_transform_component.hpp"

using namespace rive;

Core* NestedArtboardLayout::clone() const
{
  NestedArtboardLayout* nestedArtboard = static_cast<NestedArtboardLayout*>(
      NestedArtboardLayoutBase::clone());
  cloneReferencesInto(nestedArtboard);
  return nestedArtboard;
}

AABB NestedArtboardLayout::layoutBounds()
{
#ifdef WITH_RIVE_LAYOUT
  if (artboardInstance() != nullptr)
  {
    return artboardInstance()->layoutBounds();
  }
#endif
  return AABB();
}

#ifdef WITH_RIVE_LAYOUT
void* NestedArtboardLayout::layoutNode(int index)
{
  if (artboardInstance() == nullptr)
  {
    return nullptr;
  }
  return static_cast<void*>(&artboardInstance()->takeLayoutData()->node);
}
#endif

void NestedArtboardLayout::markHostingLayoutDirty(
    ArtboardInstance* artboardInstance)
{
  if (artboard() != nullptr)
  {
    artboard()->markLayoutDirty(this->artboardInstance());
  }
}

void NestedArtboardLayout::markLayoutNodeDirty(
    bool shouldForceUpdateLayoutBounds)
{
  updateWidthOverride();
  updateHeightOverride();
}

// Where the layout put us, less the mounted artboard's own origin, applied in
// the parent's frame:
//
//   parentWorld * translate(slot - origin) * m_Transform
//
// Applied after constraints rather than composed before them. A constraint that
// copies a position (follow path, translation) composes the world transform
// from its target and replaces our translation outright, so a placement folded
// into composeWorldTransform is discarded and the artboard renders off by its
// origin. With no constraint the two orders are the same matrix, so files that
// do not constrain a nested artboard are unaffected.
void NestedArtboardLayout::applyLayoutPlacement()
{
  auto artboard = artboardInstance();
  if (artboard == nullptr)
  {
    return;
  }
  auto base = Vec2D(artboard->layoutX(), artboard->layoutY()) -
              artboard->origin();
  auto* parentComponent = parent();
  if (parentComponent != nullptr && parentComponent->is<Artboard>())
  {
    base += parentComponent->as<Artboard>()->origin();
  }
  if (m_ParentTransformComponent != nullptr)
  {
    // Rotate/scale into the parent's frame; its translation cancels.
    const Mat2D& p = m_ParentTransformComponent->worldTransform();
    m_WorldTransform[4] += p[0] * base.x + p[2] * base.y;
    m_WorldTransform[5] += p[1] * base.x + p[3] * base.y;
  }
  else
  {
    m_WorldTransform[4] += base.x;
    m_WorldTransform[5] += base.y;
  }
}

void NestedArtboardLayout::updateConstraints()
{
  if (layoutConstraints().size() > 0)
  {
    for (auto parentConstraint : layoutConstraints())
    {
      parentConstraint->constrainChild(this);
    }
  }
  Super::updateConstraints();
  applyLayoutPlacement();
}

StatusCode NestedArtboardLayout::onAddedClean(CoreContext* context)
{
  StatusCode code = Super::onAddedClean(context);
  if (code != StatusCode::Ok)
  {
    return code;
  }

  updateWidthOverride();
  updateHeightOverride();

  return StatusCode::Ok;
}

void NestedArtboardLayout::updateLayoutBounds(bool animate)
{
#ifdef WITH_RIVE_LAYOUT
  if (artboardInstance() == nullptr)
  {
    return;
  }
  artboardInstance()->updateLayoutBounds(animate);
#endif
}

#ifdef WITH_RIVE_LAYOUT
bool NestedArtboardLayout::cascadeLayoutStyle(
    LayoutStyleInterpolation inheritedInterpolation,
    KeyFrameInterpolator* inheritedInterpolator,
    float inheritedInterpolationTime,
    LayoutDirection direction)
{
  if (artboardInstance() != nullptr)
  {
    artboardInstance()->cascadeLayoutStyle(
        inheritedInterpolation,
        inheritedInterpolator,
        inheritedInterpolationTime,
        direction);
  }
  return false;
}
#endif

void NestedArtboardLayout::updateWidthOverride()
{
  if (artboardInstance() == nullptr)
  {
    return;
  }
  m_styleOverrider.updateWidthOverride(artboardInstance());
}

void NestedArtboardLayout::updateHeightOverride()
{
  if (artboardInstance() == nullptr)
  {
    return;
  }
  m_styleOverrider.updateHeightOverride(artboardInstance());
}

// The layout that collected us, which may sit above a container. Asking
// parent() reported row/not-stack for a Solo and sized the wrong axis.
bool NestedArtboardLayout::isRow()
{
  auto* layout = owningLayout(parent());
  return layout != nullptr ? layout->mainAxisIsRow() : true;
}

bool NestedArtboardLayout::isStack()
{
  auto* layout = owningLayout(parent());
  return layout != nullptr && layout->isStackContainer();
}

void NestedArtboardLayout::instanceWidthChanged() { updateWidthOverride(); }

void NestedArtboardLayout::instanceHeightChanged() { updateHeightOverride(); }

void NestedArtboardLayout::instanceWidthUnitsValueChanged()
{
  updateWidthOverride();
}

void NestedArtboardLayout::instanceHeightUnitsValueChanged()
{
  updateHeightOverride();
}

void NestedArtboardLayout::instanceWidthScaleTypeChanged()
{
  updateWidthOverride();
}

void NestedArtboardLayout::instanceHeightScaleTypeChanged()
{
  updateHeightOverride();
}

bool NestedArtboardLayout::syncStyleChanges()
{
  if (m_referencedArtboard == nullptr)
  {
    return false;
  }
  return m_referencedArtboard->syncStyleChanges();
}

void NestedArtboardLayout::referencedArtboard(Artboard* artboard)
{
#ifdef WITH_RIVE_EDITOR
  if (!editorArena())
  {
    NestedArtboard::referencedArtboard(artboard);
    return;
  }
  // Editor hydration also assigns non-owned definitions. Their authored
  // layout must not receive an instance's sizing overrides.
  if (!artboard->isInstance())
  {
    NestedArtboard::referencedArtboard(artboard);
    return;
  }
#ifdef WITH_RIVE_LAYOUT
  // Direct mounts (including editor-native clones) also replace the owned
  // instance. Detach Yoga's borrowed node before nest() destroys it. The
  // artboard host only rebuilds the root, which may not be our owner when
  // a LayoutComponent sits between this instance and the artboard.
  auto* layout = owningLayout(parent());
  // Hydration may mount definitions before the owning component is valid.
  if (layout != nullptr && layout->artboard() == nullptr)
    layout = nullptr;
  if (layout != nullptr)
    layout->clearLayoutChildren();
#endif
  NestedArtboard::referencedArtboard(artboard);
  updateWidthOverride();
  updateHeightOverride();
#ifdef WITH_RIVE_LAYOUT
  if (layout != nullptr)
    layout->syncLayoutChildren();
#endif
#else
  NestedArtboard::referencedArtboard(artboard);
#endif
}

void NestedArtboardLayout::updateArtboard(
    ViewModelInstanceArtboard* viewModelInstanceArtboard)
{
#ifdef WITH_RIVE_LAYOUT
  // Re-collect on the layout that owns our node, not on parent(), or a
  // container between the two leaves the swap unsynced.
  auto* layout = owningLayout(parent());
  if (layout != nullptr)
  {
    layout->clearLayoutChildren();
  }
#endif
  NestedArtboard::updateArtboard(viewModelInstanceArtboard);
  updateWidthOverride();
  updateHeightOverride();
#ifdef WITH_RIVE_LAYOUT
  if (layout != nullptr)
  {
    layout->syncLayoutChildren();
  }
#endif
}