#pragma once

#ifndef NOMINMAX
#define NOMINMAX
#endif

#include <cstdint>
#include <string>
#include <vector>
#include <memory>

#include "memory/imemory_reader.hpp"

namespace visual {

enum class ModCategory : uint32_t {
    Default = 0,
    PhysicalAttack = 1,       // 🔴 Red: Phys, Attack Speed, Crit, Armor, Bleed
    SpellElemental = 2,       // 🔵 Blue: Spell, Cast Speed, Mana, Energy Shield, Ele Dmg
    DefenseResistSpeed = 3,   // 🟢 Green: Move Speed, Evasion, Resists (Fire, Cold, Light, Chaos)
    Tier1Rare = 4             // 🟡 Gold: T1 rolls, Fractured, Synthesised, Influenced
};

struct ColorRgb {
    uint8_t r = 255;
    uint8_t g = 255;
    uint8_t b = 255;
    uint8_t a = 255;

    constexpr ColorRgb() = default;
    constexpr ColorRgb(uint8_t r_, uint8_t g_, uint8_t b_, uint8_t a_ = 255)
        : r(r_), g(g_), b(b_), a(a_) {}

    uint32_t ToHex() const {
        return (static_cast<uint32_t>(r) << 16) |
               (static_cast<uint32_t>(g) << 8)  |
               static_cast<uint32_t>(b);
    }
};

class ModColorizer {
public:
    explicit ModColorizer(IMemoryReader& memory);
    ~ModColorizer();

    // Text classification: determines color group from mod string
    static ModCategory ClassifyMod(const std::string& modText);

    // Color definitions
    static ColorRgb GetCategoryColor(ModCategory category);
    static uint32_t GetCategoryColorHex(ModCategory category);
    static const char* GetCategoryName(ModCategory category);

    // Formats a string with ANSI / ImGui / BBCode-style color tags for UI display
    static std::string FormatColoredBBCode(const std::string& text, ModCategory category);

    // In-memory font table patcher for game process
    bool SetFontColorTableAddress(uintptr_t address, size_t size = 16);
    uintptr_t FontColorTableAddress() const { return colorTableAddr_; }

    bool ApplyColorPatches();
    bool RestoreColorPatches();
    void PanicRestoreAll();

    bool IsPatched() const { return isPatched_; }

private:
    IMemoryReader& memory_;
    uintptr_t colorTableAddr_ = 0;
    size_t tableSize_ = 0;
    std::vector<uint8_t> originalBytes_;
    std::vector<uint8_t> patchedBytes_;
    bool isPatched_ = false;
};

} // namespace visual
