#ifndef _RIVE_SCRIPTED_TRANSITION_HPP_
#define _RIVE_SCRIPTED_TRANSITION_HPP_
#include "rive/generated/scripted/scripted_transition_base.hpp"
#include "rive/data_bind/data_bind_list_item_consumer.hpp"
#include "rive/refcnt.hpp"
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

namespace rive
{
class Component;
class NestedArtboard;
class ArtboardInstance;
class StateMachineInstance;
class File;
class ViewModelInstanceListItem;

/// A ScriptedTransition renders exactly one active child (Solo-style), chosen
/// by activeComponentId, but when the active child changes it hands the
/// outgoing (from) and incoming (to) children to a Transition-protocol script
/// which composites them over time (crossfade / slide / wipe / ...).
///
/// The switchable set is a COMBINED solo set: the design-time NestedArtboard
/// children (indices 0..D-1), followed by artboards instanced from a bound
/// ViewModel list via `listSource` (indices D..D+N-1). List artboards are
/// host-owned (not core objects, so they have no id) and are instanced lazily
/// on first selection. `activeComponentId` data-bound to a number selects by
/// this combined index.
///
/// While a transition is in flight both sources are composited by the script;
/// design children are excluded from the normal draw loop via the Hidden flag,
/// and list instances (which are never in the loop) are drawn by this
/// component.
class ScriptedTransition : public ScriptedTransitionBase,
                           public DataBindListItemConsumer
{
public:
  ~ScriptedTransition() override;

  ScriptProtocol scriptProtocol() override
  {
    return ScriptProtocol::transition;
  }

  void activeComponentIdChanged() override;
  void listSourceChanged() override;
  StatusCode onAddedClean(CoreContext* context) override;
  bool collapse(bool value) override;
  bool advanceComponent(
      float elapsedSeconds,
      AdvanceFlags flags = AdvanceFlags::Animate |
                           AdvanceFlags::NewFrame) override;
  void draw(Renderer* renderer) override;
  bool willDraw() override;
  void update(ComponentDirt value) override;
  Core* clone() const override;

  // File is threaded in by File import (see file.cpp) so list artboards can
  // be resolved from the file's artboard table.
  void file(File* value) { m_file = value; }
  File* file() const { return m_file; }

  // DataBindListItemConsumer: receives the bound ViewModel list (via
  // listSource) and (lazily) instances an artboard per item.
  void updateList(std::vector<rcp<ViewModelInstanceListItem>>* list) override;

  /// The design-time child resolved from activeComponentId (or null).
  Component* activeComponent();

  // Combined-index selectors (design children then list instances).
  void updateByIndex(size_t index);
  void updateByName(const std::string& name);
  int getActiveChildIndex();
  std::string getActiveChildName();

#ifdef WITH_RIVE_LAYOUT
  void recollectOwningLayout();
#endif

private:
  // A renderable source in the combined solo set: either a design-time
  // NestedArtboard child, or a list-instanced ArtboardInstance. Exactly one
  // of the two pointers is set (both null == empty/no selection).
  struct TransitionSource
  {
    NestedArtboard* design = nullptr;
    ArtboardInstance* instance = nullptr;
    bool empty() const { return design == nullptr && instance == nullptr; }
    bool operator==(const TransitionSource& o) const
    {
      return design == o.design && instance == o.instance;
    }
    bool operator!=(const TransitionSource& o) const { return !(*this == o); }
  };

  void propagateCollapse(bool collapse);
  void startTransition(
      const TransitionSource& from,
      const TransitionSource& to);
  void completeTransition();
  void callChanged(const TransitionSource& from, const TransitionSource& to);
  bool scriptReady() const;
  bool scriptManagesTo() const;
#ifdef WITH_RIVE_SCRIPTING
  // Resolve a source into the artboard the script draws and the world
  // transform that places it. Design children carry their own transform;
  // list instances are placed at this container's.
  ScriptBackend::TransitionChildRef childRef(
      const TransitionSource& source) const;
#endif

  // Combined solo set + unified selection.
  int designChildCount();
  NestedArtboard* designChildAt(int index);
  // Combined index (design children 0..D-1, then list instances D..) of a
  // source, or -1 if not found. Used to derive the transition direction.
  int sourceIndex(const TransitionSource& source);
  TransitionSource intendedSource();
  void applySelection();
  void selectActiveSource(const TransitionSource& next);

  // list instancing (lazy)
  ArtboardInstance* ensureListInstance(int index);
  Artboard* findListArtboard(const rcp<ViewModelInstanceListItem>& item);
  void disposeListItem(const rcp<ViewModelInstanceListItem>& item);
  void clearListInstances();
  // Drop any selection/transition reference to a list instance that is about
  // to be destroyed, so m_current/m_from/m_to never dangle.
  void forgetInstance(ArtboardInstance* instance);
  void advanceLiveInstance(
      const TransitionSource& source,
      float elapsedSeconds,
      AdvanceFlags flags,
      bool& keepGoing);

  // The child currently exposed as active (design or list).
  TransitionSource m_current;
  // The in-flight transition pair.
  TransitionSource m_from;
  TransitionSource m_to;
  bool m_transitioning = false;
  // Whether the script composites the incoming (to) source this transition.
  bool m_manageTo = true;
  // >= 0 => active is that list instance; -1 => active is a design child.
  int m_activeListIndex = -1;

  File* m_file = nullptr;
  std::vector<rcp<ViewModelInstanceListItem>> m_listItems;
  std::unordered_map<
      rcp<ViewModelInstanceListItem>,
      std::unique_ptr<ArtboardInstance>>
      m_listInstances;
  // Keyed by the instance pointer for O(1) advance lookup. Destroyed before
  // the owning ArtboardInstance (see disposeListItem / clearListInstances).
  std::unordered_map<ArtboardInstance*, std::unique_ptr<StateMachineInstance>>
      m_listStateMachines;
  // Lazily-filled fast index -> instance (nullptr until ensureListInstance).
  std::vector<ArtboardInstance*> m_listInstancesByIndex;
  // Cache: viewModelId -> source artboard in the file.
  std::unordered_map<uint32_t, Artboard*> m_artboardsMap;
};
} // namespace rive

#endif
