from django.db.models import Count
from django.core.urlresolvers import reverse_lazy
from django.views.generic import \
    CreateView, \
    DetailView, \
    ListView, \
    UpdateView, \
    DeleteView \

from django.views.generic.detail import SingleObjectMixin

from .mixins import StaffRequiredMixin
from .models import Post, Category
from .forms import PostForm


class PostDetail(DetailView):
    model = Post


class PostList(ListView):
    model = Post
    paginate_by = 3

    # Крім списку постів, додамо до контексту ще 5 найпопулярніших категорій
    categories_to_show = 5

    def get_popular_categories(self):
        """
        Витягає з бази даних категорії, анотує кожен об’єкт
        Категорії кількістю прив’язаних постів, сортує їх за
        цією кількістю, і повертає 5 штук
        """
        popular_categories = Category.objects       \
            .annotate(post_count=Count('post'))     \
            .order_by('-post_count')                \

        return popular_categories[:self.categories_to_show]

    def get_context_data(self, *args, **kwargs):
        """
        Доповнює контекст п’ятьма найпопулярнішими категоріями
        """
        context = super(PostList, self).get_context_data(*args, **kwargs)
        context['category_list'] = self.get_popular_categories()
        return context


class PostCreate(StaffRequiredMixin, CreateView):
    model = Post

    # Замість того, шоб генерувати стандартну форму, зробимо кастомну
    # Ця форма визначена у forms.py
    form_class = PostForm


class PostUpdate(StaffRequiredMixin, UpdateView):
    model = Post
    form_class = PostForm


class PostDelete(StaffRequiredMixin, DeleteView):
    model = Post
    success_url = reverse_lazy('blog')


class CategoryList(ListView):
    model = Category


class CategoryDetail(SingleObjectMixin, ListView):

    """
    Приклад змішування DetailView + ListView
    """

    template_name = 'blog/category_detail.html'
    paginate_by = 2

    def get(self, request, page=1, *args, **kwargs):
        self.object = self.get_object(queryset=Category.objects.all())
        return super(CategoryDetail, self).get(request, *args, **kwargs)

    def get_context_data(self, **kwargs):
        context = super(CategoryDetail, self).get_context_data(**kwargs)
        context['category'] = self.object
        context['object'] = self.object
        return context

    def get_queryset(self):
        return self.object.post_set.all()
