"""
Wagtail API v2 路由配置。
详见 documents/设计方案分析与完善版.md §2.7 Headless API 设计规范。
"""
from django.contrib.contenttypes.models import ContentType
from django.http import Http404
from rest_framework.response import Response
from wagtail.api.v2.views import PagesAPIViewSet
from wagtail.api.v2.router import WagtailAPIRouter
from wagtail.images.api.v2.views import ImagesAPIViewSet
from wagtail.documents.api.v2.views import DocumentsAPIViewSet
from wagtail_headless_preview.models import PagePreview

api_router = WagtailAPIRouter("wagtailapi")

api_router.register_endpoint("pages", PagesAPIViewSet)
api_router.register_endpoint("images", ImagesAPIViewSet)
api_router.register_endpoint("documents", DocumentsAPIViewSet)


class PagePreviewAPIViewSet(PagesAPIViewSet):
    """
    预览模式专用只读接口：根据 `content_type`（app_label.model，小写）+ `token`
    从 `wagtail_headless_preview` 存储的草稿快照中取出对应页面实例并序列化返回。
    `token` 由编辑器在 Wagtail 后台点击"预览"时生成（详见 §2.15/§2.7），
    未知或已过期的 token 会返回 404，不会暴露任何非预览用途的草稿数据。
    """

    known_query_parameters = PagesAPIViewSet.known_query_parameters.union(
        ["content_type", "token"]
    )

    def listing_view(self, request):
        # 统一走 detail_view，保证序列化格式与详情接口一致；pk 仅占位，实际查找依赖 content_type+token。
        self.action = "detail_view"
        return self.detail_view(request, 0)

    def detail_view(self, request, pk):
        page = self.get_object()
        serializer = self.get_serializer(page)
        return Response(serializer.data)

    def get_object(self):
        try:
            app_label, model = self.request.GET["content_type"].split(".")
            content_type = ContentType.objects.get(app_label=app_label, model=model)
            page_preview = PagePreview.objects.get(
                content_type=content_type, token=self.request.GET["token"]
            )
        except (KeyError, ValueError, ContentType.DoesNotExist, PagePreview.DoesNotExist):
            # 缺少参数/content_type 格式错误/未知或已过期的 token，统一返回 404，
            # 不暴露内部异常细节（详见类文档字符串）。
            raise Http404("No matching page preview found.")
        page = page_preview.as_page()
        if not page.pk:
            # 新建（尚未保存）页面的预览没有真实主键，填充占位值避免 API 路由生成 URL 时报错
            page.pk = 0
        return page


api_router.register_endpoint("page_preview", PagePreviewAPIViewSet)

