#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_provider.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();

        // Take the node out of the focus tree. Its own manager pointer is the
        // normal route, but a node can end up without one (a detach that was
        // never paired with a re-add, or a manager torn down around it). Left
        // parented, such a node survives with a null focusable, which is a
        // state nothing else can clean up.
        //
        // Fall back to the nearest ancestor that still knows its manager, so
        // removal keeps clearing focus and invalidating the manager's cached
        // focusable-content answer; only when nothing in the chain is
        // registered do we settle for a plain detach.
        FocusManager* manager = m_focusNode->manager();
        if (manager == nullptr)
        {
            for (FocusNode* p = m_focusNode->parent(); p != nullptr;
                 p = p->parent())
            {
                if (p->manager() != nullptr)
                {
                    manager = p->manager();
                    break;
                }
            }
        }
        if (manager != nullptr)
        {
            manager->removeChild(m_focusNode);
        }
        else
        {
            m_focusNode->removeFromParent();
        }
        // 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((focusFlags() & canFocusBitmask) != 0);
        m_focusNode->canTouch((focusFlags() & canTouchBitmask) != 0);
        m_focusNode->canTraverse((focusFlags() & canTraverseBitmask) != 0);
        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::addGamepadListener(GamepadListener* listener)
{
    m_gamepadListeners.push_back(listener);
}

void FocusData::removeGamepadListener(GamepadListener* listener)
{
    auto it = std::find(m_gamepadListeners.begin(),
                        m_gamepadListeners.end(),
                        listener);
    if (it != m_gamepadListeners.end())
    {
        m_gamepadListeners.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;
}

bool FocusData::selectedText(std::string& outText) const
{
    // Mirror the TextInput special case in KeyboardListenerGroup's
    // key/text routing: the focus target for a text input is a FocusData
    // child whose parent is the TextInput itself.
    Component* target = parent();
    if (target != nullptr && target->is<TextInput>())
    {
        return target->as<TextInput>()->selectedText(outText);
    }
    return false;
}

bool FocusData::gamepadDispatch(
    const ListenerInvocation& invocation,
    ScriptedDrawable** outDispatchedScriptedDrawable)
{
    for (auto* listener : m_gamepadListeners)
    {
        if (listener->gamepadDispatch(invocation,
                                      outDispatchedScriptedDrawable))
        {
            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);
    }

    auto* parentComponent = parent();
    if (parentComponent != nullptr && parentComponent->is<TextInput>())
    {
        parentComponent->as<TextInput>()->focused();
    }
}

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

    auto* parentComponent = parent();
    if (parentComponent != nullptr && parentComponent->is<TextInput>())
    {
        parentComponent->as<TextInput>()->blurred();
    }
}

void FocusData::focusFlagsChanged()
{
    if (m_focusNode != nullptr)
    {
        m_focusNode->canFocus((focusFlags() & canFocusBitmask) != 0);
        m_focusNode->canTouch((focusFlags() & canTouchBitmask) != 0);
        m_focusNode->canTraverse((focusFlags() & canTraverseBitmask) != 0);
    }
}

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

bool FocusData::worldBounds(AABB& outBounds)
{
    auto* parentComponent = parent();
    if (parentComponent == nullptr || !parentComponent->is<LayoutComponent>())
    {
        return false;
    }
    AABB bounds = parentComponent->as<LayoutComponent>()->worldBounds();
    // Transform to root artboard space (handles nested artboards); all four
    // corners so rotated/skewed hosts still yield a valid AABB.
    auto* ab = artboard();
    if (ab != nullptr)
    {
        bounds = SemanticProvider::rootTransformAABB(ab, bounds);
    }
    outBounds = bounds;
    return true;
}

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

    AABB bounds;
    if (worldBounds(bounds))
    {
        m_focusNode->worldBounds(bounds);
    }
    else
    {
        m_focusNode->clearWorldBounds();
    }
}