from django.http import Http404

from staff.lib.decorators import available_by_center_token

from staff.person.models import Staff
from staff.groups.models import Group, GROUP_TYPE_CHOICES
from staff.departments.models import Department

from staff.apicenter.v1 import ApiView


_def_group_fields = ('id', 'parent', 'name', 'code', 'url')
_full_group_fields = ApiView.full_fields(Group, {
    'parent': Group,
    'department': Department
})
_full_group_fields.append('type')
_full_staff_fields = ApiView.full_fields(Staff)


def _get_type(group):
    name = group.get('name', group.get('url')) or ''

    # для групп нулевого уровня пустой type
    if (group.get('level') == 0 or not group.get('parent') or name.startswith('__') and name.endswith('__')):
        return ''

    try:
        return GROUP_TYPE_CHOICES[group['type']]
    except KeyError:
        return ''


@available_by_center_token
class GroupView(ApiView):
    entities = ('group', )

    def prepare_data(self, id_or_url, *args, **kwargs):
        fields = self.get_fields(
            Group, 'fields', _def_group_fields, _full_group_fields
        )
        is_type = 'type' in fields or self.request.GET.get('fields', self.request.POST.get('fields')) == '__all__'

        try:
            qs = Group.objects.values(*fields).exclude(id=Group.OPTION)
            if id_or_url.isdigit():
                try:
                    self.data = qs.get(id=id_or_url, intranet_status__gt=0)
                except (Group.DoesNotExist, ValueError):
                    pass
            if not self.data:
                self.data = qs.get(url=id_or_url, intranet_status__gt=0)
            if is_type:
                self.data['type'] = _get_type(self.data)
        except Group.DoesNotExist:
            raise Http404()


@available_by_center_token
class GroupsView(ApiView):
    entities = ('groups', 'group',)

    def prepare_data(self, *args, **kwargs):
        fields = self.get_fields(
            Group, 'fields', _def_group_fields, _full_group_fields, ['id', 'parent']
        )
        is_staff_fields = self.request.GET.get('staff_fields', self.request.POST.get('staff_fields', None)) is not None

        self.data = list(
            Group.objects
            .values(*fields)
            .filter(intranet_status__gt=0)
            .exclude(id=Group.OPTION)
            .order_by('tree_id', 'lft')
        )
        if 'type' in fields:
            for g in self.data:
                g['type'] = _get_type(g)

        if is_staff_fields:
            staff_fields = self.get_fields(
                Staff, 'staff_fields', ('id', 'login'), _full_staff_fields, ['id', 'login']
            )

            for g in self.data:
                g['_users'] = list(
                    Group.objects.get(pk=g['id']).get_all_members().filter(is_dismissed=False).values(*staff_fields)
                )


@available_by_center_token
class UserGroupsView(ApiView):
    entities = ('groups', 'group',)

    def prepare_data(self, user, *args, **kwargs):
        fields = self.get_fields(
            Group, 'fields', _def_group_fields, _full_group_fields, ['id', 'parent']
        )
        is_type = 'type' in fields

        try:
            staff = Staff.objects.get(login=user)
        except Staff.DoesNotExist:
            raise Http404()

        nearly_all_groups = [g for g in staff.get_all_groups(fields)
                             if g['id'] != Group.OPTION]
        self.data = list(nearly_all_groups)
        if is_type:
            for g in self.data:
                g['type'] = _get_type(g)
