#pragma once

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

#include "adapters/il2cpp/Il2CppObjectInstance.h"
#include "adapters/unity/bindings/UnityTypes.h"
#include "features/items/contracts/WishlistSnapshot.h"
#include "features/esp/contracts/EspTypes.h"

namespace ta::adapters::eft::esp
{
class EspLootScanner
{
public:
    void clear_caches() noexcept;

    void update_loot(ta::adapters::il2cpp::Il2CppObjectInstance game_world_instance,
                     const ta::features::esp::EspSettingsSnapshot& settings,
                     const ta::features::items::contracts::WishlistSnapshot& wishlist,
                     ta::features::esp::EspWorldSnapshot& snapshot,
                     bool refresh_dynamic,
                     bool refresh_static);

private:
    struct CachedObject
    {
        std::string name;
        ta::adapters::unity::vector3 position{};
    };

    Il2CppObject* cached_world_ = nullptr;
    std::vector<CachedObject> cached_corpses_;
    std::vector<CachedObject> cached_containers_;

    void refresh_cached_corpses(ta::adapters::il2cpp::Il2CppObjectInstance game_world_instance);
    void refresh_cached_containers(ta::adapters::il2cpp::Il2CppObjectInstance game_world_instance);
    void scan_corpses_with_origin(ta::adapters::il2cpp::Il2CppObjectInstance game_world_instance,
                                  const ta::features::esp::EspSettingsSnapshot& settings,
                                  const ta::adapters::unity::vector3& origin,
                                  float min_dist_sq,
                                  std::vector<ta::features::esp::EspLootEntry>& result);
    void scan_containers_with_origin(ta::adapters::il2cpp::Il2CppObjectInstance game_world_instance,
                                     const ta::features::esp::EspSettingsSnapshot& settings,
                                     const ta::adapters::unity::vector3& origin,
                                     std::vector<ta::features::esp::EspLootEntry>& result);
};
}
