# Create your views here.
from django.core.exceptions import ValidationError
from django.http import HttpResponseRedirect
from django.shortcuts import get_object_or_404
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_protect
from django.views.generic.edit import FormView

from accounts.models import BlogUser
from blog.models import Article
from .forms import CommentForm
from .models import Comment


# 定义一个基于类的视图，用于处理用户提交评论的请求
class CommentPostView(FormView):
    # 指定该视图使用的表单类
    form_class = CommentForm

    # 指定表单验证失败时，或需要渲染响应时使用的模板
    template_name = 'blog/article_detail.html'

    @method_decorator(csrf_protect)
    def dispatch(self, *args, **kwargs):
        return super(CommentPostView, self).dispatch(*args, **kwargs)

    def get(self, request, *args, **kwargs):
        # 从 URL 参数中获取文章 ID
        article_id = self.kwargs['article_id']

        # 根据 ID 获取文章对象，若不存在则返回 404 错误
        article = get_object_or_404(Article, pk=article_id)

        # 获取文章的绝对 URL
        url = article.get_absolute_url()

        # 重定向到文章页面，并锚定到 id="comments" 的元素（通常是评论列表）
        return HttpResponseRedirect(url + "#comments")

    def form_invalid(self, form):
        # 获取文章 ID
        article_id = self.kwargs['article_id']

        # 获取对应的文章对象（404 安全获取）
        article = get_object_or_404(Article, pk=article_id)

        # 渲染模板，将表单（含错误）和文章对象传递给模板
        return self.render_to_response({
            'form': form,
            'article': article
        })

    def form_valid(self, form):
        """提交的数据验证合法后的逻辑"""

        # 获取当前登录的用户
        user = self.request.user

        # 获取用户对应的 BlogUser 对象
        author = BlogUser.objects.get(pk=user.pk)

        # 获取 URL 中的文章 ID
        article_id = self.kwargs['article_id']

        # 获取对应的文章对象（404 安全获取）
        article = get_object_or_404(Article, pk=article_id)

        # 检查文章是否允许评论
        # 如果文章的评论状态为 'c'（关闭）或文章状态为 'c'（草稿等），则禁止评论
        if article.comment_status == 'c' or article.status == 'c':
            # 抛出验证错误，阻止评论提交
            raise ValidationError("该文章评论已关闭.")

        # 调用表单的 save 方法，但暂不提交到数据库（commit=False）
        comment = form.save(False)

        # 设置评论所属的文章
        comment.article = article

        # 导入博客设置工具函数
        from djangoblog.utils import get_blog_setting

        # 获取当前博客的全局设置
        settings = get_blog_setting()

        # 如果全局设置中不需要审核评论，则直接启用该评论
        if not settings.comment_need_review:
            comment.is_enable = True

        # 设置评论作者
        comment.author = author

        # 检查表单中是否包含父评论 ID（即是否为回复）
        if form.cleaned_data['parent_comment_id']:
            # 根据父评论 ID 获取父评论对象
            parent_comment = Comment.objects.get(
                pk=form.cleaned_data['parent_comment_id'])
            # 建立父子评论关系
            comment.parent_comment = parent_comment

        # 将评论对象保存到数据库（此时所有字段已设置完毕）
        comment.save(True)

        # 重定向到文章详情页，并定位到刚刚发表的评论
        # 使用锚点 #div-comment-{id} 定位到具体评论
        return HttpResponseRedirect(
            "%s#div-comment-%d" %
            (article.get_absolute_url(), comment.pk))