#include "rive/layout/layout_participant.hpp"
#include "rive/layout_component.hpp"
#include "rive/layout/layout_component_style.hpp"
#include "rive/layout/layout_node_style.hpp"
#include "rive/layout/grid_item_placement.hpp"
#include "rive/layout/grid_track.hpp"
#include "rive/layout/layout_data.hpp"
#include "rive/layout/layout_style_applier.hpp"
#include "rive/constraints/layout_constraint.hpp"
#include "rive/transform_component.hpp"
#include "rive/intrinsically_sizeable.hpp"
#include "rive/component.hpp"
#include "rive/solo.hpp"
#include "rive/artboard.hpp"
#include "rive/animation/keyframe_interpolator.hpp"
#include <algorithm>
#include <cmath>

using namespace rive;

#ifdef WITH_RIVE_LAYOUT
void LayoutParticipant::addLayoutStyleApplier(LayoutStyleApplier* applier)
{
  if (m_layoutData != nullptr)
  {
    m_layoutData->addApplier(applier);
  }
}
#endif

namespace rive
{
// Lazily-allocated animation state — only exists while a participant is under
// an animated layout, so a non-animating participant pays only the pointer.
struct ParticipantAnimation
{
  Layout animatedLayout;
  LayoutAnimationData a;
  LayoutAnimationData b;
  bool isSmoothing = false;
  LayoutStyleInterpolation interpolation = LayoutStyleInterpolation::hold;
  KeyFrameInterpolator* interpolator = nullptr;
  float interpolationTime = 0.0f;
};
} // namespace rive

#ifdef WITH_RIVE_LAYOUT
static YGSize participantMeasureFunc(
    YGNode* node,
    float width,
    YGMeasureMode widthMode,
    float height,
    YGMeasureMode heightMode)
{
  auto* participant = static_cast<LayoutParticipant*>(node->getContext());
  auto* sizeable = IntrinsicallySizeable::from(
      participant->transformComponent());
  if (sizeable == nullptr)
  {
    return YGSize{0.0f, 0.0f};
  }
  auto wMode = (LayoutMeasureMode)widthMode;
  auto hMode = (LayoutMeasureMode)heightMode;
  if (participant->hugUnbounded())
  {
    // Per axis: see LayoutComponent::measureLayout -- a fill axis's measure
    // feeds yoga's flex basis, so widening it would move this item's share
    // of the line.
    if ((LayoutScaleType)participant->layoutWidthScaleType() ==
        LayoutScaleType::hug)
    {
      wMode = unboundMeasureMode(wMode);
    }
    if ((LayoutScaleType)participant->layoutHeightScaleType() ==
        LayoutScaleType::hug)
    {
      hMode = unboundMeasureMode(hMode);
    }
  }
  const bool probing = YGConfigIsMeasuringMinContent(node->getConfig());
  wMode = measureModeForContent(wMode, width, probing);
  hMode = measureModeForContent(hMode, height, probing);
  Vec2D size = sizeable->measureLayout(width, wMode, height, hMode);
  return YGSize{size.x, size.y};
}
#endif

LayoutParticipant::~LayoutParticipant()
{
  delete m_animation;
#ifdef WITH_RIVE_LAYOUT
  releaseLayoutData();
#endif
}

TransformComponent* LayoutParticipant::transformComponent()
{
  auto* p = parent();
  return (p != nullptr && p->is<TransformComponent>())
             ? p->as<TransformComponent>()
             : nullptr;
}

void LayoutParticipant::applyLayoutConstraints()
{
  for (auto parentConstraint : layoutConstraints())
  {
    parentConstraint->constrainChild(this);
  }
}

LayoutComponent* LayoutParticipant::owningLayout()
{
  for (Component* c = parent(); c != nullptr; c = c->parent())
  {
    if (c->is<LayoutComponent>())
    {
      return c->as<LayoutComponent>();
    }
  }
  return nullptr;
}

