"""Helpdesk filter classes for query-parameter filtering.

Provides django-filter FilterSet classes that can be used with
Django REST Framework views (either via filter_backends or directly
in function-based views with ``filterset(data=request.query_params)``).

Usage in a function-based view::

    from simorgh.apps.helpdesk.filters import TicketFilter

    f = TicketFilter(request.query_params, queryset=qs, request=request)
    qs = f.qs
"""

from __future__ import annotations

from typing import TYPE_CHECKING

import django_filters as filters
from django.db.models import Q

if TYPE_CHECKING:
    from django.db.models import QuerySet



# ---------------------------------------------------------------------------
# Ticket filters
# ---------------------------------------------------------------------------


class TicketFilter(filters.FilterSet):
    """Filter tickets by status, priority, queue, assignment, and search."""

    status = filters.CharFilter(method="filter_status")
    priority = filters.CharFilter(field_name="priority", lookup_expr="exact")
    queue_id = filters.NumberFilter(field_name="queue_id")
    assigned_to_me = filters.BooleanFilter(method="filter_assigned_to_me")
    q = filters.CharFilter(method="filter_search")

    class Meta:
        model = None  # set dynamically at runtime
        fields: list[str] = []  # noqa: RUF012

    @staticmethod
    def filter_status(
        queryset: QuerySet, name: str, value: str
    ) -> QuerySet:
        """Support comma-separated status values (e.g. ?status=new,open)."""
        return queryset.filter(status__in=value.split(","))

    @staticmethod
    def filter_assigned_to_me(
        queryset: QuerySet, name: str, value: str,
    ) -> QuerySet:
        """``?assigned_to_me=1`` narrows to tickets assigned to the current user."""
        if value:
            # The request user is injected by the view.
            request = getattr(queryset, "_request", None)
            if request and request.user.is_authenticated:
                return queryset.filter(assigned_to=request.user)
        return queryset

    @staticmethod
    def filter_search(
        queryset: QuerySet, name: str, value: str,
    ) -> QuerySet:
        """Full-textish search across subject, requester email, and requester name."""
        q = value.strip()
        if not q:
            return queryset
        return queryset.filter(
            Q(subject__icontains=q)
            | Q(requester_email__icontains=q)
            | Q(requester_name__icontains=q)
        )


class TicketReplyFilter(filters.FilterSet):
    """Filter replies by visibility (public vs internal)."""

    is_internal = filters.BooleanFilter(field_name="is_internal")

    class Meta:
        model = None
        fields: list[str] = []  # noqa: RUF012


# ---------------------------------------------------------------------------
# Queue filters
# ---------------------------------------------------------------------------


class QueueFilter(filters.FilterSet):
    """Filter queues by active status."""

    is_active = filters.BooleanFilter(field_name="is_active")

    class Meta:
        model = None
        fields: list[str] = []  # noqa: RUF012


# ---------------------------------------------------------------------------
# SLA Policy filters
# ---------------------------------------------------------------------------


class SLAPolicyFilter(filters.FilterSet):
    """Filter SLA policies."""

    is_active = filters.BooleanFilter(field_name="is_active")

    class Meta:
        model = None
        fields: list[str] = []  # noqa: RUF012


# ---------------------------------------------------------------------------
# Category filters
# ---------------------------------------------------------------------------


class CategoryFilter(filters.FilterSet):
    """Filter categories by queue and active status."""

    queue_id = filters.NumberFilter(field_name="queue_id")
    is_active = filters.BooleanFilter(field_name="is_active")

    class Meta:
        model = None
        fields: list[str] = []  # noqa: RUF012


# ---------------------------------------------------------------------------
# Tag filters
# ---------------------------------------------------------------------------


class TagFilter(filters.FilterSet):
    """Filter tags by active status."""

    is_active = filters.BooleanFilter(field_name="is_active")

    class Meta:
        model = None
        fields: list[str] = []  # noqa: RUF012


# ---------------------------------------------------------------------------
# Automation filters
# ---------------------------------------------------------------------------


class AutomationFilter(filters.FilterSet):
    """Filter automations by trigger and active status."""

    trigger = filters.CharFilter(field_name="trigger", lookup_expr="exact")
    is_active = filters.BooleanFilter(field_name="is_active")

    class Meta:
        model = None
        fields: list[str] = []  # noqa: RUF012
