#pragma once

#include <vector>

#include "application/contracts/IApplicationTick.h"
#include "application/contracts/IGameTick.h"
#include "features/world/IWorldCommands.h"
#include "features/world/IWorldGateway.h"
#include "features/world/IWorldSettings.h"
#include "features/world/WorldDiagnostics.h"
#include "foundation/concurrency/CoalescingCommandSlot.h"
#include "features/common/SettingsCache.h"

namespace ta::features::world
{
    class WorldFeature final : public ta::application::IApplicationTick,
                               public ta::application::IGameTick,
                               public IWorldCommands
    {
    public:
        WorldFeature(IWorldGateway& gateway, IWorldSettings& settings) noexcept
            : gateway_(gateway), settings_(settings)
        {
        }

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

    private:
        [[nodiscard]] WorldSettings current_settings() const;
        [[nodiscard]] std::vector<WorldCommand> consume_commands();
        static const char* action_name(WorldCommandType type) noexcept;

        IWorldGateway& gateway_;
        IWorldSettings& settings_;
        ta::features::SettingsCache<WorldSettings> settings_cache_;
        ta::foundation::CoalescingCommandSlot<WorldCommand> unlock_command_;
        ta::foundation::CoalescingCommandSlot<WorldCommand> teleport_command_;
        WorldDiagnostics diagnostics_;
    };
}
