#include "rive/solo.hpp"
#include "rive/constraints/constraint.hpp"
#include "rive/shapes/clipping_shape.hpp"
#include "rive/focus_data.hpp"
#include "rive/semantic/semantic_data.hpp"
#include "rive/artboard.hpp"
#include "rive/node.hpp"
#include "rive/container_component.hpp"
#include "rive/transform_component.hpp"
#include "rive/layout_component.hpp"
#include "rive/layout/layout_node_provider.hpp"

using namespace rive;

// Some child components shouldn't be considered as part of the solo set as they
// are more akin to properties/metadata of the solo itself (constraints,
// clipping shapes, focus and semantic data) rather than selectable solo
// options. These are excluded both from collapse propagation and from
// index/name based selection so that data binding targets only the real solo
// options.
static bool isSoloSetMember(Component* child)
{
    return !(child->is<Constraint>() || child->is<ClippingShape>() ||
             child->is<FocusData>() || child->is<SemanticData>());
}

Component* Solo::activeComponent()
{
    auto* ab = artboard();
    Core* active = ab != nullptr ? ab->resolve(activeComponentId()) : nullptr;
    // The active id refers to one of our children; match by pointer so we get
    // it typed as a Component.
    for (Component* child : children())
    {
        if (child == active)
        {
            return child;
        }
    }
    return nullptr;
}

#ifdef WITH_RIVE_LAYOUT
void Solo::recollectOwningLayout()
{
    // We are not a LayoutComponent, so walk up for the layout that owns the
    // slot our active child occupies.
    for (Component* p = parent(); p != nullptr; p = p->parent())
    {
        if (p->is<LayoutComponent>())
        {
            p->as<LayoutComponent>()->syncLayoutChildren();
            return;
        }
    }
}
#endif

void Solo::propagateCollapse(bool collapse)
{
    Core* active =
        collapse ? nullptr : artboard()->resolve(activeComponentId());
    for (Component* child : children())
    {
        // For components that aren't part of the solo set, simply pass on the
        // collapse value of the solo itself.
        if (!isSoloSetMember(child))
        {
            child->collapse(collapse);
            continue;
        }

        // This child is part of the solo set so only make it active if it's the
        // currently marked solo object.
        child->collapse(child != active);
    }
}

bool Solo::collapse(bool value)
{
    // Intentionally using Component instead of Super as we don't want to call
    // collapse on the Container logic which just propagates blindly to
    // children.
    if (!Component::collapse(value))
    {
        return false;
    }
    propagateCollapse(value);
    return true;
}

void Solo::activeComponentIdChanged()
{
    propagateCollapse(isCollapsed());
#ifdef WITH_RIVE_LAYOUT
    // Only the active child is exposed to layout, so a swap changes the owning
    // layout's child set.
    recollectOwningLayout();
#endif
}

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

#ifdef WITH_RIVE_EDITOR
    // Coop-apply runs Pass 4 onAddedClean before a renderer is attached;
    // `propagateCollapse` fires `onDirty` on every child, which in
    // subclasses like Image/Mesh allocates render buffers via the
    // factory — so skip during hydration (post-validation edits re-fire
    // it via activeComponentIdChanged). Runtime .riv imports are marked
    // validated at read time and need it now or inactive Solo children
    // render un-collapsed.
    if (hasValidated())
#endif
    {
        propagateCollapse(isCollapsed());
#ifdef WITH_RIVE_LAYOUT
        // Parent chain + active child are resolved now; make sure the owning
        // layout has collected the active child.
        recollectOwningLayout();
#endif
    }
    return StatusCode::Ok;
}

void Solo::updateByIndex(size_t index)
{
    // The number of solo options is always <= children().size(), so any index
    // that big can never match. Bail early to avoid an O(n) walk every frame
    // for out-of-range indices (the data-binding path casts rounded floats to
    // size_t without clamping, so negative values arrive as huge indices).
    if (!artboard() || index >= children().size())
    {
        return;
    }
    // The index refers to the Nth solo option, skipping property-like children
    // (constraints, clipping shapes, focus/semantic data) so it matches the
    // ordering exposed by getActiveChildIndex.
    size_t soloIndex = 0;
    for (auto& child : children())
    {
        if (!isSoloSetMember(child))
        {
            continue;
        }
        if (soloIndex == index)
        {
            activeComponentId(artboard()->idOf(child));
            return;
        }
        soloIndex++;
    }
}

void Solo::updateByName(const std::string& name)
{
    if (!artboard())
    {
        return;
    }
    for (auto& child : children())
    {
        if (!isSoloSetMember(child))
        {
            continue;
        }
        if (child->name() == name)
        {

            int globalIndex = artboard()->idOf(child);
            activeComponentId(globalIndex);
            break;
        }
    }
}

int Solo::getActiveChildIndex()
{
    if (!artboard())
    {
        return -1;
    }
    Core* active = artboard()->resolve(activeComponentId());
    if (active)
    {
        int index = 0;
        for (auto& child : children())
        {
            if (!isSoloSetMember(child))
            {
                continue;
            }
            if (child == active)
            {
                return index;
            }
            index++;
        }
    }
    return -1;
}

std::string Solo::getActiveChildName()
{
    if (!artboard())
    {
        return "";
    }
    Core* active = artboard()->resolve(activeComponentId());
    if (active && active->is<Component>())
    {
        return active->as<Component>()->name();
    }
    return "";
}