bool LayoutParticipant::isParticipatingInLayout() const
{
#ifdef WITH_RIVE_LAYOUT
  return m_layoutData != nullptr;
#else
  return false;
#endif
}

StatusCode LayoutParticipant::onAddedClean(CoreContext* context)
{
  StatusCode code = Super::onAddedClean(context);
  if (code != StatusCode::Ok)
  {
    return code;
  }
#ifdef WITH_RIVE_LAYOUT
  resync();
#endif
  return StatusCode::Ok;
}

#ifdef WITH_RIVE_LAYOUT
void LayoutParticipant::releaseLayoutData()
{
  if (m_layoutData == nullptr)
  {
    return;
  }
#ifdef WITH_RIVE_TOOLS
  m_layoutData->unref();
#else
  delete m_layoutData;
#endif
  m_layoutData = nullptr;
}

// Releases a fill axis from any content-based minimum, guarding against CSS's
// min-width:auto. Yoga has no such minimum today, so this is currently inert —
// see layout_fill_content_floor_test.dart, which fails if that changes.
// LayoutComponent has no equivalent.
//
// Overrides rather than sits inline so it lands after the min/max Super writes.
void LayoutParticipant::applyBaseStyle(
    YGStyle& style,
    const LayoutSyncContext& context)
{
  LayoutSizingStyle::applyBaseStyle(style, context);

  const LayoutScaleType widthScale = (LayoutScaleType)layoutWidthScaleType();
  const LayoutScaleType heightScale = (LayoutScaleType)layoutHeightScaleType();
  const bool parentIsRow = context.parentIsRow;
  const bool parentIsGridLike = context.parentIsGrid;
  const bool widthFill = widthScale == LayoutScaleType::fill;
  const bool heightFill = heightScale == LayoutScaleType::fill;

  style.dimensions()[YGDimensionWidth] =
      widthScale == LayoutScaleType::fixed
          ? YGValue{std::max(0.0f, width()), (YGUnit)widthUnitsValue()}
          : YGValue{YGUndefined, YGUnitAuto};
  style.dimensions()[YGDimensionHeight] =
      heightScale == LayoutScaleType::fixed
          ? YGValue{std::max(0.0f, height()), (YGUnit)heightUnitsValue()}
          : YGValue{YGUndefined, YGUnitAuto};

  if (parentIsGridLike)
  {
    style.flexGrow() = YGFloatOptional(0.0f);
    style.flexShrink() = YGFloatOptional(0.0f);
    style.alignSelf() = heightFill ? YGAlignStretch : YGAlignAuto;
  }
  else
  {
    bool mainFill = parentIsRow ? widthFill : heightFill;
    float mainFraction = parentIsRow ? fractionalWidth() : fractionalHeight();
    style.flexGrow() = YGFloatOptional(mainFill ? mainFraction : 0.0f);
    style.flexShrink() = YGFloatOptional(mainFill ? mainFraction : 0.0f);
    style.flexBasis() = mainFill ? YGValue{0.0f, YGUnitPoint}
                                 : YGValue{YGUndefined, YGUnitAuto};
    bool crossFill = parentIsRow ? heightFill : widthFill;
    style.alignSelf() = crossFill ? YGAlignStretch : YGAlignAuto;
  }

  if (layoutWidthScaleType() == (uint32_t)LayoutScaleType::fill &&
      (YGUnit)minWidthUnitsValue() == YGUnitUndefined)
  {
    style.minDimensions()[YGDimensionWidth] = YGValue{0.0f, YGUnitPoint};
  }
  if (layoutHeightScaleType() == (uint32_t)LayoutScaleType::fill &&
      (YGUnit)minHeightUnitsValue() == YGUnitUndefined)
  {
    style.minDimensions()[YGDimensionHeight] = YGValue{0.0f, YGUnitPoint};
  }
}

