from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.mixins import PermissionRequiredMixin, LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.core.checks import messages
from django.core.paginator import PageNotAnInteger, EmptyPage
from django.db.models import Count
from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.urls import reverse_lazy
from django.utils.decorators import method_decorator
from django.utils.translation import gettext_lazy as _
from django.views.generic import DeleteView, UpdateView, CreateView
from honeypot.decorators import check_honeypot

from . import PaginatorFilter
from ..filters import MessagesFilterAdmin
from ..forms import MessageForm
from ..models import Event, Message


@method_decorator(check_honeypot, name="post")
class MessageCreateView(SuccessMessageMixin, CreateView):
    model = Message
    template_name = "agenda_culturel/message_create_form.html"
    form_class = MessageForm

    success_url = reverse_lazy("home")
    success_message = _("Your message has been sent successfully.")

    def __init__(self, *args, **kwargs):
        self.event = None
        super().__init__(*args, **kwargs)

    def get_form(self, form_class=None):
        if form_class is None:
            form_class = self.get_form_class()
        return form_class(**self.get_form_kwargs())

    def get_form_kwargs(self):
        kwargs = super().get_form_kwargs()
        kwargs["event"] = self.event
        if self.request.user.is_authenticated:
            kwargs["internal"] = True
        return kwargs

    def form_valid(self, form):
        if self.request.user.is_authenticated:
            form.instance.user = self.request.user
        form.instance.message_type = (
            Message.TYPE.EVENT_REPORT
            if "pk" in self.kwargs
            else Message.TYPE.CONTACT_FORM
        )
        return super().form_valid(form)

    def get_initial(self):
        result = super().get_initial()
        if "pk" in self.kwargs:
            self.event = get_object_or_404(Event, pk=self.kwargs["pk"])
            result["related_event"] = self.event
            result["subject"] = _("Reporting the event {} on {}").format(
                self.event.title, self.event.start_day
            )
        else:
            result["related_event"] = None
        return result


class MessageDeleteView(SuccessMessageMixin, DeleteView):
    model = Message
    success_message = _("The contact message has been successfully deleted.")
    success_url = reverse_lazy("messages")


class MessageUpdateView(
    SuccessMessageMixin,
    PermissionRequiredMixin,
    LoginRequiredMixin,
    UpdateView,
):
    model = Message
    permission_required = "agenda_culturel.change_message"
    template_name = "agenda_culturel/message_moderation_form.html"
    fields = ("spam", "closed", "comments")

    success_message = _(
        "The contact message properties has been successfully modified."
    )

    success_url = reverse_lazy("messages")

    def get_form_kwargs(self):
        """Return the keyword arguments for instantiating the form."""
        kwargs = super().get_form_kwargs()
        if hasattr(self, "object"):
            kwargs.update({"instance": self.object})
        return kwargs


@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.view_message")
def view_messages(request):
    filter = MessagesFilterAdmin(
        request.GET, queryset=Message.objects.all().order_by("-date")
    )
    paginator = PaginatorFilter(filter, 10, request)
    page = request.GET.get("page")

    nb_spams = Message.objects.filter(spam=True).count()

    try:
        response = paginator.page(page)
    except PageNotAnInteger:
        response = paginator.page(1)
    except EmptyPage:
        response = paginator.page(paginator.num_pages)

    return render(
        request,
        "agenda_culturel/messages.html",
        {"filter": filter, "nb_spams": nb_spams, "paginator_filter": response},
    )


@login_required(login_url="/accounts/login/")
@permission_required("agenda_culturel.view_message")
def delete_cm_spam(request):
    if request.method == "POST":
        Message.objects.filter(spam=True).delete()

        messages.success(request, _("Spam has been successfully deleted."))
        return HttpResponseRedirect(reverse_lazy("messages"))
    else:
        nb_msgs = Message.objects.values("spam").annotate(total=Count("spam"))
        nb_total = sum([nb["total"] for nb in nb_msgs])
        nb_spams = sum([nb["total"] for nb in nb_msgs if nb["spam"]])
        cancel_url = reverse_lazy("messages")
        return render(
            request,
            "agenda_culturel/delete_spams_confirm.html",
            {
                "nb_total": nb_total,
                "nb_spams": nb_spams,
                "cancel_url": cancel_url,
            },
        )
