/*
 * Copyright 2024 Rive
 */

#ifndef _RIVE_FOCUS_NODE_HPP_
#define _RIVE_FOCUS_NODE_HPP_

#include "rive/input/focusable.hpp"
#include "rive/math/aabb.hpp"
#include "rive/refcnt.hpp"
#include <cstdint>
#include <string>
#include <vector>

namespace rive
{

class FocusManager; // Forward declaration
class ListenerInvocation;

enum class EdgeBehavior : uint8_t
{
  parentScope = 0, // Focus exits to parent scope's next focusable
  closedLoop = 1,  // Focus wraps from last to first within this scope
  stop = 2,        // Focus stays on boundary element
};

class FocusNode : public RefCnt<FocusNode>
{
public:
  FocusNode(Focusable* focusable = nullptr) : m_focusable(focusable)
  {
    if (focusable != nullptr)
    {
      setFlag(Flag::kHadFocusable, true);
    }
  }
  ~FocusNode();

  // Transparent structural scope: unbacked (no Focusable) and never a focus
  // target itself, because canFocus and canTraverse are both off. Traversal
  // descends through it to reach focusable descendants — as it does through
  // any non-stop, so this no longer depends on the node being unbacked;
  // empty scopes contribute no focus stops. Used by data-bound
  // nested-artboard hosts and component lists.
  //
  // Any host building a container FocusNode of its own should come through
  // here. A bare FocusNode defaults to canFocus/canTraverse ON, so it is a
  // tab stop in its own right even when its only job is to hold children.
  static rcp<FocusNode> makeStructuralScope()
  {
    auto node = make_rcp<FocusNode>();
    node->canFocus(false);
    node->canTraverse(false);
    node->canTouch(false);
    return node;
  }

  // === Focusable ===

  Focusable* focusable() const { return m_focusable; }
  void setFocusable(Focusable* focusable)
  {
    const bool backingChanged = (m_focusable == nullptr) !=
                                (focusable == nullptr);
    m_focusable = focusable;
    if (focusable != nullptr)
    {
      setFlag(Flag::kHadFocusable, true);
    }
    if (backingChanged)
    {
      invalidateFocusableContent();
    }
  }
  void clearFocusable() { setFocusable(nullptr); }

  /// True once this node has been backed by a Focusable. Never cleared, so a
  /// node whose Focusable was destroyed (~FocusData clears the backing) can
  /// be told apart from a node that legitimately never had one — a
  /// structural scope, or a target a host created through this API. The
  /// former is defunct and must stop being a focus stop; the latter is
  /// still a valid target. See focusNodeEligibleForFocus.
  bool hadFocusable() const { return m_flags & Flag::kHadFocusable; }

  // === Properties (bitfield-backed) ===

  // Master switch: if false, node cannot receive focus at all
  bool canFocus() const { return m_flags & Flag::kCanFocus; }
  void canFocus(bool value)
  {
    if (canFocus() != value)
    {
      setFlag(Flag::kCanFocus, value);
      invalidateFocusableContent();
    }
  }

  // Can receive focus via pointer/touch click
  bool canTouch() const { return m_flags & Flag::kCanTouch; }
  void canTouch(bool value) { setFlag(Flag::kCanTouch, value); }

  // Whether this node's focusable takes part in the capture phase of key
  // events. FocusManager::keyInput only runs the capture phase when a node
  // on the focus path says so, which keeps the plain bubble as cheap as it
  // was for every tree without capture listeners.
  bool capturesKeyInput() const { return m_flags & Flag::kCapturesKeys; }
  void capturesKeyInput(bool value) { setFlag(Flag::kCapturesKeys, value); }

  // Included in tab traversal
  bool canTraverse() const { return m_flags & Flag::kCanTraverse; }
  void canTraverse(bool value) { setFlag(Flag::kCanTraverse, value); }

#ifdef WITH_RIVE_TOOLS
  // Only at edit time, we push down the collapse status of the nodes because
  // we can't get the FocusData node from the FocusNode
  bool isCollapsed() const { return m_isCollapsed; }
  void isCollapsed(bool value) { m_isCollapsed = value; }
#endif
  // True if this node or any descendant currently has focus
  // (set by FocusManager during focus transitions)
  bool hasFocus() const { return m_flags & Flag::kHasFocus; }

  // Note: A node with canFocus=true but canTouch=false and canTraverse=false
  // can still be focused programmatically (via script) and receives text
  // input.