void LayoutParticipant::resync()
{
  auto* host = transformComponent();
  if (host == nullptr)
  {
    return;
  }
  if (m_layoutData == nullptr)
  {
    m_layoutData = new LayoutData();
    LayoutData::useFractionalPixels();
    // Context is us, not the host: the measure func reads hugUnbounded.
    m_layoutData->node.setContext(this);
    m_layoutData->node.setMeasureFunc(participantMeasureFunc);
    // We are our own sizing style.
    addLayoutStyleApplier(this);
  }
  // A sibling placement that cleaned before us was dropped on the floor:
  // addLayoutStyleApplier is a no-op until m_layoutData exists, and
  // onAddedClean runs in file order, so nothing fixes the order for us.
  // Idempotent — appliers are pushed unique.
  if (auto* placement = GridItemPlacement::from(host))
  {
    addLayoutStyleApplier(placement);
  }
  syncStyleChanges();
  if (auto* lc = owningLayout())
  {
    lc->syncLayoutChildren();
  }
  host->addDirt(ComponentDirt::WorldTransform, true);
  markLayoutNodeDirty(true);
}

void* LayoutParticipant::layoutNode(int index)
{
  return m_layoutData != nullptr ? static_cast<void*>(&m_layoutData->node)
                                 : nullptr;
}

Layout LayoutParticipant::solvedLayout() const
{
  if (m_layoutData == nullptr)
  {
    return Layout();
  }
  const auto& l = m_layoutData->node.getLayout();
  return Layout(
      definedOrZero(l.position[YGEdgeLeft]),
      definedOrZero(l.position[YGEdgeTop]),
      definedOrZero(l.dimensions[YGDimensionWidth]),
      definedOrZero(l.dimensions[YGDimensionHeight]));
}

// While animating, the resolved slot is the interpolated animatedLayout;
// otherwise it's read straight from the yoga node (no per-participant cache).
float LayoutParticipant::resolvedLeft() const
{
  return m_animation != nullptr ? m_animation->animatedLayout.left()
                                : solvedLayout().left();
}
float LayoutParticipant::resolvedTop() const
{
  return m_animation != nullptr ? m_animation->animatedLayout.top()
                                : solvedLayout().top();
}
float LayoutParticipant::resolvedWidth() const
{
  return m_animation != nullptr ? m_animation->animatedLayout.width()
                                : solvedLayout().width();
}
float LayoutParticipant::resolvedHeight() const
{
  return m_animation != nullptr ? m_animation->animatedLayout.height()
                                : solvedLayout().height();
}

void LayoutParticipant::applyResolvedLayoutSize()
{
  auto* sizeable = IntrinsicallySizeable::from(transformComponent());
  if (sizeable == nullptr)
  {
    return;
  }
  auto* lc = owningLayout();
  LayoutDirection direction = lc != nullptr ? lc->actualDirection()
                                            : LayoutDirection::inherit;
  // Read the resolved slot once (animated slot, or a single yoga-node read)
  // rather than calling resolvedWidth()/resolvedHeight() separately.
  const Layout resolved = m_animation != nullptr ? m_animation->animatedLayout
                                                 : solvedLayout();
  sizeable->controlSize(
      Vec2D(resolved.width(), resolved.height()),
      (LayoutScaleType)layoutWidthScaleType(),
      (LayoutScaleType)layoutHeightScaleType(),
      direction);
}
#else
float LayoutParticipant::resolvedLeft() const { return 0.0f; }
float LayoutParticipant::resolvedTop() const { return 0.0f; }
float LayoutParticipant::resolvedWidth() const { return 0.0f; }
float LayoutParticipant::resolvedHeight() const { return 0.0f; }
#endif

size_t LayoutParticipant::numLayoutNodes()
{
#ifdef WITH_RIVE_LAYOUT
  return m_layoutData != nullptr ? 1 : 0;
#else
  return 0;
#endif
}

