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

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

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