from operator import itemgetter
from itertools import groupby

from staff.person.models import Staff
from staff.groups.models import GroupMembership, GROUP_TYPE_CHOICES
from staff.proposal.controllers.department import order_field

from staff.lib.utils.qs_values import localize, repack_related

from staff.proposal.forms.person import PersonEditForm
from staff.proposal.controllers.utils import raw_data


class PersonDataCtl(object):
    person_fields = (
        'id', 'login',
        'department__url', 'department__name', 'department__name_en',
        'department__level', 'department__lft', 'department__tree_id',
        'organization__id', 'organization__name', 'organization__name_en',
        'office__id', 'office__name', 'office__name_en',
        'office_id', 'position', 'position_en',
        'first_name', 'first_name_en', 'last_name', 'last_name_en',
        'extra__occupation__description',
        'extra__occupation__name',
    )

    def __init__(self, logins):
        self._meta_data = {}

        person_data_qs = (
            Staff.objects.filter(login__in=logins)
            .values(*self.person_fields)
            .order_by('login')
        )
        self.persons_data = {
            p['login']: repack_related(p)
            for p in person_data_qs
        }

        groupmemberships = (
            GroupMembership.objects
            .filter(
                group__type=GROUP_TYPE_CHOICES.SERVICE,
                group__intranet_status=1,
                staff__login__in=self.persons_data,
            )
            .values_list('staff__login', 'group__name', 'group__url')
            .order_by('staff__login')
        )
        self.services = dict.fromkeys(logins, [])
        for login, groups_data in groupby(groupmemberships, itemgetter(0)):
            self.services[login] = [
                {
                    'name': service[1],
                    'url': service[2],
                }
                for service in groups_data
            ]

        for login, services in self.services.items():
            self.persons_data[login]['services'] = [
                service['name'] for service in services
            ]

    def as_form_data(self, login):
        """"""
        if not self.persons_data or login not in self.persons_data:
            return {}

        result = raw_data(PersonEditForm().data_as_dict())
        person = self.persons_data[login]

        result['login'] = login

        result['department']['service_groups'] = [s['url'] for s in self.services[login]]
        result['organization']['organization'] = person['organization']['id']
        result['office']['office'] = person['office_id']

        if person['extra']['occupation']:
            result['grade']['occupation'] = person['extra']['occupation']['name']

        return result

    def as_meta(self, login):
        if not self.persons_data or login not in self.persons_data:
            return {}

        meta = localize(self.persons_data[login].copy())

        meta['department_url'] = meta['department']['url']
        meta['department_level'] = meta['department']['level']
        meta['department_order_field'] = order_field(meta['department']['tree_id'], meta['department']['lft'])
        for ref_name in ('department', 'office', 'organization'):
            localize(meta[ref_name])
            meta[ref_name+'_name'] = meta[ref_name]['name']
            meta.pop(ref_name)

        meta['occupation_description'] = meta['extra']['occupation']['description']
        meta['occupation_name'] = meta['extra']['occupation']['name']
        meta.pop('extra')

        return meta
