#include "rive/focus_data.hpp"
#include "rive/artboard.hpp"
#include "rive/artboard_component_list.hpp"
#include "rive/artboard_host.hpp"
#include "rive/component.hpp"
#include "rive/constraints/scrolling/scroll_constraint.hpp"
#include "rive/drawable.hpp"
#include "rive/input/focusable.hpp"
#include "rive/input/focus_listener.hpp"
#include "rive/input/focus_manager.hpp"
#include "rive/layout_component.hpp"
#include "rive/math/mat2d.hpp"
#include "rive/nested_artboard.hpp"
#include "rive/node.hpp"
#include "rive/parent_traversal.hpp"
#include "rive/semantic/semantic_data.hpp"
#include "rive/semantic/semantic_state.hpp"
#include "rive/text/text_input.hpp"
#include "rive/transform_component.hpp"
#include "rive/world_transform_component.hpp"
#include <algorithm>

using namespace rive;

namespace
{
SemanticData* findSiblingSemanticData(Component* self)
{
    auto* parentNode = self->parent();
    if (parentNode == nullptr || !parentNode->is<Node>())
    {
        return nullptr;
    }
    return parentNode->as<Node>()->firstChild<SemanticData>();
}
} // namespace

FocusData::~FocusData()
{
    if (m_focusNode != nullptr)
    {
        // Clear the focusable pointer first to prevent callbacks during removal
        m_focusNode->clearFocusable();

        // Remove from manager if registered
        auto* manager = m_focusNode->manager();
        if (manager != nullptr)
        {
            manager->removeChild(m_focusNode);
        }
        // m_focusNode (rcp) is released automatically when this destructor ends
    }
}

rcp<FocusNode> FocusData::focusNode()
{
    if (m_focusNode == nullptr)
    {
        m_focusNode = rcp<FocusNode>(new FocusNode(this));
        m_focusNode->canFocus(m_CanFocus);
        m_focusNode->canTouch(m_CanTouch);
        m_focusNode->canTraverse(m_CanTraverse);
        m_focusNode->edgeBehavior(
            static_cast<EdgeBehavior>(m_EdgeBehaviorValue));
        m_focusNode->name(name());
        // Set initial world bounds if available
        updateWorldBounds();
    }
    return m_focusNode;
}

void FocusData::addFocusListener(FocusListener* listener)
{
    m_focusListeners.push_back(listener);
}

void FocusData::removeFocusListener(FocusListener* listener)
{
    auto it =
        std::find(m_focusListeners.begin(), m_focusListeners.end(), listener);
    if (it != m_focusListeners.end())
    {
        m_focusListeners.erase(it);
    }
}

void FocusData::addKeyboardListener(KeyboardListener* listener)
{
    m_keyboardListeners.push_back(listener);
}

void FocusData::removeKeyboardListener(KeyboardListener* listener)
{
    auto it = std::find(m_keyboardListeners.begin(),
                        m_keyboardListeners.end(),
                        listener);
    if (it != m_keyboardListeners.end())
    {
        m_keyboardListeners.erase(it);
    }
}

void FocusData::addTextInputListener(KeyboardListener* listener)
{
    m_textInputListeners.push_back(listener);
}

void FocusData::removeTextInputListener(KeyboardListener* listener)
{
    auto it = std::find(m_textInputListeners.begin(),
                        m_textInputListeners.end(),
                        listener);
    if (it != m_textInputListeners.end())
    {
        m_textInputListeners.erase(it);
    }
}

void FocusData::focus()
{
    // Note: In C++ runtime, focus() needs a FocusManager to set focus.
    // The StateMachineInstance will handle this through its own FocusManager.
    // This method is provided for API completeness but the actual focus
    // setting happens through StateMachineInstance::setFocus(FocusData*).
}

bool FocusData::keyInput(Key value,
                         KeyModifiers modifiers,
                         bool isPressed,
                         bool isRepeat)
{
    // Notify listeners
    for (auto* listener : m_keyboardListeners)
    {
        if (listener->keyInput(value, modifiers, isPressed, isRepeat))
        {
            return true;
        }
    }
    return false;
}

