#pragma once

#include "application/contracts/IApplicationTick.h"
#include "application/contracts/IGameTick.h"
#include "features/player/IPlayerCommands.h"
#include "features/player/IPlayerGateway.h"
#include "features/player/IPlayerInput.h"
#include "features/player/IPlayerSettings.h"
#include "features/player/PlayerDiagnostics.h"
#include "foundation/concurrency/CoalescingCommandSlot.h"
#include "features/common/SettingsCache.h"

namespace ta::features::player
{
    class PlayerFeature final : public ta::application::IApplicationTick,
                                public ta::application::IGameTick,
                                public IPlayerCommands
    {
    public:
        PlayerFeature(IPlayerGateway& gateway,
                      IPlayerSettings& settings,
                      IPlayerInput& input) noexcept
            : gateway_(gateway), settings_(settings), input_(input)
        {
        }

        void initialize();
        void on_application_tick() override;
        void on_game_tick() override;
        void reset_session() noexcept;
        void submit(PlayerCommand command) override;
        [[nodiscard]] PlayerDiagnosticsSnapshot diagnostics_snapshot() const noexcept { return diagnostics_.snapshot(); }

    private:
        [[nodiscard]] PlayerSettings current_settings() const;

        IPlayerGateway& gateway_;
        IPlayerSettings& settings_;
        IPlayerInput& input_;
        ta::foundation::CoalescingCommandSlot<PlayerCommand> commands_;
        ta::features::SettingsCache<PlayerSettings> settings_cache_;
        PlayerDiagnostics diagnostics_;
    };
}