AABB LayoutParticipant::layoutBounds()
{
#ifdef WITH_RIVE_LAYOUT
  // Read the resolved slot once (animated slot, or a single yoga-node read)
  // instead of resolvedLeft/Top/Width/Height each re-reading it.
  const Layout resolved = m_animation != nullptr ? m_animation->animatedLayout
                                                 : solvedLayout();
  return AABB::fromLTWH(
      resolved.left(),
      resolved.top(),
      resolved.width(),
      resolved.height());
#else
  return AABB::fromLTWH(0.0f, 0.0f, 0.0f, 0.0f);
#endif
}

AABB LayoutParticipant::layoutBoundsForNode(int index)
{
#ifdef WITH_RIVE_LAYOUT
#endif
  return layoutBounds();
}

bool LayoutParticipant::syncStyleChanges()
{
#ifdef WITH_RIVE_LAYOUT
  if (m_layoutData == nullptr)
  {
    return false;
  }
  YGNode& node = m_layoutData->node;
  // Appliers write straight into the node's own style; no scratch copy.
  YGStyle& ygStyle = m_layoutData->style();

  LayoutScaleType widthScale = (LayoutScaleType)layoutWidthScaleType();
  LayoutScaleType heightScale = (LayoutScaleType)layoutHeightScaleType();

  auto* lc = owningLayout();
  bool parentIsRow = lc != nullptr ? lc->mainAxisIsRow() : true;
  bool parentIsGridLike = lc != nullptr && lc->style() != nullptr &&
                          lc->style()->isGrid();

  bool needsMeasure = widthScale == LayoutScaleType::hug ||
                      heightScale == LayoutScaleType::hug;
  if (needsMeasure)
  {
    node.setContext(this);
    node.setMeasureFunc(participantMeasureFunc);
  }
  else
  {
    node.setMeasureFunc(nullptr);
  }

  bool parentIsStack = lc != nullptr && lc->style() != nullptr &&
                       lc->style()->isStack();
  uint32_t containerJustifyItems = (lc != nullptr && lc->style() != nullptr)
                                       ? lc->style()->justifyItemsValue()
                                       : (uint32_t)YGJustifyStretch;
  // Appliers last, before the style reaches the node. A participant's
  // GridItemPlacement hangs off the same Node that owns this participant.
  LayoutSyncContext syncContext;
  syncContext.parentIsGrid = parentIsGridLike;
  syncContext.parentIsStack = parentIsStack;
  syncContext.containerJustifyItems = containerJustifyItems;
  syncContext.inlineHugs = widthScale == LayoutScaleType::hug;
  syncContext.widthFills = widthScale == LayoutScaleType::fill;
  syncContext.parentIsRow = parentIsRow;
  syncContext.isLTR = lc == nullptr ||
                      lc->actualDirection() != LayoutDirection::rtl;
  syncContext.hasLayoutParent = lc != nullptr;
  m_layoutData->applyLayoutStyles(ygStyle, syncContext);

  node.markDirtyAndPropagate();
  // Fold display:none into the host's collapse so it stops drawing (it's
  // already removed from the layout flow via the yoga display above).
  if (auto* host = transformComponent())
  {
    auto* p = host->parent();
    bool parentHidesHost = p != nullptr && p->isCollapsed();
    // A Solo hides its non-active children; mirror that here so folding our
    // display doesn't reveal an inactive Solo child. (Dart re-dispatches
    // through the parent's collapse; C++ has no host mixin, so we check
    // it.)
    if (p != nullptr && p->is<Solo>())
    {
      auto* solo = p->as<Solo>();
      auto* ab = solo->artboard();
      Core* active = ab != nullptr ? ab->resolve(solo->activeComponentId())
                                   : nullptr;
      if (active != host)
      {
        parentHidesHost = true;
      }
    }
    host->collapse(
        parentHidesHost || (YGDisplay)displayValue() == YGDisplayNone);
  }
  return true;
#else
  return false;
#endif
}

