#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);
}
