from apps.core.cache.static_cache import StaticCacheManager
from apps.core.models.sensitive_config import SensitiveConfig
from apps.core.models.static_settings import StaticSettings
from apps.core.utils.hash import unhash_id
from apps.core.utils.sensitive_filter import SensitiveFilter
from django.conf import settings
from django.db.models import F
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from django.views.generic import DetailView
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView

from ..models import Wiki


class WikiDetailView(DetailView):
    model = Wiki
    context_object_name = "wiki"

    def get_template_names(self):
        # theme = getattr(self.request, 'current_theme', 'default') template
        theme = settings.THEME_NAME
        #文章个性模板>栏目内容模板>主题模型内容页templates/articles/article_item.html
        #themes/default/templates/articles/article_item.html是最后的容灾收段
        templates = []
        if self.object.template:
            templates.append(
                self.object.template.replace(
                    f'{settings.BASE_DIR}/templates/themes/', ''))
        if self.object.category.content_template:
            templates.append(
                self.object.category.content_template.replace(
                    f'{settings.BASE_DIR}/templates/themes/', ''))
        model_name = self.object.category.content_type.model
        templates.extend([
            f"themes/{theme}/templates/item/{model_name}_item.html",
            f"themes/default/templates/item/{model_name}_item.html"
        ])

        return templates

    def dispatch(self, request, *args, **kwargs):
        # 获取当前主题和备用模板路径
        theme = getattr(settings, 'THEME_NAME', 'default')
        templates = [
            f"themes/{theme}/templates/utils/403_restricted.html",
            "themes/default/templates/utils/403_restricted.html"
        ]
        # 先获取对象再校验权限
        self.object = self.get_object()
        if (self.object.staff_only or
                self.object.category.staff_only) and not request.user.is_staff:
            return render(request,
                          templates, {'message': '该内容仅限工作人员查看'},
                          status=403)
        if (self.object.allowed_groups.exists()
                and not self.object.allowed_groups.filter(
                    id__in=request.user.groups.all()).exists()) or (
                        self.object.category.allowed_groups.exists()
                        and not self.object.category.allowed_groups.filter(
                            id__in=request.user.groups.all()).exists()):
            return render(request,
                          templates, {'message': '您所在的用户组无权查看此内容'},
                          status=403)
        return super().dispatch(request, *args, **kwargs)

    def get_queryset(self):
        """基础查询集：仅限已发布状态"""
        return super().get_queryset().filter(status=Wiki.StatusChoices.REVIEW)

    def get_object(self, **kwargs):
        # 判断路径模式
        if 'pk' in self.kwargs:
            try:
                int(self.kwargs['pk'])
                return self._pk()
            except:
                return self._handle_hash()
        return super().get_object()

    def _pk(self):
        print("self.kwargs['pk']=>", self.kwargs['pk'])
        return get_object_or_404(Wiki, pk=self.kwargs['pk'], status=99)

    def _handle_hash(self):
        return get_object_or_404(Wiki,
                                 pk=int(unhash_id(self.kwargs['pk'])),
                                 status=99)

    def get_context_data(self, **kwargs):
        """扩展上下文：添加相邻文章、相关百科等"""
        context = super().get_context_data(**kwargs)
        obj = self.object
        obj_update_fields = []
        if not obj.previous_obj:
            previous_article = Wiki.objects.filter(
                status=99, create_time__lt=obj.create_time).order_by(
                    '-create_time').first()
            if previous_article:
                obj.previous_obj = previous_article
                obj_update_fields.append('previous_obj')
                #同步更新相关文章
                previous_article.next_obj = obj
                previous_article.save(update_fields=['next_obj'])
        if not obj.next_obj:
            next_article = Wiki.objects.filter(
                status=99, create_time__gt=obj.create_time).order_by(
                    'create_time').first()
            if next_article:
                obj.next_obj = next_article
                obj_update_fields.append('next_obj')
                #同步更新相关文章
                next_article.previous_obj = obj
                next_article.save(update_fields=['previous_obj'])

            # 更新当前文章关联字段‌:ml-citation{ref="2" data="citationList"}

        if obj_update_fields:
            obj.save(update_fields=obj_update_fields)
        #开始处理敏感词
        config = SensitiveConfig.get_solo()
        sensitive_filter = SensitiveFilter(config)
        sensitive_fields = ['title', 'meta_description', 'basic', 'content']
        if config.filter_switch:
            for field in sensitive_fields:
                # 1. 检查字段是否存在
                if not hasattr(obj, field):
                    continue

                # 2. 获取原始值并处理
                original_value = getattr(obj, field)
                processed_value = sensitive_filter.process_text(original_value)

                setattr(obj, field, processed_value)

        # 相关百科（自动过滤已发布）
        context["related_wikis"] = obj.about.filter(
            status=Wiki.StatusChoices.REVIEW)[:6]  # 限制数量
        # 获取关联内容
        articles = obj.articles.filter(status=99)

        context.update({
            'obj': obj,
            'articles': articles,
            # 可扩展其他内容类型（wiki/downloads）
        })
        return context

    def get(self, request, *args, **kwargs):
        """自定义 GET 处理（可选）"""
        filename = request.path_info
        self.static_config = StaticSettings.get_solo()
        manager = StaticCacheManager(self.static_config.high_safe,
                                     self.static_config.static_tag)
        self.object = self.get_object()
        # 获取静态内容

        if self.static_config.static_key:
            static_content = manager.get(filename)
            if static_content:
                return HttpResponse(static_content)

            # 执行父类get方法完成常规处理
        response = super().get(request, *args, **kwargs)
        if self.static_config.static_key:
            manager.create(filename, response.render().content.decode('utf-8'))

        return response


class WikiHitAPIView(APIView):

    def get(self, request, pk):
        # 使用F表达式原子性更新hits字段
        updated = Wiki.objects.filter(pk=pk,
                                      status=99).update(hits=F('hits') + 1)
        if not updated:
            # 状态不符或对象不存在时返回404
            return Response({"detail": "指定文章不存在或未发布"},
                            status=status.HTTP_404_NOT_FOUND)
        # 获取更新后的值（需重新查询）
        updated_hits = Wiki.objects.get(pk=pk).hits
        return Response({'hits': updated_hits})
