from apps.content.models import Category
from apps.core.cache.conditional_cache_page import conditional_cache_page
from apps.core.cache.static_cache import StaticCacheManager
from apps.core.models.static_settings import StaticSettings
from apps.core.utils.hash import unhash_id
from django.conf import settings
from django.http import HttpResponse
from django.shortcuts import get_object_or_404, render
from django.utils.decorators import method_decorator
from django.views.generic import DetailView


@method_decorator(conditional_cache_page(settings.CHANNEL_TIMEOUT),
                  name='dispatch')
class CategoryDetailView(DetailView):
    model = Category
    """智能栏目页处理器"""

    def get_template_names(self):
        #栏目首页模板>主题模型templates/category/categorylist.html
        #themes/default/templates/category/categorylist.html是最后的容灾收段
        theme = settings.THEME_NAME
        templates = []
        if self.object.index_template:
            templates.append(
                self.object.index_template.replace(
                    f'{settings.BASE_DIR}/templates/themes/', ''))
        model_name = self.object.content_type.model
        # templates.append(f'category/{model_name}_list.html')
        templates.extend([
            f"themes/{theme}/templates/category/{model_name}_list.html",
            f"themes/default/templates/category/{model_name}_list.html"
        ])
        return templates
        # 按栏目类型回退模板
        # return {
        #     1: 'normal_category.html',
        #     2: 'wiki_category.html',
        #     3: 'download_category.html'
        # }.get(self.object.cate_type, 'category_base.html')
    def dispatch(self, request, *args, **kwargs):
        # 先获取对象再校验权限
        self.object = self.get_object()
        if self.object.staff_only and not request.user.is_staff:
            return render(request,
                          'utils/403_restricted.html',
                          {'message': '该内容仅限工作人员查看'},
                          status=403)
        if self.object.allowed_groups.exists(
        ) and not self.object.allowed_groups.filter(
                id__in=request.user.groups.all()).exists():
            return render(request,
                          'utils/403_restricted.html',
                          {'message': '您所在的用户组无权查看此内容'},
                          status=403)
        return super().dispatch(request, *args, **kwargs)

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

            return self._moreslug()
        elif 'year' in self.kwargs:
            return self._validate_date_path()
        return super().get_object()

    def get(self, request, *args, **kwargs):
        filename = request.path_info
        self.static_config = StaticSettings.get_solo()
        manager = StaticCacheManager(self.static_config.high_safe,
                                     self.static_config.static_node)
        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

    def _pk(self):
        return get_object_or_404(Category,
                                 pk=self.kwargs['pk'],
                                 review_status=1)

    def _handle_hash(self):
        return get_object_or_404(Category,
                                 pk=int(unhash_id(self.kwargs['pk'])),
                                 review_status=1)

    def _slug(self):
        return get_object_or_404(Category,
                                 slug=self.kwargs['slug'],
                                 review_status=1)

    def _moreslug(self):
        if self.kwargs['moreslug'].endswith('/'):
            slug = self.kwargs['moreslug'].split('/')[-2]
        else:
            slug = self.kwargs['moreslug'].split('/')[-1]

        return get_object_or_404(Category, slug=slug, review_status=1)

    def get_queryset(self):
        return super().get_queryset()

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['obj'] = self.object
        context['active'] = self.object.slug
        return context
