# home/api/articles.py

from django.http import JsonResponse
from django.views.decorators.http import require_GET
from django.core.cache import cache
from django.conf import settings
from wagtail.models import Site

from home.models import ArticlePage
from .permissions import tenant_api_protected
from .rate_limit import tenant_rate_limited
from .pagination import paginate_queryset
from .utils import build_absolute_media_url


CACHE_KEY_PREFIX = "articles_api_v1"
CACHE_TTL = getattr(settings, "TENANT_CACHE_TTL", 60 * 5)


# =========================
# Serializer
# =========================
def _article_to_dict(request, article):
    """
    Generic article serializer (safe for all ArticlePage variants)
    """
    featured_image = getattr(article, "featured_image", None)

    return {
        "id": article.id,
        "title": article.title,
        "slug": article.slug,
        "excerpt": getattr(article, "excerpt", ""),
        "url": article.url,
        "published_at": article.first_published_at,
        "featured_image": (
            build_absolute_media_url(request, featured_image.file.url)
            if featured_image
            else None
        ),
    }


# =========================
# Article List API (paginated)
# =========================
@require_GET
@tenant_rate_limited
@tenant_api_protected
def article_list_api(request):
    site = Site.find_for_request(request)
    if not site:
        return JsonResponse({"detail": "Site not resolved"}, status=404)

    page_param = request.GET.get("page", "1")
    size_param = request.GET.get("page_size", "10")

    cache_key = (
        f"{CACHE_KEY_PREFIX}:list:"
        f"site:{site.id}:{site.hostname}:"
        f"page:{page_param}:size:{size_param}"
    )

    cached = cache.get(cache_key)
    if cached:
        return JsonResponse(cached)

    queryset = (
        ArticlePage.objects
        .live()
        .public()
        .descendant_of(site.root_page)
        .specific()
        .order_by("-first_published_at")
    )

    meta, items = paginate_queryset(queryset, request)

    data = {
        "meta": meta,
        "items": [_article_to_dict(request, a) for a in items],
    }

    cache.set(cache_key, data, timeout=CACHE_TTL)
    return JsonResponse(data)


# =========================
# Article Detail API
# =========================
@require_GET
@tenant_rate_limited
@tenant_api_protected
def article_detail_api(request, slug):
    site = Site.find_for_request(request)
    if not site:
        return JsonResponse({"detail": "Site not resolved"}, status=404)

    cache_key = f"{CACHE_KEY_PREFIX}:detail:{slug}:site:{site.id}:{site.hostname}"

    cached = cache.get(cache_key)
    if cached:
        return JsonResponse(cached)

    try:
        article = (
            ArticlePage.objects
            .live()
            .public()
            .descendant_of(site.root_page)
            .get(slug=slug)
            .specific
        )
    except ArticlePage.DoesNotExist:
        return JsonResponse({"detail": "Article not found"}, status=404)

    data = {
        **_article_to_dict(request, article),
        # body bisa StreamField / RichText → FE yang render
        "body": getattr(article, "body", None),
    }

    cache.set(cache_key, data, timeout=CACHE_TTL)
    return JsonResponse(data)