#pragma once

#include <string>
#include <memory>

#include "soh/Enhancements/custom-message/text.h"
#include "randomizerTypes.h"
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#include "3drando/hints.hpp"

enum ItemType {
    ITEMTYPE_ITEM,
    ITEMTYPE_EQUIP,
    ITEMTYPE_MAP,
    ITEMTYPE_COMPASS,
    ITEMTYPE_BOSSKEY,
    ITEMTYPE_SMALLKEY,
    ITEMTYPE_TOKEN,
    ITEMTYPE_FORTRESS_SMALLKEY,
    ITEMTYPE_EVENT,
    ITEMTYPE_DROP,
    ITEMTYPE_REFILL,
    ITEMTYPE_SONG,
    ITEMTYPE_SHOP,
    ITEMTYPE_DUNGEONREWARD
};

enum CustomIconSize { ICON_SIZE_24, ICON_SIZE_32 };

namespace Rando {
class Item {
  public:
    Item();
    Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_,
         LogicVal logicVal_, RandomizerHintTextKey hintKey_, uint16_t itemId_, uint16_t objectId_, uint16_t gid_,
         uint16_t textId_, uint16_t field_, int16_t chestAnimation_, GetItemCategory category_, uint16_t modIndex_,
         Text article_ = {}, std::string color_ = "%g", bool progressive_ = false, uint16_t price_ = 0);
    Item(RandomizerGet randomizerGet_, Text name_, ItemType type_, int16_t getItemId_, bool advancement_,
         LogicVal logicVal_, RandomizerHintTextKey hintKey_, GetItemCategory category_, Text article_ = {},
         std::string color_ = "%g", bool progressive_ = false, uint16_t price_ = 0);

    void ApplyEffect() const;
    void UndoEffect() const;

    const Text& GetName() const;
    const Text& GetArticle() const;
    const std::string& GetColor() const;
    bool IsAdvancement() const;
    int GetItemID() const;
    ItemType GetItemType() const;
    LogicVal GetLogicVal() const;
    RandomizerGet GetRandomizerGet() const;
    uint16_t GetPrice() const;
    std::shared_ptr<GetItemEntry> GetGIEntry() const;
    GetItemEntry GetGIEntry_Copy() const;
    void SetPrice(uint16_t price_);
    void SetAsPlaythrough();
    void SetCustomDrawFunc(CustomDrawFunc) const;
    bool IsPlaythrough() const;
    bool IsBottleItem() const;
    bool IsMajorItem() const;
    bool IsShieldOrTunic() const;
    RandomizerHintTextKey GetHintKey() const;
    const HintText& GetHint() const;
    GetItemCategory GetCategory();
    bool operator==(const Item& right) const;
    bool operator!=(const Item& right) const;
    Item CustomIcon(const char* customIcon_, CustomIconSize iconSize_ = ICON_SIZE_32);
    const char* GetCustomIcon();
    CustomIconSize GetCustomIconSize();
    bool HasCustomIcon();

  private:
    RandomizerGet randomizerGet;
    Text name;
    ItemType type;
    int16_t getItemId;
    bool advancement;
    LogicVal logicVal;
    RandomizerHintTextKey hintKey;
    GetItemCategory category;
    Text article;
    std::string color;
    bool progressive;
    uint16_t price;
    bool playthrough = false;
    std::shared_ptr<GetItemEntry> giEntry;
    const char* customIcon = nullptr;
    CustomIconSize iconSize = ICON_SIZE_32;
};
} // namespace Rando