bool FocusData::textInput(const std::string& text)
{

    for (auto* listener : m_textInputListeners)
    {
        if (listener->textInput(text))
        {
            return true;
        }
    }
    return false;
}

void FocusData::scrollIntoView()
{
    // Find closest LayoutComponent ancestor
    Component* layoutComponent = parent();
    while (layoutComponent != nullptr &&
           !layoutComponent->is<LayoutComponent>())
    {
        layoutComponent = layoutComponent->parent();
    }
    if (layoutComponent == nullptr)
    {
        return;
    }

    // Get element bounds in its artboard's world space.
    // We'll transform these bounds as we cross artboard boundaries.
    AABB elementBounds = layoutComponent->as<LayoutComponent>()->worldBounds();

    // Walk up the hierarchy finding all ScrollConstraints.
    // This traversal crosses artboard boundaries via the host chain.
    ParentTraversal traversal(this);
    while (auto* p = traversal.next())
    {
        // When crossing an artboard boundary, transform element bounds from
        // nested artboard space to parent artboard space.
        if (traversal.didCrossBoundary())
        {
            auto* host = traversal.crossingHost();
            auto* sourceArtboard = traversal.sourceArtboard();
            auto* artboardInstance =
                sourceArtboard->is<ArtboardInstance>()
                    ? sourceArtboard->as<ArtboardInstance>()
                    : nullptr;
            Mat2D hostTransform =
                host->worldTransformForArtboard(artboardInstance);
            Vec2D min =
                hostTransform * Vec2D(elementBounds.minX, elementBounds.minY);
            Vec2D max =
                hostTransform * Vec2D(elementBounds.maxX, elementBounds.maxY);
            elementBounds = AABB(min.x, min.y, max.x, max.y);
        }

        // ScrollConstraint is a Constraint that targets Content, so we check
        // TransformComponent::constraints() to find ScrollConstraints.
        if (p->is<TransformComponent>())
        {
            auto* tc = p->as<TransformComponent>();

            for (auto* constraint : tc->constraints())
            {
                if (!constraint->is<ScrollConstraint>())
                {
                    continue;
                }

                scrollConstraintToShowBounds(constraint->as<ScrollConstraint>(),
                                             elementBounds);
            }
        }
    }
}

void FocusData::scrollConstraintToShowBounds(ScrollConstraint* constraint,
                                             const AABB& elementBounds)
{
    auto* content = constraint->content();
    auto* viewport = constraint->viewport();
    if (content == nullptr || viewport == nullptr)
    {
        return;
    }

    // Get viewport position in world space.
    const Mat2D& viewportTransform = viewport->worldTransform();
    float viewportWorldX = viewportTransform[4];
    float viewportWorldY = viewportTransform[5];

    float viewportWidth = constraint->viewportWidth();
    float viewportHeight = constraint->viewportHeight();

    // Element position relative to viewport in world space.
    // This directly tells us where the element appears in the viewport.
    float viewportLeft = elementBounds.minX - viewportWorldX;
    float viewportTop = elementBounds.minY - viewportWorldY;
    float viewportRight = elementBounds.maxX - viewportWorldX;
    float viewportBottom = elementBounds.maxY - viewportWorldY;

    // Use effective scroll offset (target if animating) to handle rapid focus
    // changes.
    float effectiveScrollX = constraint->effectiveScrollOffsetX();
    float effectiveScrollY = constraint->effectiveScrollOffsetY();

    float deltaX = 0.0f;
    float deltaY = 0.0f;

    // Calculate horizontal scroll adjustment.
    if (constraint->constrainsHorizontal())
    {
        float elementWidth = viewportRight - viewportLeft;
        if (elementWidth > viewportWidth)
        {
            // Oversized element: keep the left edge visible.
            deltaX = -viewportLeft;
        }
        else if (viewportLeft < 0)
        {
            // Element is to the left of viewport, scroll right (increase
            // offset)
            deltaX = -viewportLeft;
        }
        else if (viewportRight > viewportWidth)
        {
            // Element is to the right of viewport, scroll left (decrease
            // offset)
            deltaX = -(viewportRight - viewportWidth);
        }
    }

    // Calculate vertical scroll adjustment
    if (constraint->constrainsVertical())
    {
        float elementHeight = viewportBottom - viewportTop;
        if (elementHeight > viewportHeight)
        {
            // Oversized element: keep the top edge visible.
            deltaY = -viewportTop;
        }
        else if (viewportTop < 0)
        {
            // Element is above viewport, scroll up (increase offset)
            deltaY = -viewportTop;
        }
        else if (viewportBottom > viewportHeight)
        {
            // Element is below viewport, scroll down (decrease offset)
            deltaY = -(viewportBottom - viewportHeight);
        }
    }

    // Apply scroll if needed (using animated scroll)
    if (deltaX != 0 || deltaY != 0)
    {
        // Add delta to effective scroll offset to get target position.
        Vec2D current(effectiveScrollX, effectiveScrollY);
        Vec2D target(effectiveScrollX + deltaX, effectiveScrollY + deltaY);
        Vec2D snapped =
            constraint->nearestSnapOffsetInDirection(current, target);
        constraint->scrollToPosition(snapped.x, snapped.y);
    }
}

