#pragma once

#include "character/states/CharacterStateBase.h"
#include <string>

namespace frostbite2D {

struct SwordmanActionUpdateResult {
  enum class Type {
    Running,
    Finished,
    Transition,
  };

  static SwordmanActionUpdateResult Running() {
    return {};
  }

  static SwordmanActionUpdateResult Finished() {
    SwordmanActionUpdateResult result;
    result.type = Type::Finished;
    return result;
  }

  static SwordmanActionUpdateResult TransitionTo(const std::string& requestedActionId,
                                                 bool requireBufferedInput = true) {
    SwordmanActionUpdateResult result;
    result.type = Type::Transition;
    result.requestedActionId = requestedActionId;
    result.requireBufferedInput = requireBufferedInput;
    return result;
  }

  Type type = Type::Running;
  std::string requestedActionId;
  bool requireBufferedInput = true;
};

class ISwordmanActionHandler {
public:
  virtual ~ISwordmanActionHandler() = default;

  virtual const std::string& GetActionId() const = 0;
  virtual void OnEnter(CharacterStateContext& context,
                       const CharacterActionDefinition& action) = 0;
  virtual SwordmanActionUpdateResult OnUpdate(CharacterStateContext& context,
                                              const CharacterActionDefinition& action) = 0;
  virtual void OnExit(CharacterStateContext& context,
                      const CharacterActionDefinition& action) {
    (void)context;
    (void)action;
  }
};

class SwordmanActionHandlerBase : public ISwordmanActionHandler {
public:
  explicit SwordmanActionHandlerBase(std::string actionId);
  ~SwordmanActionHandlerBase() override = default;

  const std::string& GetActionId() const override { return actionId_; }

protected:
  std::string actionId_;
};

} // namespace frostbite2D
