"""Read-only query selectors for the workflow app."""

from __future__ import annotations

from django.db.models import QuerySet

from simorgh.apps.workflow.models import (
    WorkflowApproval,
    WorkflowApprovalDecision,
    WorkflowInstance,
    WorkflowInstanceStatus,
)

__all__ = [
    "get_instance_by_id",
    "get_active_instances_for_subject",
    "list_instances_for_tenant",
    "get_pending_approvals_for_user",
    "list_approvals_for_instance",
]


def get_instance_by_id(instance_id: int, tenant_id: int) -> WorkflowInstance:
    """Return a WorkflowInstance scoped to the tenant.

    Raises ``WorkflowInstance.DoesNotExist`` when not found.
    """
    return WorkflowInstance.objects.get(pk=instance_id, tenant_id=tenant_id)


def get_active_instances_for_subject(
    content_type_id: int,
    object_id: str,
    tenant_id: int,
) -> QuerySet:
    """Return all ACTIVE WorkflowInstances driving a given subject row.

    ``content_type_id`` is the Django ContentType PK for the subject model.
    ``object_id`` matches ``WorkflowInstance.object_id`` (stored as a string).
    """
    return WorkflowInstance.objects.filter(
        tenant_id=tenant_id,
        content_type_id=content_type_id,
        object_id=str(object_id),
        status=WorkflowInstanceStatus.ACTIVE,
    ).order_by("-created_at")


def list_instances_for_tenant(
    tenant_id: int,
    *,
    definition_name: str | None = None,
    status: str | None = WorkflowInstanceStatus.ACTIVE,
) -> QuerySet:
    """Return WorkflowInstances for a tenant, optionally filtered by definition or status.

    Pass ``status=None`` to include instances in all states.
    """
    qs = WorkflowInstance.objects.filter(tenant_id=tenant_id)
    if definition_name:
        qs = qs.filter(definition_name=definition_name)
    if status is not None:
        qs = qs.filter(status=status)
    return qs.order_by("-created_at")


def get_pending_approvals_for_user(user_id: int, tenant_id: int) -> QuerySet:
    """Return WorkflowApprovals awaiting decision from this user.

    "Pending" means: ``consumed_at`` is NULL and ``decision`` is not yet set.
    The related instance must still be ACTIVE.
    """
    return (
        WorkflowApproval.objects.filter(
            tenant_id=tenant_id,
            actor_id=user_id,
            consumed_at__isnull=True,
            instance__status=WorkflowInstanceStatus.ACTIVE,
        )
        .select_related("instance")
        .order_by("-created_at")
    )


def list_approvals_for_instance(instance_id: int) -> QuerySet:
    """Return all WorkflowApproval records for an instance, newest first."""
    return WorkflowApproval.objects.filter(instance_id=instance_id).order_by("-created_at")
