#include "rive/semantic/semantic_provider.hpp"

#include "rive/artboard.hpp"
#include "rive/component.hpp"
#include "rive/container_component.hpp"
#include "rive/math/mat2d.hpp"
#include "rive/node.hpp"
#include "rive/semantic/semantic_data.hpp"
#include "semantic_inference_registry.hpp"

using namespace rive;

static bool tryNodeWorldBounds(Node* node, AABB& outBounds)
{
    if (node == nullptr)
    {
        return false;
    }

    const auto localBounds = node->localBounds();
    if (localBounds.isEmptyOrNaN())
    {
        return false;
    }
    const auto worldTransform = node->worldTransform();
    const auto worldBounds = worldTransform.mapBoundingBox(localBounds);
    if (worldBounds.isEmptyOrNaN())
    {
        return false;
    }
    outBounds = worldBounds;
    return true;
}

AABB SemanticProvider::rootTransformAABB(Artboard* ab, const AABB& bounds)
{
    AABB out = AABB::forExpansion();
    AABB::expandTo(out, ab->rootTransform({bounds.minX, bounds.minY}));
    AABB::expandTo(out, ab->rootTransform({bounds.maxX, bounds.minY}));
    AABB::expandTo(out, ab->rootTransform({bounds.maxX, bounds.maxY}));
    AABB::expandTo(out, ab->rootTransform({bounds.minX, bounds.maxY}));
    return out;
}

bool SemanticProvider::canInferSemantics(Component* component)
{
    return supportsInferredSemantics(component);
}

ResolvedSemanticData SemanticProvider::resolveSemanticData(Component* component)
{
    ResolvedSemanticData out;
    if (component == nullptr || !component->is<Node>())
    {
        return out;
    }

    if (auto* sd = component->as<Node>()->firstChild<SemanticData>())
    {
        out.hasSemantics = true;
        out.role = sd->role();
        out.label = sd->label();
        return out;
    }

    // Inference fallback (Text -> label)
    resolveInferredSemantics(component, out);

    return out;
}

// Computes world-space bounds for a component. Three strategies:
// 1. Drawable nodes: localBounds() → worldTransform → rootTransform
// 2. Container nodes: merge bounds of all direct Node children
// 3. Fallback: world transform translation (degenerate point bounds)
AABB SemanticProvider::semanticBounds(Component* component)
{
    if (component == nullptr || !component->is<Node>())
    {
        return AABB();
    }

    auto* node = component->as<Node>();

    AABB worldBounds;
    if (tryNodeWorldBounds(node, worldBounds))
    {
        auto* ab = node->artboard();
        if (ab != nullptr)
        {
            return rootTransformAABB(ab, worldBounds);
        }
        return worldBounds;
    }

    // If this semantic node is a non-drawable container/group, derive bounds
    // from visual descendant nodes. ContainerComponent::forEachChild walks
    // the whole subtree (not just direct children): the predicate runs for
    // each descendant, and returning `true` tells forEachChild to keep
    // descending into that descendant's children. We always return true so
    // every Node descendant contributes bounds; non-Node descendants and
    // Nodes without valid bounds are skipped but their subtrees are still
    // walked.
    if (component->is<ContainerComponent>())
    {
        AABB merged = AABB::forExpansion();
        bool hasDescendantBounds = false;
        component->as<ContainerComponent>()->forEachChild(
            [&](Component* child) -> bool {
                if (child == nullptr || !child->is<Node>())
                {
                    return true;
                }

                AABB childBounds;
                if (!tryNodeWorldBounds(child->as<Node>(), childBounds))
                {
                    return true;
                }

                merged.expand(childBounds);
                hasDescendantBounds = true;
                return true;
            });

        if (hasDescendantBounds)
        {
            auto* ab = node->artboard();
            if (ab != nullptr)
            {
                return rootTransformAABB(ab, merged);
            }
            return merged;
        }
    }

    // Fallback for nodes/components without local bounds.
    const auto worldTransform = node->worldTransform();
    const float x = worldTransform[4];
    const float y = worldTransform[5];
    auto* ab = node->artboard();
    if (ab != nullptr)
    {
        Vec2D pos = ab->rootTransform(Vec2D(x, y));
        return AABB(pos.x, pos.y, pos.x, pos.y);
    }
    return AABB(x, y, x, y);
}
