#include <yandex/maps/wiki/common/paged_result.h>

#include <algorithm>
#include <memory>

namespace maps::wiki::common {

class Pager::Impl
{
public:
    Impl(size_t total, size_t page, size_t perPage)
        : totalCount_(total)
        , page_(page ? page : 1)
        , perPage_(perPage ? perPage : total)
    {
        if (perPage_) {
            page_ = std::min(page_, (totalCount_ + perPage_) / perPage_);
        }
    }

    size_t totalCount() const { return totalCount_; }
    size_t page() const { return page_; }
    size_t perPage() const { return perPage_; }
    size_t limit() const { return perPage_; }
    size_t offset() const { return perPage_ * (page_ - 1); }

private:
    size_t totalCount_;
    size_t page_;
    size_t perPage_;
};


Pager::Pager(size_t total, size_t page, size_t perPage)
    : impl_(new Impl(total, page, perPage))
{}

Pager::~Pager() = default;

Pager::Pager(Pager&& other) noexcept
    : impl_(std::move(other.impl_))
{}

Pager& Pager::operator=(Pager&& other) noexcept
{
    impl_ = std::move(other.impl_);
    return *this;
}

Pager::Pager(const Pager& other)
    : impl_(new Impl(*other.impl_))
{}

Pager& Pager::operator=(const Pager& other)
{
    impl_ = std::make_unique<Impl>(*other.impl_);
    return *this;
}

size_t Pager::totalCount() const { return impl_->totalCount(); }

size_t Pager::page() const { return impl_->page(); }

size_t Pager::perPage() const { return impl_->perPage(); }

size_t Pager::limit() const { return impl_->limit(); }

size_t Pager::offset() const { return impl_->offset(); }

} // namespace maps::wiki::common
