#pragma once

#include <cstddef>
#include <memory>
#include <string>
#include <vector>

#include "features/items/contracts/ItemCatalogTypes.h"

namespace ta::presentation::pages::items
{
    class ItemCatalogModel final
    {
    public:
        using Snapshot = ta::features::items::contracts::ItemCatalogSnapshot;
        using Entry = ta::features::items::contracts::ItemCatalogEntry;

        [[nodiscard]] std::string& search() noexcept { return search_; }
        [[nodiscard]] const std::string& search() const noexcept { return search_; }
        [[nodiscard]] bool& wishlist_only() noexcept { return wishlist_only_; }
        [[nodiscard]] bool wishlist_only() const noexcept { return wishlist_only_; }
        [[nodiscard]] int& category_filter() noexcept { return category_filter_; }
        [[nodiscard]] int category_filter() const noexcept { return category_filter_; }

        void refresh(std::shared_ptr<const Snapshot> snapshot);

        [[nodiscard]] const std::vector<std::size_t>& visible_indices() const noexcept
        {
            return visible_indices_;
        }

        [[nodiscard]] std::size_t wishlist_count() const noexcept
        {
            return wishlist_count_;
        }

        [[nodiscard]] static const Entry* find_by_id(const Snapshot& snapshot,
                                                     const std::string& id) noexcept;

    private:
        bool wishlist_only_ = false;
        int category_filter_ = 0;
        std::string search_;
        std::shared_ptr<const Snapshot> filtered_catalog_;
        std::string filtered_needle_;
        bool filtered_wishlist_only_ = false;
        int filtered_category_ = -1;
        std::vector<std::size_t> visible_indices_;
        std::size_t wishlist_count_ = 0;
    };
}
