import sform

from django.db.models import Q

from staff.umbrellas.models import UmbrellaAssignment, Umbrella

from staff.person_filter.controller._base import lib, FieldFilter, BaseEqual, BaseIn, BaseExistence
from staff.person_filter.controller._forms import TrueBooleanForm


@lib.register
class UmbrellaFilter(FieldFilter):
    """Зонтик"""


class EqualForm(sform.SForm):
    umbrella = sform.SuggestField(
        queryset=Umbrella.objects.all(),
        label_fields='name',
        state=sform.NORMAL,
    )


@UmbrellaFilter.register
class Equal(BaseEqual):
    form_cls = EqualForm

    def q(self):
        umbrella = self.cleaned_data['umbrella']

        if umbrella is None:
            return _construct_staff_selector(Q(umbrella__isnull=True))

        return _construct_staff_selector(Q(umbrella=self.cleaned_data['umbrella']))


@UmbrellaFilter.register
class Exclude(Equal):
    def q(self):
        return ~super().q()


@UmbrellaFilter.register
class Existence(BaseExistence):
    form_cls = TrueBooleanForm

    def q(self):
        q = _construct_staff_selector(~Q())
        return q if self.cleaned_data['value'] else ~q


class InForm(sform.SForm):
    umbrellas = sform.MultipleSuggestField(
        queryset=Umbrella.objects.all(),
        label_fields='name',
        state=sform.REQUIRED,
    )


# @UmbrellaFilter.register
class In(BaseIn):
    form_cls = InForm

    def q(self):
        return _construct_staff_selector(Q(umbrella__in=self.cleaned_data['umbrellas']))


def _construct_staff_selector(umbrella_selector: Q) -> Q:
    persons = UmbrellaAssignment.all_assignments.active().filter(umbrella_selector).values_list('person_id').distinct()

    return Q(id__in=persons)
