#pragma once

#include <algorithm>
#include <cctype>
#include <string>

#include "features/chams/ChamsSettings.h"
#include "foundation/text/StringUtils.h"


struct Il2CppObject;

namespace ta::adapters::unity::chams
{
struct ChamsMaterialState
{
    Il2CppObject* material = nullptr;
    Il2CppObject* shader = nullptr;
    Il2CppObject* main_texture = nullptr;
};

using ChamsConfigSnapshot = ta::features::chams::ChamsSettings;

class ChamsMaterialClassifier
{
public:
    static bool is_scope(const std::string& name)
    {
        const std::string lower = ta::foundation::text::lower_copy(name);
        return contains(lower, "scope") || contains(lower, "optic") || contains(lower, "sight");
    }

    // The old "Include Arms" option affected the local first-person player model,
    // not only the arm meshes. Keep the classifier broad and name it accordingly.
    static bool is_local_player_body(const std::string& name)
    {
        const std::string lower = ta::foundation::text::lower_copy(name);
        return contains(lower, "watch") || contains(lower, "bear") ||
               contains(lower, "usec") || contains(lower, "arm") ||
               contains(lower, "body") || contains(lower, "hands") ||
               contains(lower, "sleeve") || contains(lower, "glove");
    }

    static bool is_weapon_gear(const std::string& name)
    {
        const std::string lower = ta::foundation::text::lower_copy(name);
        return contains(lower, "helmet") || contains(lower, "glasses") || contains(lower, "rig") ||
               contains(lower, "belt") || contains(lower, "wear") || contains(lower, "mask") ||
               contains(lower, "balaclava") || contains(lower, "backpack") || contains(lower, "armor");
    }

    static bool is_npc_gear(const std::string& name)
    {
        const std::string lower = ta::foundation::text::lower_copy(name);
        return contains(lower, "armour") || contains(lower, "armor") || contains(lower, "helmet") ||
               contains(lower, "glasses") || contains(lower, "cover") || contains(lower, "rig") ||
               contains(lower, "belt") || contains(lower, "wear") || contains(lower, "mask") ||
               contains(lower, "balaclava") || contains(lower, "backpack") || contains(lower, "vest");
    }

private:
    static bool contains(const std::string& text, const char* token)
    {
        return text.find(token) != std::string::npos;
    }
};

class ChamsShaderCatalog
{
public:
    static std::string shader_name(int id)
    {
        switch (id)
        {
        case 0: return "chams.shader";
        case 1: return "wireframe.shader";
        case 2: return "forcefield.shader";
        case 3: return "glass.shader";
        case 4: return "lava.shader";
        case 5: return "outline.shader";
        default: return "";
        }
    }
};
}