  // Scope status is implicit: a node with children is a scope.
  // EdgeBehavior only applies to scopes (nodes with children). Load-bearing:
  // FocusManager::nextFocusStop gates the edge switch on isScope(), because
  // an edge behavior read off a childless node would let an authored
  // closedLoop wrap that node onto itself and trap focus there.
  EdgeBehavior edgeBehavior() const
  {
    return static_cast<EdgeBehavior>(
        (m_flags >> edgeBehaviorShift) & edgeBehaviorMask);
  }
  void edgeBehavior(EdgeBehavior edge)
  {
    m_flags = (m_flags & ~(edgeBehaviorMask << edgeBehaviorShift)) |
              (static_cast<uint8_t>(edge) << edgeBehaviorShift);
  }

  int tabIndex() const { return m_tabIndex; }
  void tabIndex(int value) { m_tabIndex = static_cast<int16_t>(value); }

  // Debug name (not required to be unique)
  const std::string& name() const { return m_name; }
  void name(const std::string& value) { m_name = value; }

  // === World Bounds (for directional navigation) ===

  // World bounds in root artboard space, used for spatial navigation.
  // Set during update cycle by owner (TextInput, Dart, etc).
  const AABB& worldBounds() const { return m_worldBounds; }
  void worldBounds(const AABB& bounds) { m_worldBounds = bounds; }

  // Check if bounds are available (not empty/invalid)
  bool hasWorldBounds() const { return !m_worldBounds.isEmptyOrNaN(); }

  // Clear bounds (mark as unavailable)
  void clearWorldBounds() { m_worldBounds = AABB(); }

  // === Hierarchy ===

  FocusNode* parent() const { return m_parent; }
  const std::vector<rcp<FocusNode>>& children() const { return m_children; }
  FocusManager* manager() const { return m_manager; }
  bool isScope() const { return !m_children.empty(); }

  void addChild(rcp<FocusNode> child);
  void insertChild(size_t index, rcp<FocusNode> child);
  void removeChild(rcp<FocusNode> child);

  // Remove this node from its current parent (used internally)
  void removeFromParent();

  // === Input Handling (delegates to Focusable) ===

  bool keyInput(Key key, KeyModifiers modifiers, bool isPressed, bool isRepeat)
  {
    return m_focusable
               ? m_focusable->keyInput(key, modifiers, isPressed, isRepeat)
               : false;
  }

  bool captureKeyInput(
      Key key,
      KeyModifiers modifiers,
      bool isPressed,
      bool isRepeat)
  {
    return m_focusable
               ? m_focusable
                     ->captureKeyInput(key, modifiers, isPressed, isRepeat)
               : false;
  }

  bool textInput(const std::string& text)
  {
    return m_focusable ? m_focusable->textInput(text) : false;
  }

  bool gamepadDispatch(
      const ListenerInvocation& invocation,
      ScriptedDrawable** outDispatchedScriptedDrawable = nullptr)
  {
    return m_focusable ? m_focusable->gamepadDispatch(
                             invocation,
                             outDispatchedScriptedDrawable)
                       : false;
  }

  void focused()
  {
    if (m_focusable)
    {
      m_focusable->focused();
    }
  }

  void blurred()
  {
    if (m_focusable)
    {
      m_focusable->blurred();
    }
  }

private:
  friend class FocusManager;

  // Used by FocusManager to update focus state
  void setHasFocus(bool value) { setFlag(Flag::kHasFocus, value); }

  // Tell this node's manager (if any) that its cached
  // hasFocusableContent() answer may be stale. Out-of-line because
  // FocusManager is only forward-declared here.
  void invalidateFocusableContent();

  enum Flag : uint8_t
  {
    kCanFocus = 1 << 0,    // default: true
    kCanTouch = 1 << 1,    // default: true
    kCanTraverse = 1 << 2, // default: true
    // bits 3-4: EdgeBehavior (2 bits)
    kHasFocus = 1 << 5,     // true if this node or descendant has focus
    kHadFocusable = 1 << 6, // sticky: was ever backed by a Focusable
    kCapturesKeys = 1 << 7, // see capturesKeyInput()
  };
  static constexpr uint8_t edgeBehaviorShift = 3;
  static constexpr uint8_t edgeBehaviorMask = 0x3;
  static constexpr uint8_t defaultFlags = Flag::kCanFocus | Flag::kCanTouch |
                                          Flag::kCanTraverse;

  void setFlag(Flag flag, bool value)
  {
    if (value)
    {
      m_flags |= flag;
    }
    else
    {
      m_flags &= ~flag;
    }
  }

  Focusable* m_focusable = nullptr;
  FocusNode* m_parent = nullptr;
  FocusManager* m_manager = nullptr;
  std::vector<rcp<FocusNode>> m_children;
  std::string m_name;
  AABB m_worldBounds; // Default empty (invalid) - hasWorldBounds() returns
                      // false
  uint8_t m_flags = defaultFlags;
  int16_t m_tabIndex = 0;
#ifdef WITH_RIVE_TOOLS
  bool m_isCollapsed = false;
#endif
};

} // namespace rive

#endif
