"""Read-only query selectors for the notifications app."""

from __future__ import annotations

from django.db.models import QuerySet

from simorgh.apps.notifications.models import (
    Notification,
    NotificationChannel,
    NotificationPreference,
    UserQuietHours,
)

__all__ = [
    "list_notifications",
    "list_unread_notifications",
    "count_unread",
    "get_notification",
    "list_preferences",
    "get_preference",
    "get_quiet_hours",
]


def list_notifications(
    user_id: int,
    tenant_id: int,
    *,
    channel: str = NotificationChannel.INBOX,
    limit: int = 50,
) -> QuerySet:
    """Return the most recent notifications for a user, newest first.

    Defaults to inbox (in-app) channel. Pass ``channel=None`` to include all
    channels.
    """
    qs = Notification.objects.filter(recipient_id=user_id, tenant_id=tenant_id)
    if channel is not None:
        qs = qs.filter(channel=channel)
    return qs.order_by("-created_at")[:limit]


def list_unread_notifications(
    user_id: int,
    tenant_id: int,
    *,
    channel: str = NotificationChannel.INBOX,
) -> QuerySet:
    """Return all unread notifications for a user (``read_at`` is NULL)."""
    qs = Notification.objects.filter(
        recipient_id=user_id,
        tenant_id=tenant_id,
        read_at__isnull=True,
    )
    if channel is not None:
        qs = qs.filter(channel=channel)
    return qs.order_by("-created_at")


def count_unread(user_id: int, tenant_id: int) -> int:
    """Return the count of unread inbox notifications for badge display."""
    return Notification.objects.filter(
        recipient_id=user_id,
        tenant_id=tenant_id,
        channel=NotificationChannel.INBOX,
        read_at__isnull=True,
    ).count()


def get_notification(notification_id: int, user_id: int) -> Notification:
    """Return a single Notification scoped to its recipient.

    Raises ``Notification.DoesNotExist`` when not found or not owned by the user.
    """
    return Notification.objects.get(pk=notification_id, recipient_id=user_id)


def list_preferences(user_id: int, tenant_id: int) -> QuerySet:
    """Return all notification preferences for a user."""
    return NotificationPreference.objects.filter(
        user_id=user_id, tenant_id=tenant_id
    ).order_by("kind", "channel")


def get_preference(
    user_id: int,
    tenant_id: int,
    kind: str,
    channel: str,
) -> NotificationPreference | None:
    """Return a single preference or None if not set (default = enabled)."""
    return NotificationPreference.objects.filter(
        user_id=user_id, tenant_id=tenant_id, kind=kind, channel=channel
    ).first()


def get_quiet_hours(user_id: int, tenant_id: int) -> UserQuietHours | None:
    """Return the quiet-hours config for a user or None if not set."""
    return UserQuietHours.objects.filter(
        user_id=user_id, tenant_id=tenant_id
    ).first()
