#pragma once
// ── CS2 External C++ WebRadar — Observer Target Writer ──────────────────────
// Matches C# ObserverTargetWriter.cs: writes a player's observer target to
// enable spectating through their eyes. Uses WriteProcessMemory.

#include "game/game_data.h"
#include <windows.h>

class ObserverTargetWriter {
public:
    ObserverTargetWriter() = default;

    // Set the local player's observer target to the given entity index.
    // Writes the target's pawn handle to the local player's observer services.
    static bool set_observer_target(GameData& game_data, int target_entity_index) {
        auto proc = game_data.game_process()->handle();
        if (!proc || !game_data.game_process()->is_valid()) return false;

        auto player = game_data.player();
        if (!player || !player->is_alive()) return false;

        // Find the target entity by controller index
        for (const auto& entity : game_data.entities()) {
            // The entity's controller_index matches target_entity_index
            // In practice, we need to find the entity's pawn handle
            // and write m_hObserverTarget on the local player

            // Read target pawn handle via controller + m_hPawn
            int32_t target_idx = target_entity_index;
            if (entity->is_alive()) {
                // Resolve the observable pawn handle from controller
                // and write it to local player observer services
                auto target_controller = entity->controller_addr();
                if (!target_controller) continue;

                auto target_pawn_handle = rpm<std::uintptr_t>(proc,
                    target_controller + Offsets::m_hPawn);
                if (!target_pawn_handle) continue;

                // Write to local player's observer services
                auto pawn = player->pawn_addr();
                if (!pawn) return false;

                auto observer_services = rpm<std::uintptr_t>(proc,
                    pawn + Offsets::m_pObserverServices);
                if (!observer_services) return false;

                // Write observer target handle
                return wpm(proc, observer_services + Offsets::m_hObserverTarget,
                          target_pawn_handle);
            }
        }

        return false;
    }
};
