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

#pragma once

#if __has_include(<NitroModules/HybridObject.hpp>)
#include <NitroModules/HybridObject.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif

// Forward declaration of `WorkoutActivityType` to properly resolve imports.
namespace margelo::nitro::healthkit { enum class WorkoutActivityType; }
// Forward declaration of `Quantity` to properly resolve imports.
namespace margelo::nitro::healthkit { struct Quantity; }
// Forward declaration of `WorkoutEvent` to properly resolve imports.
namespace margelo::nitro::healthkit { struct WorkoutEvent; }
// Forward declaration of `WorkoutActivity` to properly resolve imports.
namespace margelo::nitro::healthkit { struct WorkoutActivity; }
// Forward declaration of `SampleType` to properly resolve imports.
namespace margelo::nitro::healthkit { struct SampleType; }
// Forward declaration of `SourceRevision` to properly resolve imports.
namespace margelo::nitro::healthkit { struct SourceRevision; }
// Forward declaration of `Device` to properly resolve imports.
namespace margelo::nitro::healthkit { struct Device; }
// Forward declaration of `WorkoutSample` to properly resolve imports.
namespace margelo::nitro::healthkit { struct WorkoutSample; }
// Forward declaration of `LocationForSaving` to properly resolve imports.
namespace margelo::nitro::healthkit { struct LocationForSaving; }
// Forward declaration of `WorkoutPlan` to properly resolve imports.
namespace margelo::nitro::healthkit { struct WorkoutPlan; }
// Forward declaration of `WorkoutRoute` to properly resolve imports.
namespace margelo::nitro::healthkit { struct WorkoutRoute; }
// Forward declaration of `QueryStatisticsResponse` to properly resolve imports.
namespace margelo::nitro::healthkit { struct QueryStatisticsResponse; }
// Forward declaration of `QuantityTypeIdentifier` to properly resolve imports.
namespace margelo::nitro::healthkit { enum class QuantityTypeIdentifier; }

#include "WorkoutActivityType.hpp"
#include "Quantity.hpp"
#include <optional>
#include "WorkoutEvent.hpp"
#include <vector>
#include "WorkoutActivity.hpp"
#include <NitroModules/AnyMap.hpp>
#include "SampleType.hpp"
#include <chrono>
#include <string>
#include "SourceRevision.hpp"
#include "Device.hpp"
#include "WorkoutSample.hpp"
#include <NitroModules/Promise.hpp>
#include "LocationForSaving.hpp"
#include "WorkoutPlan.hpp"
#include "WorkoutRoute.hpp"
#include "QueryStatisticsResponse.hpp"
#include "QuantityTypeIdentifier.hpp"
#include <unordered_map>

namespace margelo::nitro::healthkit {

  using namespace margelo::nitro;

  /**
   * An abstract base class for `WorkoutProxy`
   * Inherit this class to create instances of `HybridWorkoutProxySpec` in C++.
   * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
   * @example
   * ```cpp
   * class HybridWorkoutProxy: public HybridWorkoutProxySpec {
   * public:
   *   HybridWorkoutProxy(...): HybridObject(TAG) { ... }
   *   // ...
   * };
   * ```
   */
  class HybridWorkoutProxySpec: public virtual HybridObject {
    public:
      // Constructor
      explicit HybridWorkoutProxySpec(): HybridObject(TAG) { }

      // Destructor
      ~HybridWorkoutProxySpec() override = default;

    public:
      // Properties
      virtual WorkoutActivityType getWorkoutActivityType() = 0;
      virtual Quantity getDuration() = 0;
      virtual std::optional<Quantity> getTotalEnergyBurned() = 0;
      virtual std::optional<Quantity> getTotalDistance() = 0;
      virtual std::optional<Quantity> getTotalSwimmingStrokeCount() = 0;
      virtual std::optional<Quantity> getTotalFlightsClimbed() = 0;
      virtual std::optional<std::vector<WorkoutEvent>> getEvents() = 0;
      virtual std::optional<std::vector<WorkoutActivity>> getActivities() = 0;
      virtual std::shared_ptr<AnyMap> getMetadata() = 0;
      virtual SampleType getSampleType() = 0;
      virtual std::chrono::system_clock::time_point getStartDate() = 0;
      virtual std::chrono::system_clock::time_point getEndDate() = 0;
      virtual bool getHasUndeterminedDuration() = 0;
      virtual std::string getUuid() = 0;
      virtual SourceRevision getSourceRevision() = 0;
      virtual std::optional<Device> getDevice() = 0;

    public:
      // Methods
      virtual WorkoutSample toJSON(const std::optional<std::string>& key) = 0;
      virtual std::shared_ptr<Promise<bool>> saveWorkoutRoute(const std::vector<LocationForSaving>& locations) = 0;
      virtual std::shared_ptr<Promise<std::optional<WorkoutPlan>>> getWorkoutPlan() = 0;
      virtual std::shared_ptr<Promise<std::vector<WorkoutRoute>>> getWorkoutRoutes() = 0;
      virtual std::shared_ptr<Promise<std::optional<QueryStatisticsResponse>>> getStatistic(QuantityTypeIdentifier quantityType, const std::optional<std::string>& unitOverride) = 0;
      virtual std::shared_ptr<Promise<std::unordered_map<std::string, QueryStatisticsResponse>>> getAllStatistics() = 0;

    protected:
      // Hybrid Setup
      void loadHybridMethods() override;

    protected:
      // Tag for logging
      static constexpr auto TAG = "WorkoutProxy";
  };

} // namespace margelo::nitro::healthkit
