#pragma once
// ── CS2 External C++ WebRadar — Entity (non-local player) ───────────────────
// Matches C# Entity.cs: reads full player fields for non-local players.
// Inherits EntityBase.

#include "game/entity_base.h"
#include "core/offsets.h"
#include <string>
#include <vector>
#include <windows.h>

// ── Weapon slot info ────────────────────────────────────────────────────────
struct WeaponSlot {
    int32_t item_def_index = 0;
    int32_t clip = 0;
    int32_t reserve = 0;
    int32_t max_clip = 0;
    std::string name;
    std::string icon;
    int ammo_type = 0; // 0=primary, 1=secondary
};

class Entity : public EntityBase {
public:
    Entity() = default;

    // ── Public state ──────────────────────────────────────────────────────
    const std::string& name() const { return m_name; }
    int32_t controller_index() const { return m_controller_index; }

    // Weapon
    int32_t active_weapon_index() const { return m_active_weapon_index; }
    const std::string& weapon_name() const { return m_weapon_name; }
    const std::string& weapon_icon() const { return m_weapon_icon; }
    int32_t clip() const { return m_clip; }
    int32_t reserve() const { return m_reserve; }
    const std::vector<WeaponSlot>& weapon_inventory() const { return m_weapon_inventory; }

    // Armor / equipment
    int32_t armor() const { return m_armor; }
    bool has_helmet() const { return m_has_helmet; }
    bool has_defuser() const { return m_has_defuser; }

    // Economy
    int32_t money() const { return m_money; }
    int32_t kills() const { return m_kills; }
    int32_t deaths() const { return m_deaths; }
    int32_t assists() const { return m_assists; }
    int32_t score() const { return m_score; }
    int32_t ping() const { return m_ping; }

    // State flags
    float flash_alpha() const { return m_flash_alpha; }
    bool is_scoped() const { return m_is_scoped; }
    bool is_walking() const { return m_is_walking; }
    bool has_bomb() const { return m_has_bomb; }
    bool is_planting() const { return m_is_planting; }
    bool is_defusing() const { return m_is_defusing; }
    bool is_reloading() const { return m_is_reloading; }
    bool is_ducking() const { return m_is_ducking; }
    bool is_observed() const { return m_is_observed; }
    float head_yaw() const { return m_head_yaw; }

    // Character model
    const std::string& character_model() const { return m_character_model; }

    // ── Static lookups ────────────────────────────────────────────────────
    static std::string weapon_index_to_name(int32_t idx);
    static std::string weapon_index_to_icon(int32_t idx);
    static std::string character_def_index_to_model(int32_t idx);

    // ── Full update ───────────────────────────────────────────────────────
    // Reads controller base, pawn base, then all entity fields.
    // entity_index is the controller index for this player.
    bool update(HANDLE proc, int32_t entity_index, std::uintptr_t client_base);

    // ── Base overrides ────────────────────────────────────────────────────
    std::uintptr_t read_controller_base(HANDLE proc) override;
    std::uintptr_t read_address_base(HANDLE proc) override;
    void set_client_base(std::uintptr_t base) { m_client_base = base; }
    std::uintptr_t client_base() const { return m_client_base; }

    // ── Bone positions ────────────────────────────────────────────────────
    void update_bone_positions(HANDLE proc);
    Vec3 bone_position(int bone_id) const;
    const std::vector<Vec3>& bone_positions() const { return m_bone_positions; }

private:
    // Identity
    std::string m_name;
    int32_t m_controller_index = -1;

    // Weapon
    int32_t m_active_weapon_index = 0;
    std::string m_weapon_name;
    std::string m_weapon_icon;
    int32_t m_clip = 0;
    int32_t m_reserve = 0;
    std::vector<WeaponSlot> m_weapon_inventory;

    // Armor / equipment
    int32_t m_armor = 0;
    bool m_has_helmet = false;
    bool m_has_defuser = false;

    // Economy
    int32_t m_money = 0;
    int32_t m_kills = 0;
    int32_t m_deaths = 0;
    int32_t m_assists = 0;
    int32_t m_score = 0;
    int32_t m_ping = 0;

    // State
    float m_flash_alpha = 0;
    bool m_is_scoped = false;
    bool m_is_walking = false;
    bool m_has_bomb = false;
    bool m_is_planting = false;
    bool m_is_defusing = false;
    bool m_is_reloading = false;
    bool m_is_ducking = false;
    bool m_is_observed = false;
    float m_head_yaw = 0;

    // Character model
    std::string m_character_model;

    // Bones
    std::vector<Vec3> m_bone_positions;

    // Client module base (set during update)
    std::uintptr_t m_client_base = 0;

    // ── Internal readers ──────────────────────────────────────────────────
    void read_name(HANDLE proc);
    void read_weapon(HANDLE proc);
    void read_inventory(HANDLE proc);
    void read_armor(HANDLE proc);
    void read_money(HANDLE proc);
    void read_stats(HANDLE proc);
    void read_ping(HANDLE proc);
    void read_flags(HANDLE proc);
    void read_character_model(HANDLE proc);
};
