from django.http import Http404
from rest_framework.response import Response


def paginate(
    object_list,
    page,
    per_page,
    orphans=0,
    allow_empty_first_page=True,
    allow_explicit_first_page=False,
    paginator=None,
):
    from django.core.paginator import Paginator, EmptyPage, InvalidPage
    from .exceptions import ExplicitFirstPage

    if page in (1, "1") and not allow_explicit_first_page:
        raise ExplicitFirstPage()
    if not page:
        page = 1

    paginator = paginator or Paginator

    try:
        return paginator(
            object_list,
            per_page,
            orphans=orphans,
            allow_empty_first_page=allow_empty_first_page,
        ).page(page)
    except (EmptyPage, InvalidPage):
        raise Http404()


def pagination_dict(page):
    pagination = {
        "page": page.number,
        "pages": page.paginator.num_pages,
        "count": page.paginator.count,
        "first": None,
        "previous": None,
        "next": None,
        "last": None,
        "before": 0,
        "more": 0,
    }

    if page.has_previous():
        pagination["first"] = 1
        pagination["previous"] = page.previous_page_number()

    if page.has_next():
        pagination["last"] = page.paginator.num_pages
        pagination["next"] = page.next_page_number()

    if page.start_index():
        pagination["before"] = page.start_index() - 1
    pagination["more"] = page.paginator.count - page.end_index()

    return pagination


def paginated_response(page, serializer=None, data=None, extra=None):
    response_data = pagination_dict(page)

    results = list(data or page.object_list)
    if serializer:
        results = serializer(results, many=True).data

    response_data.update({"results": results})

    if extra:
        response_data.update(extra)

    return Response(response_data)


def validate_slug(model, slug):
    from .exceptions import OutdatedSlug

    if model.slug != slug:
        raise OutdatedSlug(model)


def get_int_or_404(value):
    if str(value).isdigit():
        return int(value)
    raise Http404()
