#include "adapters/eft/items/wishlist/WishlistService.h"

#include "adapters/eft/items/wishlist/WishlistReader.h"

namespace ta::adapters::eft::items
{
    WishlistService::WishlistService()
        : reader_(std::make_unique<ta::adapters::eft::items::WishlistReader>())
    {
    }

    WishlistService::~WishlistService() = default;

    void WishlistService::update(ta::adapters::il2cpp::Il2CppObjectInstance& main_player)
    {
        Il2CppObject* player = main_player.get_instance();
        if (!player)
        {
            if (last_player_)
                clear();
            return;
        }

        if (player != last_player_)
        {
            last_player_ = player;
            next_refresh_at_ = {};
            refresh_requested_.store(true, std::memory_order_release);
        }

        const bool requested = refresh_requested_.exchange(false, std::memory_order_acq_rel);
        const auto now = std::chrono::steady_clock::now();
        if (!requested && now < next_refresh_at_)
            return;

        next_refresh_at_ = now + periodic_refresh_interval_;
        if (reader_->refresh(main_player))
            ++revision_;
    }

    void WishlistService::set_periodic_refresh_interval(const std::chrono::milliseconds interval) noexcept
    {
        const auto sanitized = interval.count() > 0 ? interval : std::chrono::milliseconds(1);
        if (periodic_refresh_interval_ == sanitized)
            return;

        periodic_refresh_interval_ = sanitized;
        next_refresh_at_ = std::chrono::steady_clock::now() + periodic_refresh_interval_;
    }

    void WishlistService::request_refresh() noexcept
    {
        refresh_requested_.store(true, std::memory_order_release);
    }

    void WishlistService::clear() noexcept
    {
        reader_->clear();
        last_player_ = nullptr;
        next_refresh_at_ = {};
        refresh_requested_.store(true, std::memory_order_release);
        ++revision_;
    }

    const ta::features::items::contracts::WishlistSnapshot& WishlistService::current() const noexcept
    {
        return reader_->current();
    }

    std::uint64_t WishlistService::revision() const noexcept
    {
        return revision_;
    }
}
