///
/// HybridReadiumViewComponent.hpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///

#pragma once

#include <optional>
#include <NitroModules/NitroDefines.hpp>
#include <NitroModules/NitroHash.hpp>
#include <NitroModules/CachedProp.hpp>
#include <react/renderer/core/ConcreteComponentDescriptor.h>
#include <react/renderer/core/PropsParserContext.h>
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
#include <react/renderer/components/view/ViewProps.h>

#include "ReadiumFile.hpp"
#include <optional>
#include "Preferences.hpp"
#include "DecorationGroup.hpp"
#include <vector>
#include "SelectionAction.hpp"
#include "Locator.hpp"
#include <functional>
#include "PublicationReadyEvent.hpp"
#include "DecorationActivatedEvent.hpp"
#include "SelectionEvent.hpp"
#include "SelectionActionEvent.hpp"
#include <memory>
#include "HybridReadiumViewSpec.hpp"

namespace margelo::nitro::readium::views {

  using namespace facebook;

  /**
   * The name of the actual native View.
   */
  extern const char HybridReadiumViewComponentName[];

  /**
   * Props for the "ReadiumView" View.
   */
  class HybridReadiumViewProps final: public react::ViewProps {
  public:
    HybridReadiumViewProps() = default;
    HybridReadiumViewProps(const react::PropsParserContext& context,
                           const HybridReadiumViewProps& sourceProps,
                           const react::RawProps& rawProps);

  public:
    CachedProp<std::optional<ReadiumFile>> file;
    CachedProp<std::optional<Preferences>> preferences;
    CachedProp<std::optional<std::vector<DecorationGroup>>> decorations;
    CachedProp<std::optional<std::vector<SelectionAction>>> selectionActions;
    CachedProp<std::optional<std::function<void(const Locator& /* locator */)>>> onLocationChange;
    CachedProp<std::optional<std::function<void(const PublicationReadyEvent& /* event */)>>> onPublicationReady;
    CachedProp<std::optional<std::function<void(const DecorationActivatedEvent& /* event */)>>> onDecorationActivated;
    CachedProp<std::optional<std::function<void(const SelectionEvent& /* event */)>>> onSelectionChange;
    CachedProp<std::optional<std::function<void(const SelectionActionEvent& /* event */)>>> onSelectionAction;
    CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridReadiumViewSpec>& /* ref */)>>> hybridRef;

  private:
    static bool filterObjectKeys(const std::string& propName);
  };

  /**
   * State for the "ReadiumView" View.
   */
  class HybridReadiumViewState final {
  public:
    HybridReadiumViewState() = default;
    explicit HybridReadiumViewState(const std::shared_ptr<HybridReadiumViewProps>& props):
      _props(props) {}

  public:
    [[nodiscard]]
    const std::shared_ptr<HybridReadiumViewProps>& getProps() const {
      return _props;
    }

  public:
#ifdef ANDROID
  HybridReadiumViewState(const HybridReadiumViewState& /* previousState */, folly::dynamic /* data */) {}
  folly::dynamic getDynamic() const {
    throw std::runtime_error("HybridReadiumViewState does not support folly!");
  }
  react::MapBuffer getMapBuffer() const {
    throw std::runtime_error("HybridReadiumViewState does not support MapBuffer!");
  };
#endif

  private:
    std::shared_ptr<HybridReadiumViewProps> _props;
  };

  /**
   * The Shadow Node for the "ReadiumView" View.
   */
  using HybridReadiumViewShadowNode = react::ConcreteViewShadowNode<HybridReadiumViewComponentName /* "HybridReadiumView" */,
                                                                    HybridReadiumViewProps /* custom props */,
                                                                    react::ViewEventEmitter /* default */,
                                                                    HybridReadiumViewState /* custom state */>;

  /**
   * The Component Descriptor for the "ReadiumView" View.
   */
  class HybridReadiumViewComponentDescriptor final: public react::ConcreteComponentDescriptor<HybridReadiumViewShadowNode> {
  public:
    explicit HybridReadiumViewComponentDescriptor(const react::ComponentDescriptorParameters& parameters);

  public:
    /**
     * A faster path for cloning props - reuses the caching logic from `HybridReadiumViewProps`.
     */
    std::shared_ptr<const react::Props> cloneProps(const react::PropsParserContext& context,
                                                   const std::shared_ptr<const react::Props>& props,
                                                   react::RawProps rawProps) const override;
#ifdef ANDROID
    void adopt(react::ShadowNode& shadowNode) const override;
#endif
  };

  /* The actual view for "ReadiumView" needs to be implemented in platform-specific code. */

} // namespace margelo::nitro::readium::views
