#hz 评论模块的视图处理
#hz 本模块定义了评论提交相关的视图类，处理用户评论的提交、验证和保存逻辑

# 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


#hz 评论提交视图类
#hz 继承自FormView，用于处理评论表单的提交和验证
class CommentPostView(FormView):
    #hz 使用的表单类
    form_class = CommentForm
    #hz 渲染模板名称
    template_name = 'blog/article_detail.html'

    #hz 请求分发方法，添加CSRF保护装饰器，防止跨站请求伪造攻击
    @method_decorator(csrf_protect)
    def dispatch(self, *args, **kwargs):
        return super(CommentPostView, self).dispatch(*args, **kwargs)

    #hz 处理GET请求的方法
    #hz 当用户通过GET方式访问评论提交URL时，重定向到文章详情页的评论区域
    def get(self, request, *args, **kwargs):
        #hz 从URL参数中获取文章ID
        article_id = self.kwargs['article_id']
        #hz 获取文章对象，如果不存在则返回404错误
        article = get_object_or_404(Article, pk=article_id)
        #hz 获取文章的绝对URL
        url = article.get_absolute_url()
        #hz 重定向到文章详情页的评论区域（通过锚点#comments定位）
        return HttpResponseRedirect(url + "#comments")

    #hz 表单验证失败时的处理方法
    #hz 当用户提交的评论表单验证失败时，重新渲染文章详情页并显示表单错误信息
    def form_invalid(self, form):
        #hz 从URL参数中获取文章ID
        article_id = self.kwargs['article_id']
        #hz 获取文章对象，如果不存在则返回404错误
        article = get_object_or_404(Article, pk=article_id)

        #hz 返回包含表单和文章对象的响应，用于重新渲染页面并显示错误信息
        return self.render_to_response({
            'form': form,
            'article': article
        })

    #hz 表单验证成功时的处理方法
    #hz 提交的数据验证合法后的逻辑：保存评论、处理嵌套评论、设置审核状态等
    def form_valid(self, form):
        """提交的数据验证合法后的逻辑"""
        #hz 获取当前登录用户
        user = self.request.user
        #hz 获取用户对应的BlogUser对象
        author = BlogUser.objects.get(pk=user.pk)
        #hz 从URL参数中获取文章ID
        article_id = self.kwargs['article_id']
        #hz 获取文章对象，如果不存在则返回404错误
        article = get_object_or_404(Article, pk=article_id)

        #hz 检查文章的评论状态和文章状态，如果评论已关闭或文章已关闭，则抛出验证错误
        if article.comment_status == 'c' or article.status == 'c':
            raise ValidationError("该文章评论已关闭.")
        #hz 保存表单数据但不提交到数据库（commit=False），以便进一步处理
        comment = form.save(False)
        #hz 设置评论关联的文章
        comment.article = article
        #hz 获取博客设置，用于判断评论是否需要审核
        from djangoblog.utils import get_blog_setting
        settings = get_blog_setting()
        #hz 如果博客设置中不需要审核评论，则直接启用评论（设置为可见）
        if not settings.comment_need_review:
            comment.is_enable = True
        #hz 设置评论的作者
        comment.author = author

        #hz 处理嵌套评论：如果表单中包含父评论ID，则设置评论的父评论
        if form.cleaned_data['parent_comment_id']:
            #hz 获取父评论对象
            parent_comment = Comment.objects.get(
                pk=form.cleaned_data['parent_comment_id'])
            #hz 设置评论的父评论，实现评论回复功能
            comment.parent_comment = parent_comment

        #hz 保存评论到数据库（commit=True）
        comment.save(True)
        #hz 重定向到文章详情页并定位到新提交的评论位置（通过锚点定位）
        return HttpResponseRedirect(
            "%s#div-comment-%d" %
            (article.get_absolute_url(), comment.pk))
