from django.db import models
from modelcluster.contrib.taggit import ClusterTaggableManager
from modelcluster.fields import ParentalKey
from taggit.models import TaggedItemBase
from wagtail.admin.panels import FieldPanel
from wagtail.fields import StreamField
from wagtail.search import index

from apps.core.blocks import COMMON_BLOCKS
from apps.core.models import SEOablePage


class BlogIndexPage(SEOablePage):
    """博客列表页，本身不直接管理内容，子页面为 BlogPage。"""

    intro = models.TextField(blank=True, verbose_name="栏目简介")

    content_panels = SEOablePage.content_panels + [
        FieldPanel("intro"),
    ]

    subpage_types = ["blog.BlogPage"]
    parent_page_types = ["home.HomePage"]

    class Meta:
        verbose_name = "博客栏目页"

    def get_context(self, request, *args, **kwargs):
        context = super().get_context(request, *args, **kwargs)
        context["posts"] = (
            BlogPage.objects.live().descendant_of(self).order_by("-published_at")
        )
        return context


class BlogPageTag(TaggedItemBase):
    content_object = ParentalKey(
        "BlogPage", related_name="tagged_items", on_delete=models.CASCADE
    )


class BlogPage(SEOablePage):
    """技术博客文章页。"""

    published_at = models.DateTimeField(verbose_name="发布时间")
    intro = models.CharField(max_length=250, blank=True, verbose_name="摘要")
    cover_image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
        verbose_name="封面图",
    )
    body = StreamField(COMMON_BLOCKS, use_json_field=True, blank=True)
    tags = ClusterTaggableManager(through=BlogPageTag, blank=True, verbose_name="标签")

    search_fields = SEOablePage.search_fields + [
        index.SearchField("intro"),
        index.SearchField("body"),
    ]

    content_panels = SEOablePage.content_panels + [
        FieldPanel("published_at"),
        FieldPanel("intro"),
        FieldPanel("cover_image"),
        FieldPanel("body"),
        FieldPanel("tags"),
    ]

    parent_page_types = ["blog.BlogIndexPage"]
    subpage_types = []

    class Meta:
        verbose_name = "博客文章"
