#pragma once

#include <cstdint>

#include "application/contracts/IApplicationTick.h"
#include "application/contracts/IGameTick.h"
#include "features/esp/contracts/IEspQueries.h"
#include "features/esp/dependencies/IEspGateway.h"
#include "features/esp/dependencies/IEspSettings.h"
#include "features/common/SettingsCache.h"
#include "foundation/concurrency/SharedSnapshotPublisher.h"

namespace ta::features::esp
{
    class EspFeature final : public ta::application::IApplicationTick,
                             public ta::application::IGameTick,
                             public contracts::IEspQueries
    {
    public:
        EspFeature(dependencies::IEspGateway& gateway, dependencies::IEspSettings& settings) noexcept
            : gateway_(gateway), settings_source_(settings)
        {
        }

        void initialize();
        void on_application_tick() override;
        void on_game_tick() override;
        void reset_session() noexcept;
        [[nodiscard]] std::shared_ptr<const EspSettingsSnapshot> settings() const noexcept override;
        [[nodiscard]] std::shared_ptr<const EspWorldSnapshot> world() const noexcept override;
        [[nodiscard]] std::optional<ta::foundation::math::CameraFrame> camera() const override;

    private:

        dependencies::IEspGateway& gateway_;
        dependencies::IEspSettings& settings_source_;
        ta::features::SettingsCache<
            EspSettingsSnapshot,
            ta::foundation::SharedSnapshotPublisher<EspSettingsSnapshot>> settings_cache_;
    };
}
