from django.contrib.auth.decorators import login_required
from django.contrib import messages
from django.core.paginator import Paginator
from django.db import transaction
from django.db.models import Count, Q
from django.http import HttpRequest, HttpResponse
from django.shortcuts import render, get_object_or_404, redirect
from django.urls import reverse
from django.utils.translation import ugettext_lazy as _
from django.views.decorators.http import require_POST
from rest_framework.decorators import api_view
from rest_framework.exceptions import ParseError
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK, HTTP_403_FORBIDDEN
from imagetagger.annotations.models import ExportFormat
from imagetagger.annotations.forms import ExportFormatEditForm
from imagetagger.images.forms import ImageSetCreationForm
from imagetagger.images.models import ImageSet
from imagetagger.users.forms import TeamCreationForm
from .models import Team, User


@login_required
def create_team(request):
    form = TeamCreationForm()
    if request.method == 'POST':
        form = TeamCreationForm(request.POST)
        if form.is_valid():
            with transaction.atomic():
                form.instance.save()
                form.instance.memberships.create(user=request.user,
                                                 is_admin=True)
            return redirect(reverse('users:team', args=(form.instance.id,)))
    return render(request, 'users/create_team.html', {
        'form': form,
    })


@login_required
@require_POST
def revoke_team_admin(request, team_id, user_id):
    user = get_object_or_404(User, id=user_id)
    team = get_object_or_404(Team, id=team_id)

    if user == request.user:
        messages.warning(
            request, _('You can not revoke your own admin privileges.').format(
                team.name))
        return redirect(reverse('users:team', args=(team.id,)))

    if team.has_perm('user_management', request.user):
        team.memberships.filter(user=user).update(is_admin=False)
    else:
        messages.warning(
            request,
            _('You do not have permission to revoke this users admin '
              'privileges in the team {}.').format(team.name))

    return redirect(reverse('users:team', args=(team.id,)))


@login_required
@require_POST
def grant_team_admin(request, team_id, user_id):
    user = get_object_or_404(User, id=user_id)
    team = get_object_or_404(Team, id=team_id)

    if not team.members.filter(pk=request.user.pk).exists():
        messages.warning(request, _('You are no member of the team {}.').format(
            team.name))
        return redirect(reverse('users:explore_team'))

    # Allow granting of admin privileges any team member if there is no admin
    if team.has_perm('user_management', request.user) or not team.admins:
        team.memberships.filter(user=user).update(is_admin=True)
    else:
        messages.warning(
            request,
            _('You do not have permission to grant this user admin '
              'privileges in the team {}.').format(team.name))
    return redirect(reverse('users:team', args=(team.id,)))


@login_required
def explore_team(request):
    teams = Team.objects.all()

    query = request.GET.get('query')
    get_query = ''
    if query:
        teams = teams.filter(name__icontains=query)
        get_query = '&query=' + str(query)
    paginator = Paginator(teams, 25)
    page = request.GET.get('page')
    page_teams = paginator.get_page(page)

    return render(request, 'base/explore.html', {
        'mode': 'team',
        'teams': page_teams,  # to separate what kind of stuff is displayed in the view
        'paginator': page_teams,  # for page stuff
        'get_query': get_query,
        'query': query,
    })


@login_required
def explore_user(request):
    users = User.objects.all().order_by('-points')

    query = request.GET.get('query')
    get_query = ''
    if query:
        users = users.filter(username__icontains=query)
        get_query = '&query=' + str(query)
    paginator = Paginator(users, 25)
    page = request.GET.get('page')
    page_users = paginator.get_page(page)

    return render(request, 'base/explore.html', {
        'mode': 'user',
        'users': page_users,  # to separate what kind of stuff is displayed in the view
        'paginator': page_users,  # for page stuff
        'get_query': get_query,
        'query': query,
    })


@login_required
def leave_team(request, team_id, user_id=None):
    team = get_object_or_404(Team, id=team_id)

    user = request.user
    warning = _('You are not in the team.')

    try:
        user_id = int(user_id)
    except ValueError:
        return redirect(reverse('users:team', args=(team.id,)))

    if user_id and user_id != request.user.pk:
        user = get_object_or_404(User, id=user_id)
        warning = _('The user is not in the team.')

        if not team.has_perm('user_management', request.user):
            messages.warning(
                request,
                _('You do not have the permission to kick other users from this team.'))
            return redirect(reverse('users:team', args=(team.id,)))

    if not team.members.filter(pk=user.pk).exists():
        messages.warning(request, warning)
        return redirect(reverse('users:team', args=(team.id,)))

    if request.method == 'POST':
        team.memberships.filter(user=user).delete()
        if team.memberships.count() == 0:
            for imageset in ImageSet.objects.filter(team=team):