void LayoutParticipant::updateLayoutBounds(bool animate)
{
#ifdef WITH_RIVE_LAYOUT
  if (m_layoutData == nullptr)
  {
    return;
  }
  YGNode& node = m_layoutData->node;
  if (!node.getHasNewLayout())
  {
    return;
  }
  node.setHasNewLayout(false);

  Layout newLayout = solvedLayout();
  // Animate only when under an animated layout (m_animation allocated), the
  // animate flag is set, and we've solved before (so we snap on first
  // appearance instead of animating in from 0,0).
  if (m_animation != nullptr && animate && m_hasSolvedLayout)
  {
    // Retarget: animate from where we are now to the newly solved slot,
    // smoothing over any in-flight animation (mirrors LayoutComponent).
    auto* animationData = currentAnimationData();
    if (newLayout != animationData->to)
    {
      if (animationData->elapsedSeconds != 0.0f)
      {
        if (m_animation->isSmoothing)
        {
          m_animation->a.copy(m_animation->b);
        }
        m_animation->isSmoothing = true;
      }
      else
      {
        m_animation->isSmoothing = false;
      }
      animationData = currentAnimationData();
      animationData->from = m_animation->animatedLayout;
      animationData->to = newLayout;
      animationData->elapsedSeconds = 0.0f;
    }
  }
  else if (m_animation != nullptr)
  {
    // Snap the animated slot (first solve, or the animate flag is off).
    m_animation->animatedLayout = newLayout;
    m_animation->a.to = newLayout;
  }
  // else: not animating — resolvedLeft etc. read the yoga node directly.
  m_hasSolvedLayout = true;
  applyResolvedLayoutSize();
  if (auto* host = transformComponent())
  {
    host->addDirt(ComponentDirt::WorldTransform, true);
  }
#endif
}

void LayoutParticipant::markLayoutNodeDirty(bool shouldForceUpdateLayoutBounds)
{
#ifdef WITH_RIVE_LAYOUT
  if (m_layoutData != nullptr)
  {
    m_layoutData->node.markDirtyAndPropagate();
  }
  if (auto* lc = owningLayout())
  {
    lc->markLayoutNodeDirty(shouldForceUpdateLayoutBounds);
  }
#endif
}

void LayoutParticipant::onSizingChanged()
{
#ifdef WITH_RIVE_LAYOUT
  syncStyleChanges();
  markLayoutNodeDirty();
#endif
}

// ── Layout animation. The participant has no animation style of its own; it
// inherits the parent layout's (stored via cascadeLayoutStyle) and interpolates
// its resolved slot toward each newly solved layout, advanced each frame as an
// AdvancingComponent.

LayoutAnimationData* LayoutParticipant::currentAnimationData()
{
  // Only called while animating (m_animation != nullptr).
  return m_animation->isSmoothing ? &m_animation->b : &m_animation->a;
}

bool LayoutParticipant::animates() const { return m_animation != nullptr; }

LayoutStyleInterpolation LayoutParticipant::interpolation() const
{
  return m_animation != nullptr ? m_animation->interpolation
                                : LayoutStyleInterpolation::hold;
}

float LayoutParticipant::interpolationTime() const
{
  return m_animation != nullptr ? m_animation->interpolationTime : 0.0f;
}

KeyFrameInterpolator* LayoutParticipant::interpolator() const
{
  return m_animation != nullptr ? m_animation->interpolator : nullptr;
}

AdvancingComponent::QuietState LayoutParticipant::quietState()
{
#ifdef WITH_RIVE_LAYOUT
  // The early outs of advanceComponent and applyInterpolation.
  if (m_animation == nullptr ||
      currentAnimationData()->to == m_animation->animatedLayout)
  {
    return QuietState::quiet;
  }
  return QuietState::busy;
#else
  return QuietState::quiet;
#endif
}

bool LayoutParticipant::advanceComponent(
    float elapsedSeconds,
    AdvanceFlags flags)
{
#ifdef WITH_RIVE_LAYOUT
  if (m_animation == nullptr ||
      (flags & AdvanceFlags::NewFrame) != AdvanceFlags::NewFrame)
  {
    return false;
  }
  return applyInterpolation(
      elapsedSeconds,
      (flags & AdvanceFlags::Animate) == AdvanceFlags::Animate ||
          (flags & AdvanceFlags::AdvanceNested) == AdvanceFlags::AdvanceNested);
#else
  return false;
#endif
}

