"""Scoped, lazy invoice queries; display never locks inventory."""
from django.db.models import Prefetch
from .queries import quotation_cases
from .models import ServiceInvoice, InvoiceLine, InvoiceAllocation

VIEW = "commercial.view_serviceinvoice"


def invoice_cases(*, actor, permission=VIEW):
    return quotation_cases(actor=actor, permission=permission).select_related("device__product_model__brand")


def service_invoices(*, actor):
    return ServiceInvoice.objects.filter(service_case_id__in=invoice_cases(actor=actor).values("pk")).select_related(
        "service_case__customer", "service_case__device__product_model__brand", "service_center", "quotation__family", "created_by", "finalized_by").order_by("service_center_id", "number", "pk")


def invoice_history_for_case(*, actor, service_case):
    return service_invoices(actor=actor).filter(service_case=service_case)


def current_service_invoice(*, actor, service_case):
    return invoice_history_for_case(actor=actor, service_case=service_case).first()


def finalized_service_invoice(*, actor, service_case):
    return invoice_history_for_case(actor=actor, service_case=service_case).filter(status="FINALIZED").first()


def invoice_lines(*, actor, invoice, include_history=False):
    rows = InvoiceLine.objects.filter(invoice_id__in=service_invoices(actor=actor).filter(pk=invoice.pk).values("pk"))
    if not include_history:
        rows = rows.filter(is_active=True)
    return rows.select_related("quotation_line__quotation", "quotation_line__spare_part", "confirmed_by").order_by("generation", "quotation_line__position", "pk")


def invoice_allocations(*, actor, invoice, include_history=False):
    return InvoiceAllocation.objects.filter(line_id__in=invoice_lines(actor=actor, invoice=invoice, include_history=include_history).values("pk")).select_related(
        "line__quotation_line", "consumption__movement", "actor").order_by("created_at", "pk")


def invoice_detail(*, actor, invoice):
    return service_invoices(actor=actor).prefetch_related(Prefetch("lines", queryset=invoice_lines(actor=actor, invoice=invoice).prefetch_related(
        Prefetch("allocations", queryset=invoice_allocations(actor=actor, invoice=invoice).prefetch_related("consumption__movement__unit_links__unit"))))).get(pk=invoice.pk)


def service_invoice_summary(*, actor, invoice):
    return service_invoices(actor=actor).values("number", "status", "currency", "subtotal", "discount_total", "tax_total", "grand_total",
        "customer_pay_total", "warranty_covered_total", "company_covered_total").get(pk=invoice.pk)


def service_cases_ready_for_invoicing(*, actor):
    return invoice_cases(actor=actor).filter(status__in=["QC_PASSED", "READY_FOR_DELIVERY"], invoice__isnull=True,
        quotation_family__revisions__is_current=True, quotation_family__revisions__status="APPROVED")


def service_cases_with_draft_invoices(*, actor):
    return invoice_cases(actor=actor).filter(invoice__status="DRAFT")
