PAGE_SIZE_OPTIONS = (10, 20, 30)


def get_page_size(request, default):
    try:
        page_size = int(request.GET.get("page_size", default))
    except (TypeError, ValueError):
        return default

    return page_size if page_size in PAGE_SIZE_OPTIONS else default


def build_query_string(request, **updates):
    query = request.GET.copy()

    for key, value in updates.items():
        if value is None:
            query.pop(key, None)
        else:
            query[key] = value

    return query.urlencode()


def build_pagination_context(request, page_obj, paginator):
    page_range = paginator.get_elided_page_range(page_obj.number)
    page_size = paginator.per_page

    return {
        "page_size": page_size,
        "page_size_options": [
            {
                "value": option,
                "url": f"?{build_query_string(request, page_size=option, page=None)}",
                "is_current": option == page_size,
            }
            for option in PAGE_SIZE_OPTIONS
        ],
        "pages": [
            {
                "number": page_num,
                "url": f"?{build_query_string(request, page=page_num)}"
                if page_num != "…"
                else "",
                "is_current": page_num == page_obj.number,
                "is_ellipsis": page_num == "…",
            }
            for page_num in page_range
        ],
        "previous_url": f"?{build_query_string(request, page=page_obj.previous_page_number())}"
        if page_obj.has_previous()
        else "",
        "next_url": f"?{build_query_string(request, page=page_obj.next_page_number())}"
        if page_obj.has_next()
        else "",
    }
