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

from __future__ import annotations

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

from simorgh.apps.delegations.models import DelegationLog, DelegationRule, DelegationScope


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


def rules_for_delegator(tenant_id: int, user_id: int) -> QuerySet[DelegationRule]:
    return rules_for_tenant(tenant_id).filter(delegator_id=user_id).order_by("-created_at")


def rules_for_delegate(tenant_id: int, user_id: int) -> QuerySet[DelegationRule]:
    return rules_for_tenant(tenant_id).filter(delegate_to_id=user_id).order_by("-created_at")


def active_rules_for_delegator(tenant_id: int, user_id: int) -> QuerySet[DelegationRule]:
    now = timezone.now()
    return (
        rules_for_tenant(tenant_id)
        .filter(
            delegator_id=user_id,
            is_active=True,
            start_date__lte=now,
            end_date__gte=now,
        )
    )


def active_delegate_for_user(
    tenant_id: int,
    user_id: int,
    *,
    scope: str | None = None,
) -> DelegationRule | None:
    """Find the active delegate for a user.

    Returns the first active delegation rule where the given user is the
    delegator. If scope is provided, only rules covering that scope are
    returned (rules with scope='all' always match).

    This is the primary query used by other engines to reroute work.
    """
    now = timezone.now()
    qs = rules_for_tenant(tenant_id).filter(
        delegator_id=user_id,
        is_active=True,
        start_date__lte=now,
        end_date__gte=now,
    )
    if scope is not None:
        qs = qs.filter(Q(scope=DelegationScope.ALL) | Q(scope=scope))

    return qs.order_by("-created_at").first()


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


def logs_for_rule(tenant_id: int, rule_id: int) -> QuerySet[DelegationLog]:
    return DelegationLog.objects.filter(tenant_id=tenant_id, rule_id=rule_id).order_by("-created_at")


def logs_for_entity(tenant_id: int, content_type_id: int, object_id: int) -> QuerySet[DelegationLog]:
    return (
        DelegationLog.objects
        .filter(tenant_id=tenant_id, content_type_id=content_type_id, object_id=object_id)
        .order_by("-created_at")
    )
