"""DMS search — query layer.

All DB reads for DocumentSearchIndex and SavedSearch go through here.
Views and services must never query these models directly.
"""

from __future__ import annotations

import uuid

from django.db.models import QuerySet

from simorgh.apps.dms.common.exceptions import AssetNotFound
from simorgh.apps.dms.search.models import DocumentSearchIndex, SavedSearch


# ---------------------------------------------------------------------------
# DocumentSearchIndex queries
# ---------------------------------------------------------------------------

def get_search_index_for_document(document) -> DocumentSearchIndex | None:
    """Return the search index entry for a document, or None if not indexed."""
    try:
        return DocumentSearchIndex.objects.select_related("document").get(
            document=document
        )
    except DocumentSearchIndex.DoesNotExist:
        return None


# ---------------------------------------------------------------------------
# SavedSearch queries
# ---------------------------------------------------------------------------

def get_saved_search(tenant_id: int, public_id: str, user=None) -> SavedSearch:
    """Return a SavedSearch visible to ``user``.

    A saved search is visible when it is owned by the user OR is shared.
    Superusers can see all saved searches in the tenant.

    Raises ``AssetNotFound`` if not found or not accessible.
    """
    try:
        uid = uuid.UUID(str(public_id))
    except (ValueError, AttributeError) as exc:
        raise AssetNotFound(f"Invalid saved-search id: {public_id!r}") from exc

    qs = SavedSearch.objects.filter(
        tenant_id=tenant_id, public_id=uid, is_deleted=False
    )
    if user is not None and not getattr(user, "is_superuser", False):
        from django.db.models import Q
        qs = qs.filter(Q(owner=user) | Q(is_shared=True))

    try:
        return qs.get()
    except SavedSearch.DoesNotExist as exc:
        raise AssetNotFound(f"SavedSearch {public_id!r} not found.") from exc


def list_saved_searches(tenant_id: int, user) -> QuerySet:
    """List own saved searches plus all shared ones for ``user``."""
    from django.db.models import Q

    return (
        SavedSearch.objects.filter(tenant_id=tenant_id, is_deleted=False)
        .filter(Q(owner=user) | Q(is_shared=True))
        .order_by("-created_at")
    )
