#include "torlinkc/ui/spinner.hpp"

#include <ftxui/component/animation.hpp>
#include <ftxui/component/component_base.hpp>
#include <ftxui/dom/elements.hpp>

namespace torlinkc::ui {

namespace {

constexpr const char* kFrames[] = {"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"};
constexpr int kFrameCount = 10;
constexpr float kFrameSeconds = 0.08f;

class SpinnerComponent : public ftxui::ComponentBase {
 public:
  explicit SpinnerComponent(std::function<bool()> isActive) : isActive_(std::move(isActive)) {}

  ftxui::Element Render() override {
    if (!isActive_()) return ftxui::text("");
    return ftxui::text(kFrames[frame_ % kFrameCount]);
  }

  void OnAnimation(ftxui::animation::Params& params) override {
    if (!isActive_()) return;
    elapsed_ += params.duration().count();
    if (elapsed_ >= kFrameSeconds) {
      elapsed_ = 0.0f;
      frame_ = (frame_ + 1) % kFrameCount;
    }
    ftxui::animation::RequestAnimationFrame();
  }

 private:
  std::function<bool()> isActive_;
  int frame_ = 0;
  float elapsed_ = 0.0f;
};

}  // namespace

ftxui::Component MakeSpinner(std::function<bool()> isActive) { return ftxui::Make<SpinnerComponent>(std::move(isActive)); }

}  // namespace torlinkc::ui
