from django.db import models
from django.core.exceptions import ValidationError
from django.utils.text import slugify

from wagtail.models import Page, Site
from wagtail.admin.forms import WagtailAdminPageForm
from wagtail.admin.panels import FieldPanel, MultiFieldPanel

from wagtail.images.models import Image
from wagtail.images.api.fields import ImageRenditionField

from wagtail.fields import RichTextField
from wagtail.api import APIField

from home.threadlocals import get_current_site


# =====================================================
# ARTICLE CATEGORY (SNIPPET + TENANT SAFE)
# =====================================================

class ArticleCategory(models.Model):
    site = models.ForeignKey(Site, on_delete=models.CASCADE)
    title = models.CharField(max_length=100)
    slug = models.SlugField(max_length=100)

    class Meta:
        unique_together = ("site", "slug")

    # ❌ JANGAN VALIDASI self.site DI clean()
    # clean() DIPANGGIL SEBELUM save()

    def save(self, *args, **kwargs):
        """
        SATU-SATUNYA TEMPAT YANG BENAR
        untuk inject tenant (Site)
        """
        if not self.site_id:
            site = get_current_site()
            if not site:
                raise RuntimeError(
                    "ArticleCategory harus dibuat dalam context Site aktif"
                )
            self.site = site

        if not self.slug:
            self.slug = slugify(self.title)

        super().save(*args, **kwargs)

    def __str__(self):
        return f"{self.title} ({self.site.hostname})"


# =====================================================
# ARTICLE PAGE FORM (FILTER CATEGORY PER SITE)
# =====================================================

class ArticlePageForm(WagtailAdminPageForm):
    """
    Filter dropdown category di admin
    supaya hanya category milik tenant aktif
    """

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        target = (
            getattr(self, "for_page", None)
            or getattr(self, "parent_page", None)
        )

        if target and "category" in self.fields:
            site = target.get_site()
            self.fields["category"].queryset = (
                ArticleCategory.objects.filter(site=site)
                if site
                else ArticleCategory.objects.none()
            )




# =====================================================
# INI SIASI MULTI SUB PAGE
# =====================================================
class HomePage(Page):
    """
    Root page untuk satu tenant / site
    """

    # ❌ HomePage TIDAK BOLEH PUNYA PARENT LAIN
    parent_page_types = ["wagtailcore.Page"]  # root only

    subpage_types = [
        "home.StandardIndexPage",
        "home.ArticleIndexPage",
    ]

# =====================================================
# PAGE BIASA
# =====================================================

class StandardIndexPage(Page):

    parent_page_types = ["home.HomePage"]
    subpage_types = ["home.StandardPage"]

class StandardPage(Page):
    parent_page_types = ["home.StandardIndexPage"]

    featured_image = models.ForeignKey(
        Image,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )

    author = models.CharField(max_length=255)
    date = models.DateField()
    body = RichTextField()

    content_panels = Page.content_panels + [
        FieldPanel("featured_image"),
        MultiFieldPanel(
            [
                FieldPanel("author"),
                FieldPanel("date"),
            ],
            heading="Metadata",
        ),
        FieldPanel("body"),
    ]

    api_fields = [
        APIField("author"),
        APIField("date"),
        APIField("body"),
        APIField(
            "feature_image",
            serializer=ImageRenditionField("width-1920"),
        ),
    ]

# =====================================================
# ARTICLE PAGE
# =====================================================

class ArticleIndexPage(Page):
    """
    Folder / container khusus artikel
    """

    parent_page_types = ["home.HomePage"]
    subpage_types = ["home.ArticlePage"]



class ArticlePage(Page):
    parent_page_types = ["home.ArticleIndexPage"]

    base_form_class = ArticlePageForm

    # =====================
    # FEATURE IMAGE
    # =====================
    featured_image = models.ForeignKey(
        "wagtailimages.Image",
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="+",
    )

    # =====================
    # METADATA
    # =====================
    author = models.CharField(max_length=255)
    date = models.DateField()

    category = models.ForeignKey(
        ArticleCategory,
        null=True,
        blank=True,
        on_delete=models.SET_NULL,
        related_name="articles",
    )

    body = RichTextField()

    # =====================
    # ADMIN PANELS
    # =====================
    content_panels = Page.content_panels + [
        FieldPanel("featured_image"),
        MultiFieldPanel(
            [
                FieldPanel("author"),
                FieldPanel("date"),
                FieldPanel("category"),
            ],
            heading="Metadata",
        ),
        FieldPanel("body"),
    ]

    # =====================
    # API SERIALIZER
    # =====================
    """ @property
    def category_data(self):
        if not self.category:
            return None
        return {
            "id": self.category.id,
            "title": self.category.title,
            "slug": self.category.slug,
        }

    api_fields = [
        APIField("author"),
        APIField("date"),
        APIField("body"),
        APIField(
            "featured_image",
            serializer=ImageRenditionField("width-1920"),
        ),
        APIField("category_data"),
    ] """

    # =====================
    # TENANT VALIDATION
    # =====================
    def clean(self):
        super().clean()

        if self.category:
            current_site = get_current_site()
            if not current_site:
                raise ValidationError(
                    {"category": "Tenant context tidak ditemukan."}
                )

            if self.category.site_id != current_site.id:
                raise ValidationError(
                    {"category": "Category bukan milik tenant ini."}
                )