void FocusData::focused()
{
    // Scroll this element into view, crossing artboard boundaries as needed
    scrollIntoView();

    // Notify listeners
    for (auto* listener : m_focusListeners)
    {
        listener->onFocused();
    }

    // Sync focus state to sibling SemanticData (if any)
    auto* sibling = findSiblingSemanticData(this);
    if (sibling != nullptr)
    {
        sibling->setFocusedState(true);
    }
}

void FocusData::blurred()
{
    for (auto* listener : m_focusListeners)
    {
        listener->onBlurred();
    }

    // Sync focus state to sibling SemanticData (if any)
    auto* sibling = findSiblingSemanticData(this);
    if (sibling != nullptr)
    {
        sibling->setFocusedState(false);
    }
}

void FocusData::canFocusChanged()
{
    if (m_focusNode != nullptr)
    {
        m_focusNode->canFocus(m_CanFocus);
    }
}

void FocusData::canTouchChanged()
{
    if (m_focusNode != nullptr)
    {
        m_focusNode->canTouch(m_CanTouch);
    }
}

void FocusData::canTraverseChanged()
{
    if (m_focusNode != nullptr)
    {
        m_focusNode->canTraverse(m_CanTraverse);
    }
}

void FocusData::edgeBehaviorValueChanged()
{
    if (m_focusNode != nullptr)
    {
        m_focusNode->edgeBehavior(
            static_cast<EdgeBehavior>(m_EdgeBehaviorValue));
    }
}

FocusData* FocusData::findParentFocusData() const
{
    // FocusData's parent is typically a Node. Walk up from the parent
    // to find any ancestor Node that has a FocusData child.
    auto* current = parent();
    while (current != nullptr)
    {
        if (current->is<Node>())
        {
            auto* node = current->as<Node>();
            for (auto* child : node->children())
            {
                if (child->is<FocusData>() && child != this)
                {
                    return child->as<FocusData>();
                }
            }
        }
        current = current->parent();
    }
    return nullptr;
}

rcp<FocusNode> FocusData::findClosestFocusNode(Component* component)
{
    if (component == nullptr)
    {
        return nullptr;
    }

    auto* current = component->parent();
    while (current != nullptr)
    {
        // Check if we've hit an artboard boundary
        if (current->is<Artboard>())
        {
            auto* artboard = current->as<Artboard>();
            // Try to cross the artboard boundary via the host component
            auto* host = artboard->host();
            if (host != nullptr)
            {
                auto* hostComponent = host->hostComponent();
                if (hostComponent != nullptr &&
                    hostComponent->is<ContainerComponent>())
                {
                    // Continue searching from the host component (e.g.,
                    // NestedArtboard)
                    current = hostComponent->as<ContainerComponent>();
                    continue;
                }
            }
#ifdef WITH_RIVE_TOOLS
            // Fall back to externally-set parent focus node (editor scenario)
            auto externalNode = artboard->externalParentFocusNode();
            if (externalNode != nullptr)
            {
                return externalNode;
            }
#endif
            // No way to traverse up, stop searching
            return nullptr;
        }

        // Check if this node has a FocusData child
        if (current->is<Node>())
        {
            for (auto* child : current->as<Node>()->children())
            {
                if (child->is<FocusData>())
                {
                    return child->as<FocusData>()->focusNode();
                }
            }
        }

        current = current->parent();
    }
    return nullptr;
}

