"""Selection helpers for future intake; not authorization or transaction guarantees."""
from django.db.models import Exists, OuterRef, Q

from apps.catalog.models import ProductCategory
from .models import (
    ComplaintSymptom, ComplaintSymptomProductCategory,
    FaultDiagnosis, FaultDiagnosisProductCategory,
    RootCause, RootCauseProductCategory, RepairAction, RepairActionProductCategory,
)


def _saved(instance, model):
    return (isinstance(instance, model) and instance.pk is not None
        and not instance._state.adding and instance._state.db == "default")


def _applicable_for_category(product_category, *, model, mapping_model, master_field):
    """Lazy, code-ordered queryset; inactive/missing category yields no selections."""
    if not _saved(product_category, ProductCategory):
        return model.objects.none()
    mappings = mapping_model.objects.filter(**{master_field + "_id": OuterRef("pk")})
    category_active = ProductCategory.objects.filter(pk=product_category.pk, is_active=True)
    return model.objects.active().filter(Exists(category_active)).filter(
        (Q(applies_to_all_product_categories=True) & ~Q(Exists(mappings)))
        | (Q(applies_to_all_product_categories=False) & Q(Exists(mappings.filter(product_category_id=product_category.pk))))
    ).order_by("code", "pk")


def applicable_complaints_for_category(product_category):
    return _applicable_for_category(product_category, model=ComplaintSymptom,
        mapping_model=ComplaintSymptomProductCategory, master_field="complaint_symptom")


def applicable_fault_diagnoses_for_category(product_category):
    return _applicable_for_category(product_category, model=FaultDiagnosis,
        mapping_model=FaultDiagnosisProductCategory, master_field="fault_diagnosis")


def applicable_root_causes_for_category(product_category):
    return _applicable_for_category(product_category, model=RootCause,
        mapping_model=RootCauseProductCategory, master_field="root_cause")


def applicable_repair_actions_for_category(product_category):
    return _applicable_for_category(product_category, model=RepairAction,
        mapping_model=RepairActionProductCategory, master_field="repair_action")


def complaint_applies_to_category(*, complaint, product_category):
    """Fresh stored state decides; restricted with no mappings always denies."""
    if not _saved(complaint, ComplaintSymptom):
        return False
    return applicable_complaints_for_category(product_category).filter(pk=complaint.pk).exists()


def fault_diagnosis_applies_to_category(*, diagnosis, product_category):
    if not _saved(diagnosis, FaultDiagnosis):
        return False
    return applicable_fault_diagnoses_for_category(product_category).filter(pk=diagnosis.pk).exists()


def root_cause_applies_to_category(*, root_cause, product_category):
    if not _saved(root_cause, RootCause):
        return False
    return applicable_root_causes_for_category(product_category).filter(pk=root_cause.pk).exists()


def repair_action_applies_to_category(*, repair_action, product_category):
    if not _saved(repair_action, RepairAction):
        return False
    return applicable_repair_actions_for_category(product_category).filter(pk=repair_action.pk).exists()
