#ifndef _RIVE_NESTED_ARTBOARD_HPP_
#define _RIVE_NESTED_ARTBOARD_HPP_

#include "rive/generated/nested_artboard_base.hpp"
#include "rive/artboard_host.hpp"
#include "rive/artboard_referencer.hpp"
#include "rive/data_bind_path_referencer.hpp"
#include "rive/data_bind/data_context.hpp"
#include "rive/viewmodel/viewmodel_instance_value.hpp"
#include "rive/hit_info.hpp"
#include "rive/input/focusable.hpp"
#include "rive/animation/listener_invocation.hpp"
#include "rive/span.hpp"
#include "rive/advancing_component.hpp"
#include "rive/resetting_component.hpp"
#include "rive/viewmodel/viewmodel_instance_artboard.hpp"
#include "rive/input/focus_node.hpp"
#include "rive/nested_artboard_host_flags.hpp"
#include "rive/refcnt.hpp"
#include "rive/file.hpp"
#include <stdio.h>

namespace rive
{

class ArtboardInstance;
class FocusManager;
class NestedAnimation;
class ComponentOrigin;
class NestedInput;
class NestedStateMachine;
class StateMachineInstance;
class NestedArtboard : public NestedArtboardBase,
                       public AdvancingComponent,
                       public ResettingComponent,
                       public ArtboardHost,
                       public ArtboardReferencer,
                       public Focusable
{
protected:
    std::unique_ptr<ArtboardInstance> m_Instance; // may be null
    std::unique_ptr<NestedStateMachine>
        m_boundNestedStateMachine; // may be null
    std::vector<NestedAnimation*> m_NestedAnimations;
    File* m_file = nullptr;
    rcp<ViewModelInstance> m_viewModelInstance = nullptr;
    rcp<DataContext> m_dataContext = nullptr;
    // VMI actively used for binding. Either the stateful child VMI (borrowed
    // from children(); freed by the parent Artboard's m_Objects teardown) or a
    // dynamically-created bound VMI for a different ViewModel (owned here, see
    // m_ownsActiveVmi).
    ViewModelInstance* m_activeViewModelInstance = nullptr;
    // Global ViewModelInstance children — appended to the data context passed
    // down to the wrapped artboard. The artboard's m_Objects owns the
    // construction ref; this list holds an extra ref (see ref_rcp in
    // onAddedClean) so it stays valid regardless of teardown ordering.
    std::vector<rcp<ViewModelInstance>> m_globalViewModelInstances;
    /// Structural scope for data-bound hosts only
    rcp<FocusNode> m_focusScope;

private:
    void clearNestedAnimations();
    float m_cumulatedSeconds = 0;
    // True if m_activeViewModelInstance is a dynamically-created bound VMI
    // that must be unref'd by this NestedArtboard.
    bool m_ownsActiveVmi = false;
    NestedArtboardHostFlags m_hostFlags = NestedArtboardHostFlags::none;
    void nest(Artboard* artboard);
    void detectArtboardDataBinding();
    bool tryScheduleBindStateful();
    void bindStateful();
    // Walks children() for the first ViewModelInstance child (the stateful
    // component VMI authored in the editor). Returns nullptr if none.
    ViewModelInstance* findStatefulChildVmi() const;
    // Releases the current active VMI if owned, then assigns the new one.
    void setActiveViewModelInstance(ViewModelInstance* vmi, bool owns);
    /// Create/attach this host's persistent focus scope (data-bound hosts
    /// only). With `place` true (full build pass) the scope is re-appended
    /// under `parentNode` so append order matches the hierarchy walk; with
    /// `place` false an already-registered scope is never moved.
    void registerFocusScope(FocusManager* focusManager,
                            rcp<FocusNode> parentNode,
                            bool place);

public:
    /// True when this host can receive runtime artboard swaps and therefore
    /// owns (or will own) a persistent focus scope.
    bool isArtboardDataBound() const
    {
        return enums::is_flag_set(m_hostFlags,
                                  NestedArtboardHostFlags::artboardDataBound);
    }

    /// Register this host's focus scope (if data-bound) and rebuild the nested
    /// instance focus tree under the parent FocusManager. Called from the
    /// hierarchical focus-tree build (Artboard::buildFocusTree) and from the
    /// data-bound artboard swap path.
    /// @param fallbackParent Parent used when the host has no closest ancestor
    ///        FocusNode.
    /// @param placeScope True only from the full build pass, which is the
    ///        ordering authority: the scope is re-appended at the walk's
    ///        current position. All other callers leave placement untouched.
    /// @param forceRebuild When true (the default), always tear down and
    ///        rebuild the nested instance's focus subtree. When false, skip the
    ///        rebuild if the subtree already shares this manager, preserving
    ///        focus resting inside an untouched instance. The full build pass
    ///        passes false unless it just re-wired the manager (which rebuilds
    ///        at the root and requires re-homing).
    void syncNestedFocusTree(rcp<FocusNode> fallbackParent,
                             bool placeScope = false,
                             bool forceRebuild = true);

    NestedArtboard();
    ~NestedArtboard() override;
    StatusCode onAddedClean(CoreContext* context) override;
    void draw(Renderer* renderer) override;
    bool willDraw() override;
    Core* hitTest(HitInfo*, const Mat2D&) override;
    void addNestedAnimation(NestedAnimation* nestedAnimation);
    void updateArtboard(
        ViewModelInstanceArtboard* viewModelInstanceArtboard) override;
    int referencedArtboardId() override;
    void referencedArtboard(Artboard* artboard) override;
    size_t artboardCount() override { return 1; }
    int type() const override { return coreType(); }
    ArtboardInstance* artboardInstance(int index = 0) override
    {
        return m_Instance.get();
    }
    Artboard* sourceArtboard() { return m_referencedArtboard; }

    // Pushes the optional ComponentOrigin child's origin (if any) onto the
    // mounted artboard instance. No-op when there is no override child, so
    // nested artboards without an override carry no per-instance origin state.
    void applyOriginOverride();

    StatusCode import(ImportStack& importStack) override;
    Core* clone() const override;
    bool collapse(bool value) override;
    void update(ComponentDirt value) override;

    bool hasNestedStateMachines() const;
    Span<NestedAnimation*> nestedAnimations();
    NestedArtboard* nestedArtboard(std::string name) const;
    NestedStateMachine* stateMachine(std::string name) const;
    NestedInput* input(std::string name) const;
    NestedInput* input(std::string name, std::string stateMachineName) const;

    Vec2D measureLayout(float width,
                        LayoutMeasureMode widthMode,
                        float height,
                        LayoutMeasureMode heightMode) override;
    void controlSize(Vec2D size,
                     LayoutScaleType widthScaleType,
                     LayoutScaleType heightScaleType,
                     LayoutDirection direction) override;

    /// Convert a world space (relative to the artboard that this
    /// NestedArtboard is a child of) to the local space of the Artboard
    /// nested within. Returns true when the conversion succeeds, and false
    /// when one is not possible.
    bool worldToLocal(Vec2D world, Vec2D* local);
    void decodeDataBindPathIds(Span<const uint8_t> value) override;
    void copyDataBindPathIds(const NestedArtboardBase& object) override;
    void bindViewModelInstance(rcp<ViewModelInstance> viewModelInstance,
                               rcp<DataContext> parent) override;
    void internalDataContext(rcp<DataContext> dataContext) override;
    void relinkDataContext(rcp<ViewModelInstance> viewModelInstance) override;
    void clearDataContext() override;
    void unbind() override;
    void updateDataBinds() override;

    float calculateLocalElapsedSeconds(float elapsedSeconds);
    bool advanceComponent(float elapsedSeconds,
                          AdvanceFlags flags = AdvanceFlags::Animate |
                                               AdvanceFlags::NewFrame) override;
    void reset() override;
    Artboard* parentArtboard() override { return artboard(); }
    Vec2D hostTransformPoint(const Vec2D&, ArtboardInstance*) override;
    Mat2D worldTransformForArtboard(ArtboardInstance*) override;
    bool hitTestHost(const Vec2D& position,
                     bool skipOnUnclipped,
                     ArtboardInstance* artboard) override;
    void markHostTransformDirty() override { markTransformDirty(); }
    void file(File*) override;
    File* file() const override;
    Component* hostComponent() override { return this; }

    // Focusable interface - delegates to nested state machines
    bool keyInput(Key, KeyModifiers, bool, bool) override { return false; };
    bool textInput(const std::string&) override { return false; };
    bool gamepadDispatch(const ListenerInvocation&,
                         ScriptedDrawable** = nullptr) override
    {
        return false;
    }
    void focused() override {}
    void blurred() override {}
    Artboard* focusableArtboard() const override { return artboard(); }
};
} // namespace rive

#endif
