"""Scope before search; no global customer or device enumeration."""
from django.db.models import Q

from apps.access.authorization import authorized_queryset
from apps.customers.models import Customer
from apps.devices.models import Device, CustomerDeviceRelationship
from apps.organization.models import Company, ServiceCenter
from apps.service.models import ServiceCase


def centers(actor, permission):
    return authorized_queryset(user=actor, permission=permission, queryset=ServiceCenter.objects.all())


def customers(actor, center):
    companies = authorized_queryset(user=actor, permission="customers.view_customer", queryset=Company.objects.all())
    return Customer.objects.filter(company_id=center.company_id, company_id__in=companies.values("pk"))


def devices(actor, center):
    allowed = centers(actor, "devices.view_device").filter(pk=center.pk)
    if not allowed.exists():
        return Device.objects.none()
    owned = CustomerDeviceRelationship.objects.filter(customer__in=customers(actor, center)).values("device_id")
    serviced = ServiceCase.objects.filter(service_center__in=centers(actor, "service.view_servicecase"),
                                         company_id=center.company_id).values("device_id")
    foreign_owners = CustomerDeviceRelationship.objects.filter(relationship_type="OWNER").exclude(
        customer__company_id=center.company_id).values("device_id")
    return Device.objects.filter(Q(pk__in=owned) | Q(pk__in=serviced)).exclude(pk__in=foreign_owners)


def search(actor, center, term):
    from apps.devices.identification import identity_key
    from apps.customers.models import normalize_mobile
    from django.core.exceptions import ValidationError
    term = term.strip()
    if not term or len(term) > 128:
        return Customer.objects.none(), Device.objects.none(), ServiceCase.objects.none()
    try:
        contact_term = normalize_mobile(term)
    except ValidationError:
        contact_term = term
    customer_rows = customers(actor, center).filter(
        Q(customer_number__iexact=term) | Q(primary_mobile=contact_term) | Q(primary_email__iexact=term)
        | Q(customercontact_records__is_active=True, customercontact_records__normalized_value=contact_term)
    ).distinct()[:25]
    try:
        key = identity_key(term)
    except ValidationError:
        key = ""
    device_rows = devices(actor, center).filter(identifiers__identity_key=key).distinct()[:25]
    cases = ServiceCase.objects.filter(service_center=center,
        service_center__in=centers(actor, "service.view_servicecase"), job_number__iexact=term)[:25]
    return customer_rows, device_rows, cases
