#pragma once
// ── CS2 External C++ WebRadar — Entity Base ─────────────────────────────────
// Matches C# EntityBase.cs: base class for reading entity data from CS2 memory.
// Both Player and Entity inherit from this.

#include "core/types.h"
#include "core/memory.h"
#include "core/offsets.h"
#include <cstdint>
#include <windows.h>

class EntityBase {
public:
    EntityBase() = default;
    virtual ~EntityBase() = default;

    // ── Public state ──────────────────────────────────────────────────────
    Team team() const { return m_team; }
    int health() const { return m_health; }
    uint8_t life_state() const { return m_life_state; }
    Vec3 origin() const { return m_origin; }
    Vec3 abs_velocity() const { return m_abs_velocity; }
    uint8_t flags() const { return m_flags; }
    bool is_dormant() const { return m_dormant; }
    bool is_alive() const {
        return m_life_state == LIFE_ALIVE && m_health > 0 &&
               (m_team == Team::Terrorists || m_team == Team::CounterTerrorists);
    }
    bool is_dead() const { return m_life_state == LIFE_DEAD || m_health <= 0; }

    // ── Access handles ───────────────────────────────────────────────────
    HANDLE process_handle() const { return m_proc; }
    std::uintptr_t controller_addr() const { return m_controller_addr; }
    std::uintptr_t pawn_addr() const { return m_pawn_addr; }

    // ── Read controller base address (abstract) ──────────────────────────
    virtual std::uintptr_t read_controller_base(HANDLE proc) = 0;

    // ── Read pawn base address (abstract) ────────────────────────────────
    virtual std::uintptr_t read_address_base(HANDLE proc) = 0;

    // ── Populate common fields ───────────────────────────────────────────
    // After reading base addresses, call this to fill in health/team/origin etc.
    bool update_common(HANDLE proc);

protected:
    HANDLE m_proc = nullptr;

    // Entity addresses
    std::uintptr_t m_controller_addr = 0;
    std::uintptr_t m_pawn_addr = 0;

    // Entity state
    Team m_team = Team::Unknown;
    int m_health = 0;
    uint8_t m_life_state = LIFE_DEAD;
    Vec3 m_origin{};
    Vec3 m_abs_velocity{};
    uint8_t m_flags = 0;
    bool m_dormant = true;
};
