from django.core.exceptions import PermissionDenied
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from wagtail import hooks

from wagtail.models import Page


def set_page_position(request, page_to_move_id):
    page_to_move = get_object_or_404(Page, id=page_to_move_id)
    parent_page = page_to_move.get_parent()
    position = None

    if not parent_page.permissions_for_user(request.user).can_reorder_children():
        raise PermissionDenied

    if request.method == "POST":
        # Get target_position parameter
        visible_target_position = request.GET.get("position", None)

        # Get position within all children. the frontend position is determined explorer_page queryset.
        if visible_target_position is not None:
            current_page = get_visible_children(parent_page, request)[int(visible_target_position)]
            position = list(parent_page.get_children()).index(current_page)

        # Find page that's already in this position
        position_page = None

        if position is not None:
            try:
                position_page = parent_page.get_children()[position]
            except IndexError:
                pass  # No page in this position

        # Move page
        # any invalid moves *should* be caught by the permission check above,
        # so don't bother to catch InvalidMoveToDescendant

        if position_page:
            # If the page has been moved to the right, insert it to the
            # right. If left, then left.
            old_position = list(parent_page.get_children()).index(page_to_move)
            if position < old_position:
                page_to_move.move(position_page, pos="left", user=request.user)
            elif position > old_position:
                page_to_move.move(position_page, pos="right", user=request.user)
        else:
            # Move page to end
            page_to_move.move(parent_page, pos="last-child", user=request.user)

    return HttpResponse("")

def get_visible_children(parent_page, request):
    """
    Get the pages of parent which are visible to the user. If a hook is used the visible pages are returned by the hook.
    """
    pages = parent_page.get_children()

    for hook in hooks.get_hooks("construct_explorer_page_queryset"):
        pages = hook(parent_page, pages, request)
    return pages
