#pragma once

#include <cstddef>
#include <memory>
#include <utility>

namespace maps::wiki::common {

/**
 * Values behaviour is the same as in class Pager
 */
struct PageParams
{
    size_t page = 0;
    size_t perPage = 0;
};

/**
 * Paged result helper class
 * considerations:
 * page index starts from 1
 * requesting page 0 or perPage 0 is equivalent of requesting all
 */
class Pager
{
public:
    Pager(size_t total, size_t page, size_t perPage);
    ~Pager();
    Pager(Pager&&) noexcept;
    Pager& operator=(Pager&&) noexcept;
    Pager(const Pager&);
    Pager& operator=(const Pager&);

    size_t totalCount() const;
    size_t page() const;
    size_t perPage() const;
    size_t limit() const;
    size_t offset() const;

private:
    class Impl;
    std::unique_ptr<Impl> impl_;
};

template <typename T>
class PagedResult
{
public:
    PagedResult(Pager pager, T value)
        : pager_(std::move(pager))
        , value_(std::move(value))
    {}

    const Pager& pager() const { return pager_; }

    const T& value() const { return value_; }

    T& value() { return value_; }

    void assignValue(T&& value) { value_ = std::forward<T>(value); }

private:
    Pager pager_;
    T value_;
};

} // namespace maps::wiki::common
