#pragma once

#include <cstdint>
#include <memory>
#include <optional>

#include "adapters/eft/esp/EspWorldScanner.h"
#include "adapters/eft/items/wishlist/WishlistService.h"
#include "adapters/eft/runtime/EftGameContext.h"
#include "adapters/unity/camera/UnityCameraFrameSource.h"
#include "external/il2cpp/il2cpp-api-types.h"
#include "features/esp/dependencies/IEspGateway.h"
#include "foundation/concurrency/CopySnapshotPublisher.h"
#include "foundation/concurrency/SharedSnapshotPublisher.h"

namespace ta::adapters::eft::esp
{
class EftEspGateway final : public ta::features::esp::dependencies::IEspGateway
{
public:
    EftEspGateway(ta::adapters::eft::runtime::EftGameContext& context,
                  ta::adapters::eft::items::WishlistService& wishlist_service);
    void application_tick() override;
    void game_tick(const ta::features::esp::EspSettingsSnapshot& settings, std::uint64_t settings_revision) override;
    void reset_session() noexcept override;
    [[nodiscard]] std::shared_ptr<const ta::features::esp::EspWorldSnapshot> world() const noexcept override;
    [[nodiscard]] std::optional<ta::foundation::math::CameraFrame> camera() const override;

private:
    void gameworld_update(
        const ta::adapters::eft::runtime::EftGameContextSnapshot& context,
        const ta::features::esp::EspSettingsSnapshot& settings,
        std::uint64_t settings_revision);
    void clear_raid_data();

    ta::adapters::eft::runtime::EftGameContext& context_;
    ta::foundation::SharedSnapshotPublisher<ta::features::esp::EspWorldSnapshot> snapshot_;
    ta::foundation::CopySnapshotPublisher<ta::foundation::math::CameraFrame> camera_snapshot_;
    ta::adapters::eft::items::WishlistService& wishlist_service_;
    EspWorldScanner world_scanner_;
    ta::features::esp::EspWorldSnapshot working_snapshot_;
    bool has_published_world_ = false;
    int raid_absent_ticks_ = 30;
    bool has_applied_settings_ = false;
    ta::features::esp::EspSettingsSnapshot applied_settings_{};
    std::uint64_t applied_settings_revision_ = 0;
    std::uint64_t applied_wishlist_revision_ = 0;
    std::uint64_t camera_revision_ = 0;
    unsigned long long last_local_position_refresh_ms_ = 0;
    unsigned long long last_player_refresh_ms_ = 0;
    unsigned long long last_dynamic_refresh_ms_ = 0;
    unsigned long long last_exfil_status_refresh_ms_ = 0;
    unsigned long long last_static_refresh_ms_ = 0;
};
}
