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

#pragma once

#include <fbjni/fbjni.h>
#include "LDP_PresentParams.hpp"

#include "JFunc_void_LDP_Range.hpp"
#include "JLDP_Mode.hpp"
#include "JLDP_Range.hpp"
#include "LDP_Mode.hpp"
#include "LDP_Range.hpp"
#include <NitroModules/JNICallable.hpp>
#include <functional>
#include <optional>
#include <string>

namespace margelo::nitro::lunardatepicker {

  using namespace facebook;

  /**
   * The C++ JNI bridge between the C++ struct "LDP_PresentParams" and the the Kotlin data class "LDP_PresentParams".
   */
  struct JLDP_PresentParams final: public jni::JavaClass<JLDP_PresentParams> {
  public:
    static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/lunardatepicker/LDP_PresentParams;";

  public:
    /**
     * Convert this Java/Kotlin-based struct to the C++ struct LDP_PresentParams by copying all values to C++.
     */
    [[maybe_unused]]
    [[nodiscard]]
    LDP_PresentParams toCpp() const {
      static const auto clazz = javaClassStatic();
      static const auto fieldTheme = clazz->getField<jni::JString>("theme");
      jni::local_ref<jni::JString> theme = this->getFieldValue(fieldTheme);
      static const auto fieldLanguage = clazz->getField<jni::JString>("language");
      jni::local_ref<jni::JString> language = this->getFieldValue(fieldLanguage);
      static const auto fieldTitle = clazz->getField<jni::JString>("title");
      jni::local_ref<jni::JString> title = this->getFieldValue(fieldTitle);
      static const auto fieldSubmitText = clazz->getField<jni::JString>("submitText");
      jni::local_ref<jni::JString> submitText = this->getFieldValue(fieldSubmitText);
      static const auto fieldFromText = clazz->getField<jni::JString>("fromText");
      jni::local_ref<jni::JString> fromText = this->getFieldValue(fieldFromText);
      static const auto fieldToText = clazz->getField<jni::JString>("toText");
      jni::local_ref<jni::JString> toText = this->getFieldValue(fieldToText);
      static const auto fieldNotSelectedText = clazz->getField<jni::JString>("notSelectedText");
      jni::local_ref<jni::JString> notSelectedText = this->getFieldValue(fieldNotSelectedText);
      static const auto fieldMode = clazz->getField<JLDP_Mode>("mode");
      jni::local_ref<JLDP_Mode> mode = this->getFieldValue(fieldMode);
      static const auto fieldShowHeader = clazz->getField<jni::JBoolean>("showHeader");
      jni::local_ref<jni::JBoolean> showHeader = this->getFieldValue(fieldShowHeader);
      static const auto fieldOnDone = clazz->getField<JFunc_void_LDP_Range::javaobject>("onDone");
      jni::local_ref<JFunc_void_LDP_Range::javaobject> onDone = this->getFieldValue(fieldOnDone);
      static const auto fieldMinimumDate = clazz->getField<jni::JString>("minimumDate");
      jni::local_ref<jni::JString> minimumDate = this->getFieldValue(fieldMinimumDate);
      static const auto fieldMaximumDate = clazz->getField<jni::JString>("maximumDate");
      jni::local_ref<jni::JString> maximumDate = this->getFieldValue(fieldMaximumDate);
      static const auto fieldInitialValue = clazz->getField<JLDP_Range>("initialValue");
      jni::local_ref<JLDP_Range> initialValue = this->getFieldValue(fieldInitialValue);
      return LDP_PresentParams(
        theme->toStdString(),
        language->toStdString(),
        title->toStdString(),
        submitText->toStdString(),
        fromText != nullptr ? std::make_optional(fromText->toStdString()) : std::nullopt,
        toText != nullptr ? std::make_optional(toText->toStdString()) : std::nullopt,
        notSelectedText != nullptr ? std::make_optional(notSelectedText->toStdString()) : std::nullopt,
        mode->toCpp(),
        showHeader != nullptr ? std::make_optional(static_cast<bool>(showHeader->value())) : std::nullopt,
        [&]() -> std::function<void(const LDP_Range& /* result */)> {
          if (onDone->isInstanceOf(JFunc_void_LDP_Range_cxx::javaClassStatic())) [[likely]] {
            auto downcast = jni::static_ref_cast<JFunc_void_LDP_Range_cxx::javaobject>(onDone);
            return downcast->cthis()->getFunction();
          } else {
            auto onDoneRef = jni::make_global(onDone);
            return JNICallable<JFunc_void_LDP_Range, void(LDP_Range)>(std::move(onDoneRef));
          }
        }(),
        minimumDate != nullptr ? std::make_optional(minimumDate->toStdString()) : std::nullopt,
        maximumDate != nullptr ? std::make_optional(maximumDate->toStdString()) : std::nullopt,
        initialValue != nullptr ? std::make_optional(initialValue->toCpp()) : std::nullopt
      );
    }

  public:
    /**
     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
     */
    [[maybe_unused]]
    static jni::local_ref<JLDP_PresentParams::javaobject> fromCpp(const LDP_PresentParams& value) {
      using JSignature = JLDP_PresentParams(jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<JLDP_Mode>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<JFunc_void_LDP_Range::javaobject>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<JLDP_Range>);
      static const auto clazz = javaClassStatic();
      static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
      return create(
        clazz,
        jni::make_jstring(value.theme),
        jni::make_jstring(value.language),
        jni::make_jstring(value.title),
        jni::make_jstring(value.submitText),
        value.fromText.has_value() ? jni::make_jstring(value.fromText.value()) : nullptr,
        value.toText.has_value() ? jni::make_jstring(value.toText.value()) : nullptr,
        value.notSelectedText.has_value() ? jni::make_jstring(value.notSelectedText.value()) : nullptr,
        JLDP_Mode::fromCpp(value.mode),
        value.showHeader.has_value() ? jni::JBoolean::valueOf(value.showHeader.value()) : nullptr,
        JFunc_void_LDP_Range_cxx::fromCpp(value.onDone),
        value.minimumDate.has_value() ? jni::make_jstring(value.minimumDate.value()) : nullptr,
        value.maximumDate.has_value() ? jni::make_jstring(value.maximumDate.value()) : nullptr,
        value.initialValue.has_value() ? JLDP_Range::fromCpp(value.initialValue.value()) : nullptr
      );
    }
  };

} // namespace margelo::nitro::lunardatepicker
