from django.contrib import messages
from django.core.paginator import Paginator
from django.db.models import Count, Q
from django.shortcuts import redirect, render
from django.urls import reverse_lazy
from django.views import View

from apps.core.crud import BaseCreateView, BaseDeleteView, BaseUpdateView
from apps.core.mixins import EditeurRequiredMixin

from .forms import CategoryForm, TagForm
from .models import Category, Tag


class CategoryListView(EditeurRequiredMixin, View):
    def get(self, request):
        qs = Category.objects.annotate(nb=Count("articles", filter=Q(articles__deleted_at__isnull=True)))
        if q := request.GET.get("q"):
            qs = qs.filter(Q(nom__icontains=q) | Q(description__icontains=q))
        menu = request.GET.get("menu")
        if menu in ("1", "0"):
            qs = qs.filter(est_dans_menu=menu == "1")
        qs = qs.order_by("-est_dans_menu", "ordre", "nom")
        page = Paginator(qs, 25).get_page(request.GET.get("page"))
        return render(request, "backoffice/taxonomy/categories.html", {"page_obj": page})


class CategoryCreateView(EditeurRequiredMixin, BaseCreateView):
    model = Category
    form_class = CategoryForm
    page_title = "Nouvelle rubrique"
    back_url = reverse_lazy("taxonomy:category-list")
    success_message = "Rubrique « %(nom)s » créée."
    wide_fields = ("description",)


class CategoryUpdateView(EditeurRequiredMixin, BaseUpdateView):
    model = Category
    form_class = CategoryForm
    back_url = reverse_lazy("taxonomy:category-list")
    success_message = "Rubrique « %(nom)s » mise à jour."
    wide_fields = ("description",)


class CategoryDeleteView(EditeurRequiredMixin, BaseDeleteView):
    model = Category
    success_url = reverse_lazy("taxonomy:category-list")
    success_message = "Rubrique supprimée."

    def check(self, obj):
        n = obj.articles.count()
        if n:
            return f"Impossible de supprimer « {obj} » : elle contient {n} article(s) (corbeille comprise). Déplacez-les d'abord."


class TagListView(EditeurRequiredMixin, View):
    def get(self, request, form=None):
        qs = Tag.objects.annotate(nb=Count("articles"))
        if q := request.GET.get("q"):
            qs = qs.filter(nom__icontains=q)
        page = Paginator(qs.order_by("nom"), 40).get_page(request.GET.get("page"))
        return render(request, "backoffice/taxonomy/tags.html", {"page_obj": page, "form": form or TagForm()})

    def post(self, request):
        form = TagForm(request.POST)
        if form.is_valid():
            tag = form.save()
            messages.success(request, f"Mot-clé « {tag} » ajouté.")
            return redirect("taxonomy:tag-list")
        return self.get(request, form=form)


class TagUpdateView(EditeurRequiredMixin, BaseUpdateView):
    model = Tag
    form_class = TagForm
    back_url = reverse_lazy("taxonomy:tag-list")
    success_message = "Mot-clé mis à jour."


class TagDeleteView(EditeurRequiredMixin, BaseDeleteView):
    model = Tag
    success_url = reverse_lazy("taxonomy:tag-list")
    success_message = "Mot-clé supprimé (retiré des articles concernés)."
