from django.shortcuts import redirect, get_object_or_404
from django.urls import reverse_lazy
from django.contrib.auth.decorators import login_required
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.db.models import Count, OuterRef, Q, Subquery
from django.views.generic import CreateView, DeleteView, ListView
from django.http import HttpResponseRedirect

from propositions.models import Answer, Proposition


class PropositionCreate(LoginRequiredMixin, CreateView):
    template_name = "propositions/create.html"
    success_url = reverse_lazy("propositions:list")
    model = Proposition
    fields = ["name", "artist", "link"]

    def form_valid(self, form):
        proposition = form.save(commit=False)
        proposition.user = self.request.user
        proposition.save()
        return HttpResponseRedirect(self.success_url)


class PropositionList(LoginRequiredMixin, ListView):
    template_name = "propositions/liste.html"
    context_object_name = "propositions"
    model = Proposition

    def get_queryset(self):
        user = self.request.user
        user_answers = (
            Answer.objects
            .filter(proposition=OuterRef("id"), user=user)
            .values_list("answer", flat=True)
        )
        return (
            Proposition.objects
            .annotate(nb_yes=Count("answer", filter=Q(answer__answer=Answer.YES)))
            .annotate(nb_no=Count("answer", filter=Q(answer__answer=Answer.NO)))
            .annotate(user_answer=Subquery(user_answers[:1]))
            .order_by("-nb_yes", "nb_no", "name")
        )


class PropositionDelete(LoginRequiredMixin, UserPassesTestMixin, DeleteView):
    model = Proposition
    template_name = "propositions/delete.html"
    success_url = reverse_lazy("propositions:list")

    def test_func(self):
        proposition = self.get_object()
        user = self.request.user
        return (proposition.user == user or user.profile.is_chef)


@login_required
def answer(request, id, ans):
    proposition = get_object_or_404(Proposition, id=id)
    user = request.user
    Answer.objects.filter(proposition=proposition, user=user).delete()
    Answer.objects.create(proposition=proposition, user=user, answer=ans)
    return redirect("propositions:list")
