"""SLA Engine selectors — read-only queries."""

from __future__ import annotations

from django.db.models import Q, QuerySet
from django.utils import timezone

from simorgh.apps.sla_engine.models import (
    SLABreach,
    SLAPolicy,
    SLATimer,
)


def policies_for_tenant(tenant_id: int) -> QuerySet[SLAPolicy]:
    return SLAPolicy.objects.filter(tenant_id=tenant_id)


def active_policies(tenant_id: int) -> QuerySet[SLAPolicy]:
    return policies_for_tenant(tenant_id).filter(is_active=True)


def policies_by_type(tenant_id: int, sla_type: str) -> QuerySet[SLAPolicy]:
    return active_policies(tenant_id).filter(sla_type=sla_type)


def policy_by_public_id(tenant_id: int, public_id: str) -> SLAPolicy:
    return SLAPolicy.objects.get(tenant_id=tenant_id, public_id=public_id)


def timers_for_tenant(tenant_id: int) -> QuerySet[SLATimer]:
    return SLATimer.objects.filter(tenant_id=tenant_id)


def active_timers(tenant_id: int) -> QuerySet[SLATimer]:
    return timers_for_tenant(tenant_id).filter(is_stopped=False)


def breached_timers(tenant_id: int) -> QuerySet[SLATimer]:
    return active_timers(tenant_id).filter(is_breached=True, is_recovered=False)


def overdue_timers(tenant_id: int) -> QuerySet[SLATimer]:
    """Timers past their target date that haven't been breached yet."""
    return active_timers(tenant_id).filter(
        target_at__lt=timezone.now(),
        is_breached=False,
    )


def warning_timers(tenant_id: int) -> QuerySet[SLATimer]:
    """Timers past warning threshold where warning not yet sent."""
    return active_timers(tenant_id).filter(
        warning_sent=False,
        warning_at__lte=timezone.now(),
        warning_at__isnull=False,
    )


def timer_by_public_id(public_id: str) -> SLATimer:
    return SLATimer.objects.get(public_id=public_id)


def timers_for_entity(content_type_id: int, object_id: int) -> QuerySet[SLATimer]:
    return SLATimer.objects.filter(content_type_id=content_type_id, object_id=object_id)


def breaches_for_tenant(tenant_id: int) -> QuerySet[SLABreach]:
    return SLABreach.objects.filter(tenant_id=tenant_id).order_by("-occurred_at")


def breaches_by_status(tenant_id: int, status: str) -> QuerySet[SLABreach]:
    return breaches_for_tenant(tenant_id).filter(status=status)


def breach_by_public_id(public_id: str) -> SLABreach:
    return SLABreach.objects.get(public_id=public_id)


def search_policies(tenant_id: int, query: str) -> QuerySet[SLAPolicy]:
    return (
        policies_for_tenant(tenant_id)
        .filter(
            Q(name__icontains=query)
            | Q(description__icontains=query)
        )
        .distinct()
    )
