"""Catalog Engine — django-filter FilterSet classes.

Provides filter backends for CatalogCategory and CatalogItem querysets.

Usage in function-based views::

    from simorgh.apps.catalog.filters import CatalogItemFilter

    f = CatalogItemFilter(request.query_params, queryset=qs, request=request)
    qs = f.qs
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import django_filters as filters

if TYPE_CHECKING:
    from django.db.models import QuerySet

from simorgh.apps.catalog.models import (
    CatalogCategory,
    CatalogItem,
    CatalogItemStatus,
    CatalogType,
)


# ---------------------------------------------------------------------------
# CatalogCategory filters
# ---------------------------------------------------------------------------

class CatalogCategoryFilter(filters.FilterSet):
    """Filter categories by type, parent, and active status."""

    catalog_type = filters.ChoiceFilter(
        choices=CatalogType.choices,
    )
    parent_id = filters.NumberFilter(field_name="parent_id")
    is_active = filters.BooleanFilter(field_name="is_active")
    q = filters.CharFilter(method="filter_search")

    class Meta:
        model = CatalogCategory
        fields: list[str] = []  # noqa: RUF012

    @staticmethod
    def filter_search(
        queryset: QuerySet, name: str, value: str
    ) -> QuerySet:
        """Full-text search across name, slug, and description."""
        from django.db.models import Q

        return queryset.filter(
            Q(name__icontains=value)
            | Q(slug__icontains=value)
            | Q(description__icontains=value)
        )


# ---------------------------------------------------------------------------
# CatalogItem filters
# ---------------------------------------------------------------------------

class CatalogItemFilter(filters.FilterSet):
    """Filter catalog items by type, status, category, owner, and search."""

    catalog_type = filters.ChoiceFilter(
        choices=CatalogType.choices,
    )
    status = filters.CharFilter(method="filter_status")
    category_id = filters.NumberFilter(field_name="category_id")
    owner_id = filters.NumberFilter(field_name="owner_id")
    is_published = filters.BooleanFilter(method="filter_is_published")
    q = filters.CharFilter(method="filter_search")

    class Meta:
        model = CatalogItem
        fields: list[str] = []  # noqa: RUF012

    @staticmethod
    def filter_status(
        queryset: QuerySet, name: str, value: str
    ) -> QuerySet:
        """Support comma-separated status values (e.g. ?status=published,review)."""
        statuses = [s.strip() for s in value.split(",") if s.strip()]
        if not statuses:
            return queryset
        valid = {s.value for s in CatalogItemStatus}
        statuses = [s for s in statuses if s in valid]
        return queryset.filter(status__in=statuses) if statuses else queryset

    @staticmethod
    def filter_is_published(
        queryset: QuerySet, name: str, value: bool
    ) -> QuerySet:
        """?is_published=true → only published items."""
        if value:
            return queryset.filter(status=CatalogItemStatus.PUBLISHED)
        return queryset.exclude(status=CatalogItemStatus.PUBLISHED)

    @staticmethod
    def filter_search(
        queryset: QuerySet, name: str, value: str
    ) -> QuerySet:
        """Full-text search across name, description, short_description, and category."""
        from django.db.models import Q

        return queryset.filter(
            Q(name__icontains=value)
            | Q(description__icontains=value)
            | Q(short_description__icontains=value)
            | Q(slug__icontains=value)
            | Q(category__name__icontains=value)
        )
