#pragma once

#include "esphome/core/automation.h"
#include "display_menu_base.h"

namespace esphome::display_menu_base {

template<typename... Ts> class UpAction final : public Action<Ts...> {
 public:
  explicit UpAction(DisplayMenuComponent *menu) : menu_(menu) {}

  void play(const Ts &...x) override { this->menu_->up(); }

 protected:
  DisplayMenuComponent *menu_;
};

template<typename... Ts> class DownAction final : public Action<Ts...> {
 public:
  explicit DownAction(DisplayMenuComponent *menu) : menu_(menu) {}

  void play(const Ts &...x) override { this->menu_->down(); }

 protected:
  DisplayMenuComponent *menu_;
};

template<typename... Ts> class LeftAction final : public Action<Ts...> {
 public:
  explicit LeftAction(DisplayMenuComponent *menu) : menu_(menu) {}

  void play(const Ts &...x) override { this->menu_->left(); }

 protected:
  DisplayMenuComponent *menu_;
};

template<typename... Ts> class RightAction final : public Action<Ts...> {
 public:
  explicit RightAction(DisplayMenuComponent *menu) : menu_(menu) {}

  void play(const Ts &...x) override { this->menu_->right(); }

 protected:
  DisplayMenuComponent *menu_;
};

template<typename... Ts> class EnterAction final : public Action<Ts...> {
 public:
  explicit EnterAction(DisplayMenuComponent *menu) : menu_(menu) {}

  void play(const Ts &...x) override { this->menu_->enter(); }

 protected:
  DisplayMenuComponent *menu_;
};

template<typename... Ts> class ShowAction final : public Action<Ts...> {
 public:
  explicit ShowAction(DisplayMenuComponent *menu) : menu_(menu) {}

  void play(const Ts &...x) override { this->menu_->show(); }

 protected:
  DisplayMenuComponent *menu_;
};

template<typename... Ts> class HideAction final : public Action<Ts...> {
 public:
  explicit HideAction(DisplayMenuComponent *menu) : menu_(menu) {}

  void play(const Ts &...x) override { this->menu_->hide(); }

 protected:
  DisplayMenuComponent *menu_;
};

template<typename... Ts> class ShowMainAction final : public Action<Ts...> {
 public:
  explicit ShowMainAction(DisplayMenuComponent *menu) : menu_(menu) {}

  void play(const Ts &...x) override { this->menu_->show_main(); }

 protected:
  DisplayMenuComponent *menu_;
};
template<typename... Ts> class IsActiveCondition final : public Condition<Ts...> {
 public:
  explicit IsActiveCondition(DisplayMenuComponent *menu) : menu_(menu) {}
  bool check(const Ts &...x) override { return this->menu_->is_active(); }

 protected:
  DisplayMenuComponent *menu_;
};

class DisplayMenuOnEnterTrigger final : public Trigger<const MenuItem *> {
 public:
  explicit DisplayMenuOnEnterTrigger(MenuItem *parent) : parent_(parent) {
    parent->add_on_enter_callback([this]() { this->trigger(this->parent_); });
  }

 protected:
  MenuItem *parent_;
};

class DisplayMenuOnLeaveTrigger final : public Trigger<const MenuItem *> {
 public:
  explicit DisplayMenuOnLeaveTrigger(MenuItem *parent) : parent_(parent) {
    parent->add_on_leave_callback([this]() { this->trigger(this->parent_); });
  }

 protected:
  MenuItem *parent_;
};

class DisplayMenuOnValueTrigger final : public Trigger<const MenuItem *> {
 public:
  explicit DisplayMenuOnValueTrigger(MenuItem *parent) : parent_(parent) {
    parent->add_on_value_callback([this]() { this->trigger(this->parent_); });
  }

 protected:
  MenuItem *parent_;
};

class DisplayMenuOnNextTrigger final : public Trigger<const MenuItem *> {
 public:
  explicit DisplayMenuOnNextTrigger(MenuItemCustom *parent) : parent_(parent) {
    parent->add_on_next_callback([this]() { this->trigger(this->parent_); });
  }

 protected:
  MenuItemCustom *parent_;
};

class DisplayMenuOnPrevTrigger final : public Trigger<const MenuItem *> {
 public:
  explicit DisplayMenuOnPrevTrigger(MenuItemCustom *parent) : parent_(parent) {
    parent->add_on_prev_callback([this]() { this->trigger(this->parent_); });
  }

 protected:
  MenuItemCustom *parent_;
};

}  // namespace esphome::display_menu_base
