"""SQL-scoped request/reservation queues."""
from django.db.models import Sum, Q
from apps.access.authorization import authorized_queryset
from apps.organization.models import ServiceCenter
from apps.parts.locking import persisted_pk
from .models import PartsRequest, StockReservation
from .queries import authorized_locations


def parts_requests(*, actor, permission="inventory.view_stock"):
    centers = authorized_queryset(user=actor, permission=permission, queryset=ServiceCenter.objects.all())
    return PartsRequest.objects.filter(service_case__service_center_id__in=centers.values("pk")).select_related(
        "company", "service_case__service_center", "requester", "decided_by").order_by("requested_at", "pk")


def parts_request_detail(*, actor, request):
    return parts_requests(actor=actor).prefetch_related("lines__spare_part", "lines__reservations", "events__actor").get(pk=persisted_pk(request, PartsRequest))


def stock_reservations(*, actor, active_only=False):
    rows = StockReservation.objects.filter(line__request_id__in=parts_requests(actor=actor).values("pk"),
        location_id__in=authorized_locations(actor=actor).values("pk")).select_related(
        "line__request", "service_case", "spare_part", "location", "reserved_by", "ended_by").order_by("reserved_at", "pk")
    return rows.filter(status="ACTIVE") if active_only else rows


def request_fulfillment(*, actor, request):
    row = parts_requests(actor=actor).get(pk=persisted_pk(request, PartsRequest))
    return row.lines.values("pk", "spare_part__part_code", "quantity").annotate(
        reserved_quantity=Sum("reservations__quantity", filter=Q(reservations__status="ACTIVE"), default=0),
        issued_quantity=Sum("reservations__quantity", filter=Q(reservations__status="ISSUED"), default=0)).order_by("spare_part__part_code")