namespace
{

bool componentAllowsFocusTraversal(const Component* c)
{
    if (c == nullptr || c->isCollapsed())
    {
        return false;
    }
    if (c->is<Drawable>())
    {
        if (c->as<Drawable>()->isHidden())
        {
            return false;
        }
    }
    if (c->is<TransformComponent>())
    {
        if (c->as<TransformComponent>()->renderOpacity() <= 0.0f)
        {
            return false;
        }
    }
    return true;
}

} // namespace

bool FocusData::isEligibleForFocusTraversal() const
{
    if (isCollapsed())
    {
        return false;
    }
    Component* start = parent();
    if (start == nullptr)
    {
        return true;
    }
    if (!componentAllowsFocusTraversal(start))
    {
        return false;
    }
    ParentTraversal traversal(start);
    while (true)
    {
        ContainerComponent* p = traversal.next();
        if (p == nullptr)
        {
            break;
        }
        if (!componentAllowsFocusTraversal(p))
        {
            return false;
        }
        if (traversal.didCrossBoundary())
        {
            ArtboardHost* host = traversal.crossingHost();
            if (host != nullptr)
            {
                Component* hc = host->hostComponent();
                if (hc != nullptr)
                {
                    if (!componentAllowsFocusTraversal(hc))
                    {
                        return false;
                    }
                    if (hc->is<NestedArtboard>() &&
                        hc->as<NestedArtboard>()->isPaused())
                    {
                        return false;
                    }
                }
            }
        }
    }
    return true;
}

bool FocusData::worldPosition(Vec2D& outPosition)
{
    // Get local position from parent transform component
    auto* parentComponent = parent();
    if (!parentComponent || !parentComponent->is<WorldTransformComponent>())
    {
        return false;
    }
    Vec2D localPos =
        parentComponent->as<WorldTransformComponent>()->worldTranslation();

    // Transform to root artboard space (handles nested artboards)
    auto* ab = artboard();
    if (ab)
    {
        outPosition = ab->rootTransform(localPos);
    }
    else
    {
        outPosition = localPos;
    }
    return true;
}

void FocusData::nameChanged()
{
    if (m_focusNode != nullptr)
    {
        m_focusNode->name(name());
    }
}

void FocusData::buildDependencies()
{
    Super::buildDependencies();
    // Depend on parent's world transform so we update when it moves
    auto* parentComponent = parent();
    if (parentComponent != nullptr)
    {
        parentComponent->addDependent(this);
    }
}

void FocusData::update(ComponentDirt value)
{
    if ((value & ComponentDirt::WorldTransform) ==
        ComponentDirt::WorldTransform)
    {
        updateWorldBounds();
    }
}

void FocusData::updateWorldBounds()
{
    if (m_focusNode == nullptr)
    {
        return;
    }

    auto* parentComponent = parent();
    if (parentComponent != nullptr && parentComponent->is<LayoutComponent>())
    {
        // LayoutComponent has worldBounds based on its layout dimensions
        AABB bounds = parentComponent->as<LayoutComponent>()->worldBounds();
        // Transform to root artboard space (handles nested artboards)
        auto* ab = artboard();
        if (ab != nullptr)
        {
            Vec2D min = ab->rootTransform(Vec2D(bounds.minX, bounds.minY));
            Vec2D max = ab->rootTransform(Vec2D(bounds.maxX, bounds.maxY));
            bounds = AABB(min.x, min.y, max.x, max.y);
        }
        m_focusNode->worldBounds(bounds);
    }
    else
    {
        // For non-layout parents, clear bounds (will fall back to position)
        m_focusNode->clearWorldBounds();
    }
}