from django.shortcuts import render, reverse, redirect, get_object_or_404
from django.urls import reverse, reverse_lazy
from django.db import models
from django.views.generic.base import TemplateView
from django.views.generic.detail import DetailView
from django.views.generic.list import ListView
from django.views.generic.edit import (
    FormView, CreateView, UpdateView, DeleteView, FormMixin
)
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.messages.views import SuccessMessageMixin
from django.contrib.contenttypes.models import ContentType

from .models import Topic, Post, Comment
from .forms import PostForm, CommentCreateForm


class CommentListView(LoginRequiredMixin, ListView):
    model = Comment


class CommentDetailView(LoginRequiredMixin, DetailView):
    model = Comment


class CommentCreateView(LoginRequiredMixin, CreateView):
    model = Comment
    form_class = CommentCreateForm
    template_name_suffix = '_create_form'

    # def get_success_url(self):
    #     return self.object.content_object.get_absolute_url()

    def form_valid(self, form):
        form.instance.author = self.request.user
        form.send_notification()
        return super().form_valid(form)


class CommentUpdateView(
    LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView
):
    model = Comment
    success_message = 'Comment saved.'
    fields = ['content']

    def test_func(self):
        return self.request.user.pk == self.get_object().author.pk

    def get_success_url(self):
        return self.object.content_object.get_absolute_url()


class CommentDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
    model = Comment
    success_message = 'Comment deleted.'
    success_url = reverse_lazy('core:comment-list')


class TopicListView(LoginRequiredMixin, ListView):
    model = Topic

    def get_queryset(self):
        queryset = Topic.objects.annotate(
            models.Count('post')
        )
        return queryset


class TopicCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = Topic
    success_message = 'Topic created.'
    template_name_suffix = '_create_form'
    fields = '__all__'


class TopicDetailView(LoginRequiredMixin, DetailView):
    model = Topic
    pk_url_kwarg = 'topic_pk'


class TopicUpdateView(LoginRequiredMixin, SuccessMessageMixin, UpdateView):
    model = Topic
    pk_url_kwarg = 'topic_pk'
    success_message = 'Topic saved.'
    fields = [
        'name',
        'description'
    ]


class TopicDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
    model = Topic
    pk_url_kwarg = 'topic_pk'
    success_message = 'Topic deleted.'
    success_url = reverse_lazy('topic-list')


class PostListView(ListView):
    model = Post


class PostCreateView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
    model = Post
    success_message = 'Post created.'
    template_name_suffix = '_create_form'
    form_class = PostForm

    def get_context_data(self, *args, **kwargs):
        context = super().get_context_data(*args, **kwargs)
        context['topic'] = get_object_or_404(Topic, pk=self.kwargs['topic_pk'])
        return context

    def form_valid(self, form):
        form.instance.author = self.request.user
        form.instance.topic = get_object_or_404(
            Topic, pk=self.kwargs['topic_pk']
        )
        return super().form_valid(form)


class PostDetailView(LoginRequiredMixin, DetailView):
    model = Post
    pk_url_kwarg = 'post_pk'

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        object_content_type = ContentType.objects.get_for_model(self.object).pk

        context['comment_create_form'] = CommentCreateForm(initial={
            'content_type': object_content_type,
            'object_id': self.object.pk
        })
        return context


class PostUpdateView(
    LoginRequiredMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView
):
    model = Post
    pk_url_kwarg = 'post_pk'
    success_message = 'Post saved.'
    form_class = PostForm

    def test_func(self):
        return self.request.user.pk == self.get_object().author.pk


class PostDeleteView(LoginRequiredMixin, SuccessMessageMixin, DeleteView):
    model = Post
    pk_url_kwarg = 'post_pk'
    success_message = 'Post deleted.'
    success_url = reverse_lazy('core:topic-list')
