"""QC evidence queries and explicitly inspector-scoped operational queues."""
from django.contrib.auth import get_user_model
from django.db.models import Exists, OuterRef, Subquery

from apps.organization.models import ServiceCenter
from .models import ServiceCase, ServiceRepairExecution, ServiceQualityControl, ServiceQualityControlCheck, ServiceQualityControlComplaintCheck
from .queries import _saved, _rows
from .engineer_queries import _paths, _known_permission, _operational

QC_PERMISSION = "perform_quality_control"
QC_STATES = ("REPAIRED", "QC_PENDING", "QC_IN_PROGRESS", "QC_PASSED")


def _latest_repair():
    return ServiceRepairExecution.objects.filter(service_case_id=OuterRef("pk")).order_by("-started_at", "-pk")


def _qc_cases():
    repair = _latest_repair()
    return _rows().filter(pk__in=_operational().values("pk"), status__in=QC_STATES).annotate(
        _repair_id=Subquery(repair.values("pk")[:1]),
        _repair_outcome=Subquery(repair.values("outcome")[:1]),
        _repair_engineer_id=Subquery(repair.values("engineer_assignment__engineer_id")[:1]),
    ).filter(_repair_outcome="REPAIRED").order_by("received_at", "job_number", "pk")


def eligible_quality_control_inspectors(service_case):
    users = get_user_model().objects.all()
    if not _saved(service_case, ServiceCase):
        return users.none()
    case = _qc_cases().filter(pk=service_case.pk).order_by()
    paths = _paths(user=OuterRef("pk"), company=Subquery(case.values("company_id")[:1]),
        region=Subquery(case.values("service_center__region_id")[:1]), center=Subquery(case.values("service_center_id")[:1]), codename=QC_PERMISSION)
    return users.filter(is_active=True).filter(Exists(case), Exists(_known_permission(QC_PERMISSION)), Exists(paths)).exclude(
        pk=Subquery(case.values("_repair_engineer_id")[:1])).order_by("username", "pk")


def qc_cases_for_inspector(inspector):
    """Business operational scope: fresh posting, permission and separation of duties."""
    rows = _qc_cases()
    if not _saved(inspector, get_user_model()):
        return rows.none()
    paths = _paths(user=inspector.pk, company=OuterRef("company_id"), region=OuterRef("service_center__region_id"),
        center=OuterRef("service_center_id"), codename=QC_PERMISSION)
    return rows.filter(Exists(paths), Exists(_known_permission(QC_PERMISSION))).exclude(_repair_engineer_id=inspector.pk)


def quality_control_visible_cases(inspector):
    """Current QC posting scope for history disclosure, independent of case status."""
    rows = _rows()
    if not _saved(inspector, get_user_model()):
        return rows.none()
    paths = _paths(user=inspector.pk, company=OuterRef("company_id"), region=OuterRef("service_center__region_id"),
        center=OuterRef("service_center_id"), codename=QC_PERMISSION)
    return rows.filter(Exists(paths), Exists(_known_permission(QC_PERMISSION)))


def qc_pending_cases_for_center(service_center, *, inspector=None):
    """Without inspector this is a trusted internal center query, not authorization."""
    rows = _qc_cases() if inspector is None else qc_cases_for_inspector(inspector)
    rows = rows.filter(status="QC_PENDING")
    return rows.filter(service_center_id=service_center.pk) if _saved(service_center, ServiceCenter) else rows.none()


def quality_control_history(service_case):
    rows = ServiceQualityControl.objects.select_related("service_case", "repair_execution__engineer_assignment__engineer", "inspector", "abandoned_by")
    return rows.filter(service_case_id=service_case.pk) if _saved(service_case, ServiceCase) else rows.none()


def current_quality_control(service_case):
    return quality_control_history(service_case).filter(status="IN_PROGRESS").first()


def latest_completed_quality_control(service_case):
    return quality_control_history(service_case).filter(status="COMPLETED").order_by("-completed_at", "-pk").first()


def failed_quality_controls_for_case(service_case):
    return quality_control_history(service_case).filter(status="COMPLETED", outcome="FAILED")


def quality_control_checks(quality_control):
    rows = ServiceQualityControlCheck.objects.select_related("quality_control")
    return rows.filter(quality_control_id=quality_control.pk) if _saved(quality_control, ServiceQualityControl) else rows.none()


def quality_control_complaint_checks(quality_control):
    rows = ServiceQualityControlComplaintCheck.objects.select_related("quality_control", "complaint__complaint_symptom")
    return rows.filter(quality_control_id=quality_control.pk) if _saved(quality_control, ServiceQualityControl) else rows.none()
