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

#include "HybridBlurViewComponent.hpp"

#include <string>
#include <exception>
#include <utility>
#include <NitroModules/NitroDefines.hpp>
#include <NitroModules/JSIConverter.hpp>
#include <NitroModules/PropNameIDCache.hpp>
#include <react/renderer/core/RawValue.h>
#include <react/renderer/core/ShadowNode.h>
#include <react/renderer/core/ComponentDescriptor.h>
#include <react/renderer/components/view/ViewProps.h>

namespace margelo::nitro::qmblurview::views {

  extern const char HybridBlurViewComponentName[] = "BlurView";

  HybridBlurViewProps::HybridBlurViewProps(const react::PropsParserContext& context,
                                           const HybridBlurViewProps& sourceProps,
                                           const react::RawProps& rawProps):
    react::ViewProps(context, sourceProps, rawProps, filterObjectKeys),
    blurRadius([&]() -> CachedProp<std::optional<double>> {
      try {
        const react::RawValue* rawValue = rawProps.at("blurRadius", nullptr, nullptr);
        if (rawValue == nullptr) return sourceProps.blurRadius;
        const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
        return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.blurRadius);
      } catch (const std::exception& exc) {
        throw std::runtime_error(std::string("BlurView.blurRadius: ") + exc.what());
      }
    }()),
    cornerRadius([&]() -> CachedProp<std::optional<double>> {
      try {
        const react::RawValue* rawValue = rawProps.at("cornerRadius", nullptr, nullptr);
        if (rawValue == nullptr) return sourceProps.cornerRadius;
        const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
        return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.cornerRadius);
      } catch (const std::exception& exc) {
        throw std::runtime_error(std::string("BlurView.cornerRadius: ") + exc.what());
      }
    }()),
    blurRounds([&]() -> CachedProp<std::optional<double>> {
      try {
        const react::RawValue* rawValue = rawProps.at("blurRounds", nullptr, nullptr);
        if (rawValue == nullptr) return sourceProps.blurRounds;
        const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
        return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.blurRounds);
      } catch (const std::exception& exc) {
        throw std::runtime_error(std::string("BlurView.blurRounds: ") + exc.what());
      }
    }()),
    overlayColor([&]() -> CachedProp<std::optional<std::string>> {
      try {
        const react::RawValue* rawValue = rawProps.at("overlayColor", nullptr, nullptr);
        if (rawValue == nullptr) return sourceProps.overlayColor;
        const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
        return CachedProp<std::optional<std::string>>::fromRawValue(*runtime, value, sourceProps.overlayColor);
      } catch (const std::exception& exc) {
        throw std::runtime_error(std::string("BlurView.overlayColor: ") + exc.what());
      }
    }()),
    downsampleFactor([&]() -> CachedProp<std::optional<double>> {
      try {
        const react::RawValue* rawValue = rawProps.at("downsampleFactor", nullptr, nullptr);
        if (rawValue == nullptr) return sourceProps.downsampleFactor;
        const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
        return CachedProp<std::optional<double>>::fromRawValue(*runtime, value, sourceProps.downsampleFactor);
      } catch (const std::exception& exc) {
        throw std::runtime_error(std::string("BlurView.downsampleFactor: ") + exc.what());
      }
    }()),
    hybridRef([&]() -> CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridBlurViewSpec>& /* ref */)>>> {
      try {
        const react::RawValue* rawValue = rawProps.at("hybridRef", nullptr, nullptr);
        if (rawValue == nullptr) return sourceProps.hybridRef;
        const auto& [runtime, value] = (std::pair<jsi::Runtime*, jsi::Value>)*rawValue;
        return CachedProp<std::optional<std::function<void(const std::shared_ptr<HybridBlurViewSpec>& /* ref */)>>>::fromRawValue(*runtime, value.asObject(*runtime).getProperty(*runtime, PropNameIDCache::get(*runtime, "f")), sourceProps.hybridRef);
      } catch (const std::exception& exc) {
        throw std::runtime_error(std::string("BlurView.hybridRef: ") + exc.what());
      }
    }()) { }

  HybridBlurViewProps::HybridBlurViewProps(const HybridBlurViewProps& other):
    react::ViewProps(),
    blurRadius(other.blurRadius),
    cornerRadius(other.cornerRadius),
    blurRounds(other.blurRounds),
    overlayColor(other.overlayColor),
    downsampleFactor(other.downsampleFactor),
    hybridRef(other.hybridRef) { }

  bool HybridBlurViewProps::filterObjectKeys(const std::string& propName) {
    switch (hashString(propName)) {
      case hashString("blurRadius"): return true;
      case hashString("cornerRadius"): return true;
      case hashString("blurRounds"): return true;
      case hashString("overlayColor"): return true;
      case hashString("downsampleFactor"): return true;
      case hashString("hybridRef"): return true;
      default: return false;
    }
  }

  HybridBlurViewComponentDescriptor::HybridBlurViewComponentDescriptor(const react::ComponentDescriptorParameters& parameters)
    : ConcreteComponentDescriptor(parameters,
                                  react::RawPropsParser(/* enableJsiParser */ true)) {}

  std::shared_ptr<const react::Props> HybridBlurViewComponentDescriptor::cloneProps(const react::PropsParserContext& context,
                                                                                    const std::shared_ptr<const react::Props>& props,
                                                                                    react::RawProps rawProps) const {
    // 1. Prepare raw props parser
    rawProps.parse(rawPropsParser_);
    // 2. Copy props with Nitro's cached copy constructor
    return HybridBlurViewShadowNode::Props(context, /* & */ rawProps, props);
  }

#ifdef ANDROID
  void HybridBlurViewComponentDescriptor::adopt(react::ShadowNode& shadowNode) const {
    // This is called immediately after `ShadowNode` is created, cloned or in progress.
    // On Android, we need to wrap props in our state, which gets routed through Java and later unwrapped in JNI/C++.
    auto& concreteShadowNode = dynamic_cast<HybridBlurViewShadowNode&>(shadowNode);
    const HybridBlurViewProps& props = concreteShadowNode.getConcreteProps();
    HybridBlurViewState state;
    state.setProps(props);
    concreteShadowNode.setStateData(std::move(state));
  }
#endif

} // namespace margelo::nitro::qmblurview::views