#ifdef WITH_RIVE_LAYOUT
bool LayoutParticipant::cascadeLayoutStyle(
    LayoutStyleInterpolation inheritedInterpolation,
    KeyFrameInterpolator* inheritedInterpolator,
    float inheritedInterpolationTime,
    LayoutDirection direction)
{
  // A participant has no animation style of its own; it inherits the parent
  // layout's. Allocate the animation state only while it actually animates.
  bool willAnimate = inheritedInterpolation != LayoutStyleInterpolation::hold &&
                     inheritedInterpolationTime > 0.0f;
  if (willAnimate)
  {
    if (m_animation == nullptr)
    {
      m_animation = new ParticipantAnimation();
      // Seed from the current resolved slot so enabling animation
      // mid-life doesn't animate in from 0.
      Layout current = solvedLayout();
      m_animation->animatedLayout = current;
      m_animation->a.from = current;
      m_animation->a.to = current;
    }
    m_animation->interpolation = inheritedInterpolation;
    m_animation->interpolator = inheritedInterpolator;
    m_animation->interpolationTime = inheritedInterpolationTime;
  }
  else if (m_animation != nullptr)
  {
    // Parent no longer animates: drop the state and snap from here on.
    delete m_animation;
    m_animation = nullptr;
  }
  return willAnimate;
}

bool LayoutParticipant::applyInterpolation(float elapsedSeconds, bool animate)
{
  if (m_animation == nullptr)
  {
    return false;
  }
  auto* animationData = currentAnimationData();
  if (!animate || animationData->to == m_animation->animatedLayout)
  {
    return false;
  }
  if (m_animation->isSmoothing)
  {
    float f = std::fmin(
        1.0f,
        interpolationTime() > 0.0f
            ? m_animation->a.elapsedSeconds / interpolationTime()
            : 1.0f);
    if (interpolation() != LayoutStyleInterpolation::linear &&
        interpolator() != nullptr)
    {
      f = interpolator()->transform(f);
    }
    m_animation->b.from = m_animation->a.interpolate(f);
    if (f == 1.0f)
    {
      m_animation->a.copy(m_animation->b);
      m_animation->isSmoothing = false;
    }
    else
    {
      m_animation->a.elapsedSeconds += elapsedSeconds;
    }
  }

  animationData = currentAnimationData();
  if (animationData->elapsedSeconds >= interpolationTime())
  {
    m_animation->animatedLayout = animationData->to;
    if (m_animation->isSmoothing)
    {
      m_animation->isSmoothing = false;
      m_animation->a.copy(m_animation->b);
      m_animation->a.elapsedSeconds = m_animation->b.elapsedSeconds = 0.0f;
    }
    else
    {
      m_animation->a.elapsedSeconds = 0.0f;
    }
    applyResolvedLayoutSize();
    if (auto* host = transformComponent())
    {
      host->addDirt(ComponentDirt::WorldTransform, true);
    }
    return false;
  }

  float f = std::fmin(
      1.0f,
      interpolationTime() > 0.0f
          ? animationData->elapsedSeconds / interpolationTime()
          : 1.0f);
  if (interpolation() != LayoutStyleInterpolation::linear &&
      interpolator() != nullptr)
  {
    f = interpolator()->transform(f);
  }
  auto current = animationData->interpolate(f);
  if (m_animation->animatedLayout != current)
  {
    m_animation->animatedLayout = current;
    applyResolvedLayoutSize();
    if (auto* host = transformComponent())
    {
      host->addDirt(ComponentDirt::WorldTransform, true);
    }
  }
  animationData->elapsedSeconds += elapsedSeconds;
  return f != 1.0f;
}
#endif
